Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project>
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
</Project>
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ An app for [Seq](https://datalust.co/seq) that forwards messages to [Slack](http

### Getting started

1. Install the app into Seq through the Seq UI: _Settings_ > _Apps_ > _Install from Nuget_. The package id is _Seq.App.Slack_.
2. In Slack, select _Manage apps_ > _Search App Directory_ > _"Incoming WebHooks"_
3. Add a new incoming webhook configuration and copy the _Webhook URL_
4. Back in Seq, under _Settings_ > _Apps_, select _Add Instance_ next to the Slack app icon
5. Configure the app instance, providing the webhook URL
1. Install the app into Seq through the Seq UI: _Settings_ > _Apps_ > _Install from NuGet_; the package id is _Seq.App.Slack_
2. In Slack, select _Admin_ > _Apps and Workflows_ > _Build_ > _Create new App_ > _From Scratch_
3. In the app registration, choose _Incoming WebHooks_ (this is the new endpoint, not the legacy one)
4. Add a new incoming webhook configuration and copy the _Webhook URL_
5. Back in Seq, under _Settings_ > _Apps_, select _Add Instance_ next to the Slack app icon
6. Configure the app instance, providing the webhook URL

Consult the Seq documentation for further information about [installing Seq apps](https://docs.datalust.co/docs/installing-seq-apps).

For more information see [Notifying with Slack](https://docs.datalust.co/docs/slack-notifications).
For more information see [Notifying with Slack](https://docs.datalust.co/docs/slack-notifications).
1 change: 1 addition & 0 deletions Seq.App.Slack.sln
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{225F20AD
README.md = README.md
Build.ps1 = Build.ps1
Run.ps1 = Run.ps1
Directory.Build.props = Directory.Build.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Seq.App.Slack.Tests", "test\Seq.App.Slack.Tests\Seq.App.Slack.Tests.csproj", "{143E44C0-C8B0-473D-9522-B31BCAA81A80}"
Expand Down
11 changes: 5 additions & 6 deletions src/Seq.App.Slack/Api/ISlackApi.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System.Threading.Tasks;

namespace Seq.App.Slack.Api
namespace Seq.App.Slack.Api;

public interface ISlackApi
{
public interface ISlackApi
{
Task SendMessageAsync(string webhookUrl, SlackMessage message);
}
}
Task SendMessageAsync(string webhookUrl, SlackMessage message);
}
73 changes: 36 additions & 37 deletions src/Seq.App.Slack/Api/SlackApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,51 @@
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Seq.App.Slack.Api
namespace Seq.App.Slack.Api;

class SlackApi : ISlackApi
{
class SlackApi : ISlackApi
static SlackApi()
{
static SlackApi()
{
// Enable TLS 1.2 before any connection to the Slack API is made.
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
}
// Enable TLS 1.2 before any connection to the Slack API is made.
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
}

private readonly HttpClient _httpClient;
private static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
private readonly HttpClient _httpClient;
private static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};

public SlackApi(string proxyServer)
public SlackApi(string? proxyServer)
{
if (!string.IsNullOrWhiteSpace(proxyServer))
{
if (!string.IsNullOrWhiteSpace(proxyServer))
var proxy = new WebProxy(proxyServer, false)
{
var proxy = new WebProxy(proxyServer, false)
{
UseDefaultCredentials = true
};
var httpClientHandler = new HttpClientHandler()
{
Proxy = proxy,
PreAuthenticate = true,
UseDefaultCredentials = true,
};
_httpClient = new HttpClient(handler: httpClientHandler);
}
else
UseDefaultCredentials = true
};
var httpClientHandler = new HttpClientHandler()
{
_httpClient = new HttpClient();
}
Proxy = proxy,
PreAuthenticate = true,
UseDefaultCredentials = true,
};
_httpClient = new HttpClient(handler: httpClientHandler);
}
else
{
_httpClient = new HttpClient();
}
}

public async Task SendMessageAsync(string webhookUrl, SlackMessage message)
public async Task SendMessageAsync(string webhookUrl, SlackMessage message)
{
var json = JsonConvert.SerializeObject(message, JsonSettings);
using (var content = new StringContent(json, Encoding.UTF8, "application/json"))
{
var json = JsonConvert.SerializeObject(message, JsonSettings);
using (var content = new StringContent(json, Encoding.UTF8, "application/json"))
{
var resp = await _httpClient.PostAsync(webhookUrl, content);
resp.EnsureSuccessStatusCode();
}
var resp = await _httpClient.PostAsync(webhookUrl, content);
resp.EnsureSuccessStatusCode();
}
}
}
}
47 changes: 23 additions & 24 deletions src/Seq.App.Slack/Api/SlackMessage.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Seq.App.Slack.Api
namespace Seq.App.Slack.Api;

public class SlackMessage
{
public class SlackMessage
{
[JsonProperty("fallback")]
public string Fallback { get; }
[JsonProperty("fallback")]
public string Fallback { get; }

[JsonProperty("text")]
public string Text { get; }
[JsonProperty("text")]
public string Text { get; }

[JsonProperty("attachments")]
public List<SlackMessageAttachment> Attachments { get; }
[JsonProperty("attachments")]
public List<SlackMessageAttachment> Attachments { get; }

[JsonProperty("username")]
public string Username { get; }
[JsonProperty("username")]
public string Username { get; }

[JsonProperty("icon_url")]
public string IconUrl { get; }
[JsonProperty("icon_url")]
public string IconUrl { get; }

[JsonProperty("channel")]
public string Channel { get; }
[JsonProperty("channel")]
public string? Channel { get; }

public SlackMessage(string fallback, string text, string username, string iconUrl, string channel)
{
this.Fallback = fallback;
this.Text = text;
this.Attachments = new List<SlackMessageAttachment>();
this.Username = username;
this.IconUrl = iconUrl;
this.Channel = channel;
}
public SlackMessage(string fallback, string text, string username, string iconUrl, string? channel)
{
this.Fallback = fallback;
this.Text = text;
this.Attachments = new List<SlackMessageAttachment>();
this.Username = username;
this.IconUrl = iconUrl;
this.Channel = channel;
}
}
47 changes: 23 additions & 24 deletions src/Seq.App.Slack/Api/SlackMessageAttachment.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Seq.App.Slack.Api
namespace Seq.App.Slack.Api;

public class SlackMessageAttachment
{
public class SlackMessageAttachment
{
[JsonProperty("color")]
public string Color { get; }
[JsonProperty("color")]
public string Color { get; }

[JsonProperty("text")]
public string Text { get; }
[JsonProperty("text")]
public string? Text { get; }

[JsonProperty("title")]
public string Title { get; }
[JsonProperty("title")]
public string? Title { get; }

[JsonProperty("fields")]
public List<SlackMessageAttachmentField> Fields { get; }
[JsonProperty("fields")]
public List<SlackMessageAttachmentField> Fields { get; }

[JsonProperty("mrkdwn_in")]
public List<string> MarkdownIn { get; }
[JsonProperty("mrkdwn_in")]
public List<string> MarkdownIn { get; }

public SlackMessageAttachment(string color, string text = null, string title = null, bool textIsMarkdown = false)
{
this.Color = color;
this.Text = text;
this.Title = title;
this.Fields = new List<SlackMessageAttachmentField>();
this.MarkdownIn = new List<string>();
public SlackMessageAttachment(string color, string? text = null, string? title = null, bool textIsMarkdown = false)
{
this.Color = color;
this.Text = text;
this.Title = title;
this.Fields = new List<SlackMessageAttachmentField>();
this.MarkdownIn = new List<string>();

if (textIsMarkdown)
this.MarkdownIn.Add("text");
}
if (textIsMarkdown)
this.MarkdownIn.Add("text");
}
}
}
29 changes: 14 additions & 15 deletions src/Seq.App.Slack/Api/SlackMessageAttachmentField.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
using Newtonsoft.Json;

namespace Seq.App.Slack.Api
namespace Seq.App.Slack.Api;

public class SlackMessageAttachmentField
{
public class SlackMessageAttachmentField
{
[JsonProperty("title")]
public string Title { get; }
[JsonProperty("title")]
public string Title { get; }

[JsonProperty("value")]
public string Value { get; }
[JsonProperty("value")]
public string Value { get; }

[JsonProperty("short")]
public bool Short { get; }
[JsonProperty("short")]
public bool Short { get; }

public SlackMessageAttachmentField(string title, string value, bool @short)
{
Title = title;
Value = value;
Short = @short;
}
public SlackMessageAttachmentField(string title, string value, bool @short)
{
Title = title;
Value = value;
Short = @short;
}
}
Loading
Loading