From e526c1071a5eb0104d66a0a315973438ce4b3844 Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 2 Nov 2017 13:19:24 +0000 Subject: [PATCH] Added Telegram Notification support, Not tested. --- README.md | 35 ++--- src/Ombi.Api.Telegram/ITelegramApi.cs | 9 ++ .../Ombi.Api.Telegram.csproj | 11 ++ src/Ombi.Api.Telegram/TelegramApi.cs | 33 ++++ .../UI/TelegramNotificationViewModel.cs | 21 +++ src/Ombi.DependencyInjection/IocExtensions.cs | 3 +- .../Ombi.DependencyInjection.csproj | 1 + src/Ombi.Helpers/LoggingEvents.cs | 1 + src/Ombi.Mapping/Profiles/SettingsProfile.cs | 1 + .../Agents/TelegramNotification.cs | 144 ++++++++++++++++++ .../Ombi.Notifications.csproj | 1 + .../Models/Notifications/TelegramSettings.cs | 10 ++ src/Ombi.sln | 9 +- .../app/interfaces/INotificationSettings.ts | 7 + .../ClientApp/app/interfaces/IRequestModel.ts | 5 + .../app/requests/movierequests.component.ts | 3 + .../services/applications/tester.service.ts | 4 + .../app/services/settings.service.ts | 11 ++ .../notifications/telegram.component.html | 66 ++++++++ .../notifications/telegram.component.ts | 71 +++++++++ .../ClientApp/app/settings/settings.module.ts | 6 +- .../app/settings/settingsmenu.component.html | 1 + src/Ombi/ClientApp/styles/Themes/plex.scss | 15 ++ .../Controllers/External/TesterController.cs | 16 ++ src/Ombi/Controllers/SettingsController.cs | 35 +++++ 25 files changed, 494 insertions(+), 25 deletions(-) create mode 100644 src/Ombi.Api.Telegram/ITelegramApi.cs create mode 100644 src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj create mode 100644 src/Ombi.Api.Telegram/TelegramApi.cs create mode 100644 src/Ombi.Core/Models/UI/TelegramNotificationViewModel.cs create mode 100644 src/Ombi.Notifications/Agents/TelegramNotification.cs create mode 100644 src/Ombi.Settings/Settings/Models/Notifications/TelegramSettings.cs create mode 100644 src/Ombi/ClientApp/app/settings/notifications/telegram.component.html create mode 100644 src/Ombi/ClientApp/app/settings/notifications/telegram.component.ts diff --git a/README.md b/README.md index 7925f9829..ae07711f3 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ ____ [![Report a bug](http://i.imgur.com/xSpw482.png)](https://github.com/tidusjar/Ombi/issues/new) [![Feature request](http://i.imgur.com/mFO0OuX.png)](http://feathub.com/tidusjar/Ombi) -| Service | Master (Version 2.0 - Recommended) | Open Beta (Version 3.0) | +| Service | Master (V2) | Open Beta (V3 - Recommended) | |----------|:---------------------------:|:----------------------------:| | AppVeyor | [![Build status](https://ci.appveyor.com/api/projects/status/hgj8j6lcea7j0yhn/branch/master?svg=true)](https://ci.appveyor.com/project/tidusjar/requestplex/branch/master) | [![Build status](https://ci.appveyor.com/api/projects/status/hgj8j6lcea7j0yhn/branch/DotNetCore?svg=true)](https://ci.appveyor.com/project/tidusjar/requestplex/branch/DotNetCore) | | Download |[![Download](http://i.imgur.com/odToka3.png)](https://github.com/tidusjar/Ombi/releases) | [![Download](http://i.imgur.com/odToka3.png)](https://ci.appveyor.com/project/tidusjar/requestplex/branch/DotNetCore/artifacts) | @@ -24,19 +24,19 @@ Here are some of the features Ombi V3 has: * User management system (supports plex.tv, Emby and local accounts) * A landing page that will give you the availability of your Plex/Emby server and also add custom notification text to inform your users of downtime. * Allows your users to get custom notifications! -* Secure authentication so you don't have to worry about those script kiddies +* Secure authentication using best practises * Will show if the request is already on plex or even if it's already monitored. * Automatically updates the status of requests when they are available on Plex/Emby * Slick, responsive and mobile friendly UI * Ombi will automatically update itself :) -* Very fast system. +* Very fast! ### Integration We integrate with the following applications: * Plex Media Server * Emby * Sonarr -* Radarr (beta) +* Radarr * DogNzb * Couch Potato @@ -49,30 +49,31 @@ Supported notifications: * Pushbullet * Pushover * Mattermost +* Telegram ### The difference between Version 3 and 2 -Over the last 7 months, we focused on the main functions on Ombi, a complete rewrite while making it better, faster and more stable. +Over the last 8 months, we focused on the main functions on Ombi, a complete rewrite while making it better, faster and more stable. We have already done most of the work, but some features are still be missing in this first version. -We are planning to bring back these features in Version 3 but for now you can find a list below with a comparison of features between v2 and v3. +We are planning to bring back these features in V3 but for now you can find a list below with a quick comparison of features between v2 and v3. | Service | Version 3 | Version 2 | |----------|:----------:|:----------:| -| Supported online | Yes | No | -|Multiple Plex/Emby Servers| Yes | No | +| Multiple Plex/Emby Servers| Yes | No | | Emby & Plex support | Yes | Yes | | Mono dependency | No | Yes | | Notifications support | Yes| Yes | | Landing page | Yes (brand new) | Yes | | Login page | Yes (brand new) | Yes | -| Custom Logo in Ombi and notifications | Yes | No | +| Custom Notification Messages | Yes | No | | Sending newsletters | Planned | Yes | | Send a Mass Email | Planned | Yes | -| SickRage | Planned (not supported yet)| Yes | +| SickRage | Planned | Yes | | CouchPotato | Yes | Yes | | Watcher | Planned | Yes | | DogNzb | Yes | No | +| Issues | Planned | Yes | | Headphones | No (support dropped) | Yes | # Feature Requests @@ -89,17 +90,7 @@ Search the existing requests to see if your suggestion has already been submitte # Installation -Windows: Download the windows zip file above and run ombi.exe - -Linux: Download the linux zip file, run chmod +x Ombi to make the Ombi file an executable. - -Get the following error? -libunwind.so.8: cannot open shared object file -You may need to install libwind8. -```apt-get install libunwind8``` - -# FAQ -Do you have an issue or a question? if so check out our [FAQ](https://github.com/tidusjar/Ombi/wiki/FAQ)! +[Click Here](https://github.com/tidusjar/Ombi/wiki/Installation) # Contributors @@ -113,7 +104,7 @@ If you feel like donating you can donate with the below buttons! [![Patreon](https://www.ombi.io/img/patreondonate.svg)](https://patreon.com/tidusjar/Ombi) [![Paypal](https://www.ombi.io/img/paypaldonate.svg)](https://paypal.me/PlexRequestsNet) -### A massive thanks to everyone for all their helps! +### A massive thanks to everyone for all their help! ## Stats [![Throughput Graph](https://graphs.waffle.io/tidusjar/PlexRequests.Net/throughput.svg)](https://waffle.io/tidusjar/PlexRequests.Net/metrics/throughput) diff --git a/src/Ombi.Api.Telegram/ITelegramApi.cs b/src/Ombi.Api.Telegram/ITelegramApi.cs new file mode 100644 index 000000000..6b4e2007a --- /dev/null +++ b/src/Ombi.Api.Telegram/ITelegramApi.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Ombi.Api.Telegram +{ + public interface ITelegramApi + { + Task Send(string message, string botApi, string chatId, string parseMode); + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj b/src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj new file mode 100644 index 000000000..a3651df3c --- /dev/null +++ b/src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.0 + + + + + + + diff --git a/src/Ombi.Api.Telegram/TelegramApi.cs b/src/Ombi.Api.Telegram/TelegramApi.cs new file mode 100644 index 000000000..99942a177 --- /dev/null +++ b/src/Ombi.Api.Telegram/TelegramApi.cs @@ -0,0 +1,33 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Ombi.Api.Telegram +{ + public class TelegramApi : ITelegramApi + { + public TelegramApi(IApi api) + { + _api = api; + } + + private readonly IApi _api; + private const string BaseUrl = "https://api.telegram.org/bot"; + + + public async Task Send(string message, string botApi, string chatId, string parseMode) + { + var request = new Request($"{botApi}/sendMessage", BaseUrl, HttpMethod.Post); + request.AddQueryString("chat_id", chatId); + + var body = new + { + text = message, + parse_mode = parseMode + }; + + request.AddJsonBody(body); + await _api.Request(request); + } + } +} diff --git a/src/Ombi.Core/Models/UI/TelegramNotificationViewModel.cs b/src/Ombi.Core/Models/UI/TelegramNotificationViewModel.cs new file mode 100644 index 000000000..0cf14488b --- /dev/null +++ b/src/Ombi.Core/Models/UI/TelegramNotificationViewModel.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Ombi.Settings.Settings.Models.Notifications; +using Ombi.Store.Entities; + +namespace Ombi.Core.Models.UI +{ + /// + /// The view model for the notification settings page + /// + /// + public class TelegramNotificationsViewModel : TelegramSettings + { + /// + /// Gets or sets the notification templates. + /// + /// + /// The notification templates. + /// + public List NotificationTemplates { get; set; } + } +} diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index 5420e0960..5ae9e7bd5 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -44,10 +44,10 @@ using Ombi.Schedule.Jobs.Emby; using Ombi.Schedule.Jobs.Ombi; using Ombi.Schedule.Jobs.Plex; using Ombi.Schedule.Jobs.Sonarr; -using Ombi.Store.Entities; using Ombi.Store.Repository.Requests; using Ombi.Updater; using PlexContentCacher = Ombi.Schedule.Jobs.Plex.PlexContentCacher; +using Ombi.Api.Telegram; namespace Ombi.DependencyInjection { @@ -99,6 +99,7 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } public static void RegisterStore(this IServiceCollection services) { diff --git a/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj b/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj index 2bdd6caf8..dbb660326 100644 --- a/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj +++ b/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj @@ -28,6 +28,7 @@ + diff --git a/src/Ombi.Helpers/LoggingEvents.cs b/src/Ombi.Helpers/LoggingEvents.cs index a5bbad6aa..34b69864e 100644 --- a/src/Ombi.Helpers/LoggingEvents.cs +++ b/src/Ombi.Helpers/LoggingEvents.cs @@ -27,6 +27,7 @@ namespace Ombi.Helpers public static EventId SlackNotification => new EventId(4003); public static EventId MattermostNotification => new EventId(4004); public static EventId PushoverNotification => new EventId(4005); + public static EventId TelegramNotifcation => new EventId(4006); public static EventId TvSender => new EventId(5000); public static EventId SonarrSender => new EventId(5001); diff --git a/src/Ombi.Mapping/Profiles/SettingsProfile.cs b/src/Ombi.Mapping/Profiles/SettingsProfile.cs index 339e0eb68..5b0c43097 100644 --- a/src/Ombi.Mapping/Profiles/SettingsProfile.cs +++ b/src/Ombi.Mapping/Profiles/SettingsProfile.cs @@ -14,6 +14,7 @@ namespace Ombi.Mapping.Profiles CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); + CreateMap().ReverseMap(); } } } \ No newline at end of file diff --git a/src/Ombi.Notifications/Agents/TelegramNotification.cs b/src/Ombi.Notifications/Agents/TelegramNotification.cs new file mode 100644 index 000000000..9b42f865c --- /dev/null +++ b/src/Ombi.Notifications/Agents/TelegramNotification.cs @@ -0,0 +1,144 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Ombi.Core.Settings; +using Ombi.Helpers; +using Ombi.Notifications.Interfaces; +using Ombi.Notifications.Models; +using Ombi.Settings.Settings.Models; +using Ombi.Settings.Settings.Models.Notifications; +using Ombi.Store.Entities; +using Ombi.Store.Repository; +using Ombi.Store.Repository.Requests; +using Ombi.Api.Telegram; + +namespace Ombi.Notifications.Agents +{ + public class TelegramNotification : BaseNotification + { + public TelegramNotification(ITelegramApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s) : base(sn, r, m, t,s) + { + Api = api; + Logger = log; + } + + public override string NotificationName => "TelegramNotification"; + + private ITelegramApi Api { get; } + private ILogger Logger { get; } + + protected override bool ValidateConfiguration(TelegramSettings settings) + { + if (!settings.Enabled) + { + return false; + } + return !settings.BotApi.IsNullOrEmpty() && !settings.ChatId.IsNullOrEmpty(); + } + + protected override async Task NewRequest(NotificationOptions model, TelegramSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.NewRequest, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + + await Send(notification, settings); + } + + protected override async Task Issue(NotificationOptions model, TelegramSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.Issue, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + await Send(notification, settings); + } + + protected override async Task AddedToRequestQueue(NotificationOptions model, TelegramSettings settings) + { + var user = string.Empty; + var title = string.Empty; + var image = string.Empty; + if (model.RequestType == RequestType.Movie) + { + user = MovieRequest.RequestedUser.UserAlias; + title = MovieRequest.Title; + image = MovieRequest.PosterPath; + } + else + { + user = TvRequest.RequestedUser.UserAlias; + title = TvRequest.ParentRequest.Title; + image = TvRequest.ParentRequest.PosterPath; + } + var message = $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying"; + var notification = new NotificationMessage + { + Message = message + }; + await Send(notification, settings); + } + + protected override async Task RequestDeclined(NotificationOptions model, TelegramSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.RequestDeclined, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + await Send(notification, settings); + } + + protected override async Task RequestApproved(NotificationOptions model, TelegramSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.RequestApproved, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + + await Send(notification, settings); + } + + protected override async Task AvailableRequest(NotificationOptions model, TelegramSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.RequestAvailable, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + await Send(notification, settings); + } + + protected override async Task Send(NotificationMessage model, TelegramSettings settings) + { + try + { + + await Api.Send(model.Message, settings.BotApi, settings.ChatId, settings.ParseMode); + } + catch (Exception e) + { + Logger.LogError(LoggingEvents.TelegramNotifcation, e, "Failed to send Telegram Notification"); + } + } + + protected override async Task Test(NotificationOptions model, TelegramSettings settings) + { + var message = $"This is a test from Ombi, if you can see this then we have successfully pushed a notification!"; + var notification = new NotificationMessage + { + Message = message, + }; + await Send(notification, settings); + } + } +} diff --git a/src/Ombi.Notifications/Ombi.Notifications.csproj b/src/Ombi.Notifications/Ombi.Notifications.csproj index 43db91dd1..48bba1c2c 100644 --- a/src/Ombi.Notifications/Ombi.Notifications.csproj +++ b/src/Ombi.Notifications/Ombi.Notifications.csproj @@ -19,6 +19,7 @@ + diff --git a/src/Ombi.Settings/Settings/Models/Notifications/TelegramSettings.cs b/src/Ombi.Settings/Settings/Models/Notifications/TelegramSettings.cs new file mode 100644 index 000000000..c283a9350 --- /dev/null +++ b/src/Ombi.Settings/Settings/Models/Notifications/TelegramSettings.cs @@ -0,0 +1,10 @@ +namespace Ombi.Settings.Settings.Models.Notifications +{ + public class TelegramSettings : Settings + { + public bool Enabled { get; set; } + public string BotApi { get; set; } + public string ChatId { get; set; } + public string ParseMode { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.sln b/src/Ombi.sln index 5f7af3ead..2c46992c2 100644 --- a/src/Ombi.sln +++ b/src/Ombi.sln @@ -84,7 +84,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.CouchPotato", "Omb EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.DogNzb", "Ombi.Api.DogNzb\Ombi.Api.DogNzb.csproj", "{4F3BF03A-6AAC-4960-A2CD-1EAD7273115E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Tests", "Ombi.Tests\Ombi.Tests.csproj", "{C12F5276-352A-43CF-8E33-400E768E9757}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Tests", "Ombi.Tests\Ombi.Tests.csproj", "{C12F5276-352A-43CF-8E33-400E768E9757}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Telegram", "Ombi.Api.Telegram\Ombi.Api.Telegram.csproj", "{CB9DD209-8E09-4E01-983E-C77C89592D36}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -220,6 +222,10 @@ Global {C12F5276-352A-43CF-8E33-400E768E9757}.Debug|Any CPU.Build.0 = Debug|Any CPU {C12F5276-352A-43CF-8E33-400E768E9757}.Release|Any CPU.ActiveCfg = Release|Any CPU {C12F5276-352A-43CF-8E33-400E768E9757}.Release|Any CPU.Build.0 = Release|Any CPU + {CB9DD209-8E09-4E01-983E-C77C89592D36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB9DD209-8E09-4E01-983E-C77C89592D36}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB9DD209-8E09-4E01-983E-C77C89592D36}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB9DD209-8E09-4E01-983E-C77C89592D36}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -251,6 +257,7 @@ Global {87D7897D-7C73-4856-A0AA-FF5948F4EA86} = {9293CA11-360A-4C20-A674-B9E794431BF5} {4F3BF03A-6AAC-4960-A2CD-1EAD7273115E} = {9293CA11-360A-4C20-A674-B9E794431BF5} {C12F5276-352A-43CF-8E33-400E768E9757} = {6F42AB98-9196-44C4-B888-D5E409F415A1} + {CB9DD209-8E09-4E01-983E-C77C89592D36} = {9293CA11-360A-4C20-A674-B9E794431BF5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869} diff --git a/src/Ombi/ClientApp/app/interfaces/INotificationSettings.ts b/src/Ombi/ClientApp/app/interfaces/INotificationSettings.ts index 6be671eb0..a635c4e40 100644 --- a/src/Ombi/ClientApp/app/interfaces/INotificationSettings.ts +++ b/src/Ombi/ClientApp/app/interfaces/INotificationSettings.ts @@ -52,6 +52,13 @@ export interface IDiscordNotifcationSettings extends INotificationSettings { notificationTemplates: INotificationTemplates[]; } +export interface ITelegramNotifcationSettings extends INotificationSettings { + botApi: string; + chatId: string; + parseMode: string; + notificationTemplates: INotificationTemplates[]; +} + export interface ISlackNotificationSettings extends INotificationSettings { webhookUrl: string; username: string; diff --git a/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts b/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts index 888e8efff..53d788cf6 100644 --- a/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts +++ b/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts @@ -95,9 +95,13 @@ export interface IFullBaseRequest extends IBaseRequest { overview: string; title: string; posterPath: string; + backdropPath: string; releaseDate: Date; status: string; released: boolean; + + // Used in the UI + background: any; } export interface IBaseRequest { @@ -121,6 +125,7 @@ export interface ITvRequests { overview: string; title: string; posterPath: string; + backdropPath: string; releaseDate: Date; status: string; childRequests: IChildRequests[]; diff --git a/src/Ombi/ClientApp/app/requests/movierequests.component.ts b/src/Ombi/ClientApp/app/requests/movierequests.component.ts index 5b2c5cb6f..c4ae1e9de 100644 --- a/src/Ombi/ClientApp/app/requests/movierequests.component.ts +++ b/src/Ombi/ClientApp/app/requests/movierequests.component.ts @@ -122,6 +122,9 @@ export class MovieRequestsComponent implements OnInit { private loadRequests(amountToLoad: number, currentlyLoaded: number) { this.requestService.getMovieRequests(amountToLoad, currentlyLoaded + 1) .subscribe(x => { + // x.background = this.sanitizer. + // bypassSecurityTrustStyle + // ("linear-gradient(to bottom, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.6) 100%),url(" + "https://image.tmdb.org/t/p/w1280" + x.backdropPath + ")"); this.setOverrides(x); this.movieRequests.push.apply(this.movieRequests, x); this.currentlyLoaded = currentlyLoaded + amountToLoad; diff --git a/src/Ombi/ClientApp/app/services/applications/tester.service.ts b/src/Ombi/ClientApp/app/services/applications/tester.service.ts index be9b882f4..433576eb8 100644 --- a/src/Ombi/ClientApp/app/services/applications/tester.service.ts +++ b/src/Ombi/ClientApp/app/services/applications/tester.service.ts @@ -17,6 +17,7 @@ import { IRadarrSettings, ISlackNotificationSettings, ISonarrSettings, + ITelegramNotifcationSettings, } from "../../interfaces"; @Injectable() @@ -61,5 +62,8 @@ export class TesterService extends ServiceAuthHelpers { } public couchPotatoTest(settings: ICouchPotatoSettings): Observable { return this.http.post(`${this.url}couchpotato`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData); + } + public telegramTest(settings: ITelegramNotifcationSettings): Observable { + return this.http.post(`${this.url}telegram`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData); } } diff --git a/src/Ombi/ClientApp/app/services/settings.service.ts b/src/Ombi/ClientApp/app/services/settings.service.ts index 9fb704c0c..02400805d 100644 --- a/src/Ombi/ClientApp/app/services/settings.service.ts +++ b/src/Ombi/ClientApp/app/services/settings.service.ts @@ -22,6 +22,7 @@ import { IRadarrSettings, ISlackNotificationSettings, ISonarrSettings, + ITelegramNotifcationSettings, IUpdateSettings, IUserManagementSettings, } from "../interfaces"; @@ -220,4 +221,14 @@ export class SettingsService extends ServiceAuthHelpers { .post(`${this.url}/DogNzb`, JSON.stringify(settings), { headers: this.headers }) .map(this.extractData).catch(this.handleError); } + + public getTelegramNotificationSettings(): Observable { + return this.httpAuth.get(`${this.url}/notifications/telegram`).map(this.extractData).catch(this.handleError); + } + + public saveTelegramNotificationSettings(settings: ITelegramNotifcationSettings): Observable { + return this.httpAuth + .post(`${this.url}/notifications/telegram`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); + } } diff --git a/src/Ombi/ClientApp/app/settings/notifications/telegram.component.html b/src/Ombi/ClientApp/app/settings/notifications/telegram.component.html new file mode 100644 index 000000000..1c325de40 --- /dev/null +++ b/src/Ombi/ClientApp/app/settings/notifications/telegram.component.html @@ -0,0 +1,66 @@ + + +
+
+ Telegram Notifications +
+
+ +
+
+ + +
+
+ + +
+ + + The Bot API is required + You need a bot for Telegram notifications, You can find out how to create a bot + here. + +
+ + +
+ + + The Chat Id is required + This is the Chat ID from Telegram. You can get the Chat Id from + here. This also supports Group Chat Id's. +
+ +
+ +
+
+ +
+ Select a formatting option for the messages, you can view the supported formatting here. + + +
+
+ +
+
+ +
+
+ +
+
+
+
+ + +
+ +
+
+
\ No newline at end of file diff --git a/src/Ombi/ClientApp/app/settings/notifications/telegram.component.ts b/src/Ombi/ClientApp/app/settings/notifications/telegram.component.ts new file mode 100644 index 000000000..0c9965e8e --- /dev/null +++ b/src/Ombi/ClientApp/app/settings/notifications/telegram.component.ts @@ -0,0 +1,71 @@ +import { Component, OnInit } from "@angular/core"; +import { FormBuilder, FormGroup, Validators } from "@angular/forms"; + +import { INotificationTemplates, ITelegramNotifcationSettings, NotificationType } from "../../interfaces"; +import { TesterService } from "../../services"; +import { NotificationService } from "../../services"; +import { SettingsService } from "../../services"; + +@Component({ + templateUrl: "./telegram.component.html", +}) +export class TelegramComponent implements OnInit { + + public NotificationType = NotificationType; + public templates: INotificationTemplates[]; + public form: FormGroup; + + constructor(private settingsService: SettingsService, + private notificationService: NotificationService, + private fb: FormBuilder, + private testerService: TesterService) { } + + public ngOnInit() { + this.settingsService.getTelegramNotificationSettings().subscribe(x => { + this.templates = x.notificationTemplates; + + this.form = this.fb.group({ + enabled: [x.enabled], + botApi: [x.botApi, [Validators.required]], + chatId: [x.chatId, [Validators.required]], + parseMode: [x.parseMode, [Validators.required]], + + }); + }); + } + + public onSubmit(form: FormGroup) { + if (form.invalid) { + this.notificationService.error("Please check your entered values"); + return; + } + + const settings = form.value; + settings.notificationTemplates = this.templates; + + this.settingsService.saveTelegramNotificationSettings(settings).subscribe(x => { + if (x) { + this.notificationService.success("Successfully saved the Telegram settings"); + } else { + this.notificationService.success("There was an error when saving the Telegram settings"); + } + }); + + } + + public test(form: FormGroup) { + if (form.invalid) { + this.notificationService.error("Please check your entered values"); + return; + } + + this.testerService.telegramTest(form.value).subscribe(x => { + if (x) { + this.notificationService.success("Successfully sent a Telegram message, please check the Telegram channel"); + } else { + this.notificationService.error("There was an error when sending the Telegram message. Please check your settings"); + } + }); + + } +} diff --git a/src/Ombi/ClientApp/app/settings/settings.module.ts b/src/Ombi/ClientApp/app/settings/settings.module.ts index a89fc44ce..8b5bf3137 100644 --- a/src/Ombi/ClientApp/app/settings/settings.module.ts +++ b/src/Ombi/ClientApp/app/settings/settings.module.ts @@ -24,6 +24,7 @@ import { NotificationTemplate } from "./notifications/notificationtemplate.compo import { PushbulletComponent } from "./notifications/pushbullet.component"; import { PushoverComponent } from "./notifications/pushover.component"; import { SlackComponent } from "./notifications/slack.component"; +import { TelegramComponent } from "./notifications/telegram.component"; import { OmbiComponent } from "./ombi/ombi.component"; import { PlexComponent } from "./plex/plex.component"; import { RadarrComponent } from "./radarr/radarr.component"; @@ -34,7 +35,7 @@ import { WikiComponent } from "./wiki.component"; import { SettingsMenuComponent } from "./settingsmenu.component"; -import { AutoCompleteModule, CalendarModule, InputSwitchModule, InputTextModule, MenuModule, TooltipModule } from "primeng/primeng"; +import { AutoCompleteModule, CalendarModule, InputSwitchModule, InputTextModule, MenuModule, RadioButtonModule, TooltipModule } from "primeng/primeng"; const routes: Routes = [ { path: "Settings/Ombi", component: OmbiComponent, canActivate: [AuthGuard] }, @@ -55,6 +56,7 @@ const routes: Routes = [ { path: "Settings/Update", component: UpdateComponent, canActivate: [AuthGuard] }, { path: "Settings/CouchPotato", component: CouchPotatoComponent, canActivate: [AuthGuard] }, { path: "Settings/DogNzb", component: DogNzbComponent, canActivate: [AuthGuard] }, + { path: "Settings/Telegram", component: TelegramComponent, canActivate: [AuthGuard] }, ]; @NgModule({ @@ -74,6 +76,7 @@ const routes: Routes = [ CalendarModule, ClipboardModule, PipeModule, + RadioButtonModule, ], declarations: [ SettingsMenuComponent, @@ -97,6 +100,7 @@ const routes: Routes = [ WikiComponent, CouchPotatoComponent, DogNzbComponent, + TelegramComponent, ], exports: [ RouterModule, diff --git a/src/Ombi/ClientApp/app/settings/settingsmenu.component.html b/src/Ombi/ClientApp/app/settings/settingsmenu.component.html index 98e9067b2..380957eb2 100644 --- a/src/Ombi/ClientApp/app/settings/settingsmenu.component.html +++ b/src/Ombi/ClientApp/app/settings/settingsmenu.component.html @@ -61,6 +61,7 @@
  • Pushbullet
  • Pushover
  • Mattermost
  • +
  • Telegram
  • diff --git a/src/Ombi/ClientApp/styles/Themes/plex.scss b/src/Ombi/ClientApp/styles/Themes/plex.scss index 332ea10e9..0eef3d041 100644 --- a/src/Ombi/ClientApp/styles/Themes/plex.scss +++ b/src/Ombi/ClientApp/styles/Themes/plex.scss @@ -310,4 +310,19 @@ button.list-group-item:focus { .ui-dialog-titlebar{ background:$bg-colour-disabled; color:white; +} + +.ui-state-active{ + color:$primary-colour $i; +} + +.ui-state-default { + border-width: 2px; + border-style: solid; + border-color: $primary-colour-outline; + border-image: initial; +} + +.ui-radiobutton, .ui-radiobutton-label{ + vertical-align: baseline; } \ No newline at end of file diff --git a/src/Ombi/Controllers/External/TesterController.cs b/src/Ombi/Controllers/External/TesterController.cs index 92487e535..47dd1ea93 100644 --- a/src/Ombi/Controllers/External/TesterController.cs +++ b/src/Ombi/Controllers/External/TesterController.cs @@ -9,6 +9,7 @@ using Ombi.Api.Emby; using Ombi.Api.Plex; using Ombi.Api.Radarr; using Ombi.Api.Sonarr; +using Ombi.Api.Telegram; using Ombi.Attributes; using Ombi.Core.Notifications; using Ombi.Core.Settings.Models.External; @@ -292,5 +293,20 @@ namespace Ombi.Controllers.External return false; } } + + /// + /// Sends a test message to Slack using the provided settings + /// + /// The settings. + /// + //[HttpPost("telegram")] + //public async Task Telegram([FromBody] TelegramSettings settings) + //{ + // settings.Enabled = true; + // await TelegramApi.Send("This is a test ") + + // return true; + //} + } } \ No newline at end of file diff --git a/src/Ombi/Controllers/SettingsController.cs b/src/Ombi/Controllers/SettingsController.cs index 395a2b122..2097aa606 100644 --- a/src/Ombi/Controllers/SettingsController.cs +++ b/src/Ombi/Controllers/SettingsController.cs @@ -454,6 +454,41 @@ namespace Ombi.Controllers return model; } + + /// + /// Saves the telegram notification settings. + /// + /// The model. + /// + [HttpPost("notifications/telegram")] + public async Task TelegramNotificationSettings([FromBody] TelegramNotificationsViewModel model) + { + // Save the email settings + var settings = Mapper.Map(model); + var result = await Save(settings); + + // Save the templates + await TemplateRepository.UpdateRange(model.NotificationTemplates); + + return result; + } + + /// + /// Gets the telegram Notification Settings. + /// + /// + [HttpGet("notifications/telegram")] + public async Task TelegramNotificationSettings() + { + var emailSettings = await Get(); + var model = Mapper.Map(emailSettings); + + // Lookup to see if we have any templates saved + model.NotificationTemplates = await BuildTemplates(NotificationAgent.Telegram); + + return model; + } + /// /// Saves the pushbullet notification settings. ///