mirror of
https://github.com/jellyfin/jellyfin-plugin-webhook.git
synced 2024-11-23 05:59:58 +00:00
Add Slack client
This commit is contained in:
parent
8af1e676a1
commit
76f95c2f36
@ -4,6 +4,7 @@ using Jellyfin.Plugin.Webhook.Destinations.Generic;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Gotify;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Pushbullet;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Pushover;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Slack;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Smtp;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
|
||||
@ -25,6 +26,7 @@ namespace Jellyfin.Plugin.Webhook.Configuration
|
||||
GotifyOptions = Array.Empty<GotifyOption>();
|
||||
PushbulletOptions = Array.Empty<PushbulletOption>();
|
||||
PushoverOptions = Array.Empty<PushoverOption>();
|
||||
SlackOptions = Array.Empty<SlackOption>();
|
||||
SmtpOptions = Array.Empty<SmtpOption>();
|
||||
}
|
||||
|
||||
@ -58,6 +60,11 @@ namespace Jellyfin.Plugin.Webhook.Configuration
|
||||
/// </summary>
|
||||
public PushoverOption[] PushoverOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the slack options.
|
||||
/// </summary>
|
||||
public SlackOption[] SlackOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the smtp options.
|
||||
/// </summary>
|
||||
|
@ -32,8 +32,11 @@
|
||||
<button id="btnAddPushover" is="emby-button" type="button" class="raised button block">
|
||||
<span>Add Pushover Destination</span>
|
||||
</button>
|
||||
<button id="btnAddSlack" is="emby-button" type="button" class="raised button block">
|
||||
<span>Add Slack Destination</span>
|
||||
</button>
|
||||
<button id="btnAddSmtp" is="emby-button" type="button" class="raised button block">
|
||||
<span>Add SMTP Destionation</span>
|
||||
<span>Add SMTP Destination</span>
|
||||
</button>
|
||||
<br/>
|
||||
<div id="configurationWrapper"></div>
|
||||
@ -253,6 +256,15 @@
|
||||
<input is="emby-input" type="text" data-name="txtChannel" label="Channel:"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="template-slack">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" data-name="txtUsername" label="Display Name:"/>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" data-name="txtIconUrl" label="Icon Url:"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.checkboxContainer {
|
||||
|
@ -304,7 +304,6 @@
|
||||
btnAdd: document.querySelector("#btnAddPushbullet"),
|
||||
template: document.querySelector("#template-pushbullet"),
|
||||
addConfig: function (config) {
|
||||
console.log(config);
|
||||
const template = document.createElement("div");
|
||||
template.dataset.type = "pushbullet";
|
||||
template.appendChild(Webhook.baseConfig.template.cloneNode(true).content);
|
||||
@ -369,6 +368,33 @@
|
||||
return config;
|
||||
}
|
||||
},
|
||||
slack: {
|
||||
btnAdd: document.querySelector("#btnAddSlack"),
|
||||
template: document.querySelector("#template-slack"),
|
||||
addConfig: function (config) {
|
||||
const template = document.createElement("div");
|
||||
template.dataset.type = "slack";
|
||||
template.appendChild(Webhook.baseConfig.template.cloneNode(true).content);
|
||||
template.appendChild(Webhook.slack.template.cloneNode(true).content);
|
||||
|
||||
const baseConfig = Webhook.baseConfig.addConfig(template, "Slack");
|
||||
Webhook.configurationWrapper.appendChild(baseConfig);
|
||||
|
||||
// Load configuration.
|
||||
Webhook.slack.setConfig(config, baseConfig);
|
||||
},
|
||||
setConfig: function (config, element) {
|
||||
Webhook.baseConfig.setConfig(config, element);
|
||||
element.querySelector("[data-name=txtUsername]").value = config.Username || "";
|
||||
element.querySelector("[data-name=txtIconUrl]").value = config.IconUrl || "";
|
||||
},
|
||||
getConfig: function (e) {
|
||||
const config = Webhook.baseConfig.getConfig(e);
|
||||
config.Username = e.querySelector("[data-name=txtUsername]").value || "";
|
||||
config.IconUrl = e.querySelector("[data-name=txtIconUrl]").value || "";
|
||||
return config;
|
||||
}
|
||||
},
|
||||
smtp: {
|
||||
btnAdd: document.querySelector("#btnAddSmtp"),
|
||||
template: document.querySelector("#template-smtp"),
|
||||
@ -419,6 +445,7 @@
|
||||
Webhook.gotify.btnAdd.addEventListener("click", Webhook.gotify.addConfig);
|
||||
Webhook.pushbullet.btnAdd.addEventListener("click", Webhook.pushbullet.addConfig);
|
||||
Webhook.pushover.btnAdd.addEventListener("click", Webhook.pushover.addConfig);
|
||||
Webhook.slack.btnAdd.addEventListener("click", Webhook.slack.addConfig);
|
||||
Webhook.smtp.btnAdd.addEventListener("click", Webhook.smtp.addConfig);
|
||||
document.querySelector("#saveConfig").addEventListener("click", Webhook.saveConfig);
|
||||
|
||||
@ -465,6 +492,12 @@
|
||||
config.PushoverOptions.push(Webhook.pushover.getConfig(pushoverConfigs[i]));
|
||||
}
|
||||
|
||||
config.SlackOptions = [];
|
||||
const slackConfigs = document.querySelectorAll("[data-type=slack]");
|
||||
for (let i = 0; i < slackConfigs.length; i++) {
|
||||
config.SlackOptions.push(Webhook.slack.getConfig(slackConfigs[i]));
|
||||
}
|
||||
|
||||
config.SmtpOptions = [];
|
||||
const smtpConfigs = document.querySelectorAll("[data-type=smtp]");
|
||||
for (let i = 0; i < smtpConfigs.length; i++) {
|
||||
@ -498,6 +531,10 @@
|
||||
Webhook.pushover.addConfig(config.PushoverOptions[i]);
|
||||
}
|
||||
|
||||
for (let i = 0; i < config.SlackOptions.length; i++) {
|
||||
Webhook.slack.addConfig(config.SlackOptions[i]);
|
||||
}
|
||||
|
||||
for (let i = 0; i < config.SmtpOptions.length; i++) {
|
||||
Webhook.smtp.addConfig(config.SmtpOptions[i]);
|
||||
}
|
||||
|
55
Jellyfin.Plugin.Webhook/Destinations/Slack/SlackClient.cs
Normal file
55
Jellyfin.Plugin.Webhook/Destinations/Slack/SlackClient.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Net.Mime;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Pushover;
|
||||
using MediaBrowser.Common.Net;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Jellyfin.Plugin.Webhook.Destinations.Slack
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class SlackClient : IWebhookClient<SlackOption>
|
||||
{
|
||||
private readonly ILogger<SlackClient> _logger;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SlackClient"/> class.
|
||||
/// </summary>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{SlackClient}"/> interface.</param>
|
||||
/// <param name="httpClientFactory">Instance of the <see cref="IHttpClientFactory"/>.</param>
|
||||
public SlackClient(ILogger<SlackClient> logger, IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task SendAsync(SlackOption option, Dictionary<string, object> data)
|
||||
{
|
||||
try
|
||||
{
|
||||
data["SlackUsername"] = option.Username;
|
||||
data["SlackIconUrl"] = option.IconUrl;
|
||||
|
||||
var body = option.GetCompiledTemplate()(data);
|
||||
_logger.LogDebug("SendAsync Body: {@Body}", body);
|
||||
using var content = new StringContent(body, Encoding.UTF8, MediaTypeNames.Application.Json);
|
||||
using var response = await _httpClientFactory
|
||||
.CreateClient(NamedClient.Default)
|
||||
.PostAsync(option.WebhookUri, content);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseStr = await response.Content.ReadAsStringAsync();
|
||||
_logger.LogWarning("Error sending notification: {Response}", responseStr);
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException e)
|
||||
{
|
||||
_logger.LogWarning(e, "Error sending notification");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
Jellyfin.Plugin.Webhook/Destinations/Slack/SlackOption.cs
Normal file
18
Jellyfin.Plugin.Webhook/Destinations/Slack/SlackOption.cs
Normal file
@ -0,0 +1,18 @@
|
||||
namespace Jellyfin.Plugin.Webhook.Destinations.Slack
|
||||
{
|
||||
/// <summary>
|
||||
/// Slack specific options.
|
||||
/// </summary>
|
||||
public class SlackOption : BaseOption
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the username.
|
||||
/// </summary>
|
||||
public string Username { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the icon url.
|
||||
/// </summary>
|
||||
public string IconUrl { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MailKit" Version="2.10.1" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.*" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.*" PrivateAssets="All" />
|
||||
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
|
||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||
|
@ -7,6 +7,7 @@ using Jellyfin.Plugin.Webhook.Destinations.Generic;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Gotify;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Pushbullet;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Pushover;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Slack;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Smtp;
|
||||
using Jellyfin.Plugin.Webhook.Notifiers;
|
||||
using Jellyfin.Plugin.Webhook.Notifiers.ItemAddedNotifier;
|
||||
@ -37,6 +38,7 @@ namespace Jellyfin.Plugin.Webhook
|
||||
serviceCollection.AddScoped<IWebhookClient<GotifyOption>, GotifyClient>();
|
||||
serviceCollection.AddScoped<IWebhookClient<PushbulletOption>, PushbulletClient>();
|
||||
serviceCollection.AddScoped<IWebhookClient<PushoverOption>, PushoverClient>();
|
||||
serviceCollection.AddScoped<IWebhookClient<SlackOption>, SlackClient>();
|
||||
serviceCollection.AddScoped<IWebhookClient<SmtpOption>, SmtpClient>();
|
||||
|
||||
// Register sender.
|
||||
|
17
Jellyfin.Plugin.Webhook/Templates/Slack.handlebars
Normal file
17
Jellyfin.Plugin.Webhook/Templates/Slack.handlebars
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
{{#if_exist SlackUsername}}
|
||||
"username": "{{SlackUsername}}",
|
||||
{{/if_exist}}
|
||||
{{#if_exist SlackIconUrl}}
|
||||
"icon_url": "{{SlackIconUrl}}",
|
||||
{{/if_exist}}
|
||||
{{#if_equals ItemType 'Season'}}
|
||||
"text": "{{{SeriesName}}} {{{Name}}} has been added to {{{ServerName}}}",
|
||||
{{else}}
|
||||
{{#if_equals ItemType 'Episode'}}
|
||||
"text": "{{{SeriesName}}} S{{SeasonNumber00}}E{{EpisodeNumber00}} {{{Name}}} has been added to {{{ServerName}}}",
|
||||
{{else}}
|
||||
"text": "{{{Name}}} ({{Year}}) has been added to {{{ServerName}}}",
|
||||
{{/if_equals}}
|
||||
{{/if_equals}}
|
||||
}
|
@ -9,6 +9,7 @@ using Jellyfin.Plugin.Webhook.Destinations.Generic;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Gotify;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Pushbullet;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Pushover;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Slack;
|
||||
using Jellyfin.Plugin.Webhook.Destinations.Smtp;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
@ -26,6 +27,7 @@ namespace Jellyfin.Plugin.Webhook
|
||||
private readonly IWebhookClient<GotifyOption> _gotifyClient;
|
||||
private readonly IWebhookClient<PushbulletOption> _pushbulletClient;
|
||||
private readonly IWebhookClient<PushoverOption> _pushoverClient;
|
||||
private readonly IWebhookClient<SlackOption> _slackClient;
|
||||
private readonly IWebhookClient<SmtpOption> _smtpClient;
|
||||
|
||||
/// <summary>
|
||||
@ -37,6 +39,7 @@ namespace Jellyfin.Plugin.Webhook
|
||||
/// <param name="gotifyClient">Instance of <see cref="IWebhookClient{GotifyOption}"/>.</param>
|
||||
/// <param name="pushbulletClient">Instance of the <see cref="IWebhookClient{PushbulletOption}"/>.</param>
|
||||
/// <param name="pushoverClient">Instance of the <see cref="IWebhookClient{PushoverOption}"/>.</param>
|
||||
/// <param name="slackClient">Instance of the <see cref="IWebhookClient{SlackOption}"/>.</param>
|
||||
/// <param name="smtpClient">Instance of the <see cref="IWebhookClient{SmtpOption}"/>.</param>
|
||||
public WebhookSender(
|
||||
ILogger<WebhookSender> logger,
|
||||
@ -45,6 +48,7 @@ namespace Jellyfin.Plugin.Webhook
|
||||
IWebhookClient<GotifyOption> gotifyClient,
|
||||
IWebhookClient<PushbulletOption> pushbulletClient,
|
||||
IWebhookClient<PushoverOption> pushoverClient,
|
||||
IWebhookClient<SlackOption> slackClient,
|
||||
IWebhookClient<SmtpOption> smtpClient)
|
||||
{
|
||||
_logger = logger;
|
||||
@ -53,6 +57,7 @@ namespace Jellyfin.Plugin.Webhook
|
||||
_gotifyClient = gotifyClient;
|
||||
_pushbulletClient = pushbulletClient;
|
||||
_pushoverClient = pushoverClient;
|
||||
_slackClient = slackClient;
|
||||
_smtpClient = smtpClient;
|
||||
}
|
||||
|
||||
@ -88,6 +93,11 @@ namespace Jellyfin.Plugin.Webhook
|
||||
await SendNotification(_pushoverClient, option, itemData, itemType);
|
||||
}
|
||||
|
||||
foreach (var option in Configuration.SlackOptions.Where(o => o.NotificationTypes.Contains(notificationType)))
|
||||
{
|
||||
await SendNotification(_slackClient, option, itemData, itemType);
|
||||
}
|
||||
|
||||
foreach (var option in Configuration.SmtpOptions.Where(o => o.NotificationTypes.Contains(notificationType)))
|
||||
{
|
||||
await SendNotification(_smtpClient, option, itemData, itemType);
|
||||
|
@ -16,4 +16,4 @@ artifacts:
|
||||
- "MimeKit.dll"
|
||||
- "BouncyCastle.Crypto.dll"
|
||||
changelog: >
|
||||
Add SMTP and Pushullet clients
|
||||
Add SMTP, Pushullet, Slack clients
|
||||
|
Loading…
Reference in New Issue
Block a user