Started on whatsapp

pull/3373/head
tidusjar 5 years ago
parent f08033f743
commit 952db09e28

@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace Ombi.Api.Twilio
{
public interface IWhatsAppApi
{
Task<string> SendMessage(WhatsAppModel message, string accountSid, string authToken);
}
}

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Twilio" Version="5.37.2" />
</ItemGroup>
</Project>

@ -0,0 +1,30 @@
using System;
using System.Threading.Tasks;
using Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
namespace Ombi.Api.Twilio
{
public class WhatsAppApi : IWhatsAppApi
{
public async Task<string> SendMessage(WhatsAppModel message, string accountSid, string authToken)
{
// Find your Account Sid and Token at twilio.com/console
// DANGER! This is insecure. See http://twil.io/secure
//const string accountSid = "AC8a1b6ab0d9f351be8210ccc8f7930d27";
//const string authToken = "f280272092780a770f7cd4fb0beed125";
TwilioClient.Init(accountSid, authToken);
var response =await MessageResource.CreateAsync(
body: message.Message,
from: new PhoneNumber($"whatsapp:{message.From}"),
to: new PhoneNumber($"whatsapp:{message.To}")
);
return response.Sid;
}
}
}

@ -0,0 +1,9 @@
namespace Ombi.Api.Twilio
{
public class WhatsAppModel
{
public string Message { get; set; }
public string To { get; set; }
public string From { get; set; }
}
}

@ -0,0 +1,21 @@
using System.Collections.Generic;
using Ombi.Settings.Settings.Models.Notifications;
using Ombi.Store.Entities;
namespace Ombi.Core.Models.UI
{
/// <summary>
/// The view model for the notification settings page
/// </summary>
/// <seealso cref="WhatsAppNotificationsViewModel" />
public class WhatsAppNotificationsViewModel : WhatsAppSettings
{
/// <summary>
/// Gets or sets the notification templates.
/// </summary>
/// <value>
/// The notification templates.
/// </value>
public List<NotificationTemplates> NotificationTemplates { get; set; }
}
}

@ -64,6 +64,7 @@ using Ombi.Schedule.Processor;
using Ombi.Store.Entities;
using Quartz.Spi;
using Ombi.Api.MusicBrainz;
using Ombi.Api.Twilio;
namespace Ombi.DependencyInjection
{
@ -147,6 +148,7 @@ namespace Ombi.DependencyInjection
services.AddTransient<ILidarrApi, LidarrApi>();
services.AddTransient<IGroupMeApi, GroupMeApi>();
services.AddTransient<IMusicBrainzApi, MusicBrainzApi>();
services.AddTransient<IWhatsAppApi, WhatsAppApi>();
}
public static void RegisterStore(this IServiceCollection services) {

@ -37,6 +37,7 @@
<ProjectReference Include="..\Ombi.Api.Telegram\Ombi.Api.Telegram.csproj" />
<ProjectReference Include="..\Ombi.Api.Trakt\Ombi.Api.Trakt.csproj" />
<ProjectReference Include="..\Ombi.Api.TvMaze\Ombi.Api.TvMaze.csproj" />
<ProjectReference Include="..\Ombi.Api.Twilio\Ombi.Api.Twilio.csproj" />
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
<ProjectReference Include="..\Ombi.Notifications\Ombi.Notifications.csproj" />
<ProjectReference Include="..\Ombi.Schedule\Ombi.Schedule.csproj" />

@ -33,6 +33,7 @@ namespace Ombi.Helpers
public static EventId PushoverNotification => new EventId(4005);
public static EventId TelegramNotifcation => new EventId(4006);
public static EventId GotifyNotification => new EventId(4007);
public static EventId WhatsApp => new EventId(4008);
public static EventId TvSender => new EventId(5000);
public static EventId SonarrSender => new EventId(5001);

@ -11,5 +11,6 @@
Mattermost = 6,
Mobile = 7,
Gotify = 8,
WhatsApp = 9
}
}

@ -0,0 +1,125 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Ombi.Core.Settings;
using Ombi.Helpers;
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.Twilio;
namespace Ombi.Notifications.Agents
{
public class WhatsAppNotification : BaseNotification<WhatsAppSettings>
{
public WhatsAppNotification(IWhatsAppApi api, ISettingsService<WhatsAppSettings> sn, ILogger<WhatsAppNotification> log,
INotificationTemplatesRepository r, IMovieRequestRepository m,
ITvRequestRepository t, ISettingsService<CustomizationSettings> s
, IRepository<RequestSubscription> sub, IMusicRequestRepository music,
IRepository<UserNotificationPreferences> userPref) : base(sn, r, m, t,s,log, sub, music, userPref)
{
Api = api;
Logger = log;
}
public override string NotificationName => "WhatsAppNotification";
private IWhatsAppApi Api { get; }
private ILogger Logger { get; }
protected override bool ValidateConfiguration(WhatsAppSettings settings)
{
if (!settings.Enabled)
{
return false;
}
return !settings.AccountSid.IsNullOrEmpty() && !settings.AuthToken.IsNullOrEmpty() && !settings.From.IsNullOrEmpty();
}
protected override async Task NewRequest(NotificationOptions model, WhatsAppSettings settings)
{
await Run(model, settings, NotificationType.NewRequest);
}
protected override async Task NewIssue(NotificationOptions model, WhatsAppSettings settings)
{
await Run(model, settings, NotificationType.Issue);
}
protected override async Task IssueComment(NotificationOptions model, WhatsAppSettings settings)
{
await Run(model, settings, NotificationType.IssueComment);
}
protected override async Task IssueResolved(NotificationOptions model, WhatsAppSettings settings)
{
await Run(model, settings, NotificationType.IssueResolved);
}
protected override async Task AddedToRequestQueue(NotificationOptions model, WhatsAppSettings settings)
{
await Run(model, settings, NotificationType.ItemAddedToFaultQueue);
}
protected override async Task RequestDeclined(NotificationOptions model, WhatsAppSettings settings)
{
await Run(model, settings, NotificationType.RequestDeclined);
}
protected override async Task RequestApproved(NotificationOptions model, WhatsAppSettings settings)
{
await Run(model, settings, NotificationType.RequestApproved);
}
protected override async Task AvailableRequest(NotificationOptions model, WhatsAppSettings settings)
{
await Run(model, settings, NotificationType.RequestAvailable);
}
protected override async Task Send(NotificationMessage model, WhatsAppSettings settings)
{
try
{
var whatsApp = new WhatsAppModel
{
Message = model.Message,
From = settings.From,
To = ""// TODO
};
await Api.SendMessage(whatsApp, settings.AccountSid, settings.AuthToken);
}
catch (Exception e)
{
Logger.LogError(LoggingEvents.WhatsApp, e, "Failed to send WhatsApp Notification");
}
}
protected override async Task Test(NotificationOptions model, WhatsAppSettings 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);
}
private async Task Run(NotificationOptions model, WhatsAppSettings settings, NotificationType type)
{
var parsed = await LoadTemplate(NotificationAgent.WhatsApp, type, model);
if (parsed.Disabled)
{
Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.WhatsApp}");
return;
}
var notification = new NotificationMessage
{
Message = parsed.Message,
};
await Send(notification, settings);
}
}
}

@ -22,6 +22,7 @@
<ProjectReference Include="..\Ombi.Api.Pushover\Ombi.Api.Pushover.csproj" />
<ProjectReference Include="..\Ombi.Api.Slack\Ombi.Api.Slack.csproj" />
<ProjectReference Include="..\Ombi.Api.Telegram\Ombi.Api.Telegram.csproj" />
<ProjectReference Include="..\Ombi.Api.Twilio\Ombi.Api.Twilio.csproj" />
<ProjectReference Include="..\Ombi.Notifications.Templates\Ombi.Notifications.Templates.csproj" />
<ProjectReference Include="..\Ombi.Settings\Ombi.Settings.csproj" />
<ProjectReference Include="..\Ombi.Store\Ombi.Store.csproj" />

@ -0,0 +1,10 @@
namespace Ombi.Settings.Settings.Models.Notifications
{
public class WhatsAppSettings : Settings
{
public bool Enabled { get; set; }
public string AccountSid { get; set; }
public string AuthToken { get; set; }
public string From { get; set; }
}
}

@ -108,7 +108,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Hubs", "Ombi.Hubs\Ombi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.GroupMe", "Ombi.Api.GroupMe\Ombi.Api.GroupMe.csproj", "{9266403C-B04D-4C0F-AC39-82F12C781949}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.MusicBrainz", "Ombi.Api.MusicBrainz\Ombi.Api.MusicBrainz.csproj", "{C5C1769B-4197-4410-A160-0EEF39EDDC98}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.MusicBrainz", "Ombi.Api.MusicBrainz\Ombi.Api.MusicBrainz.csproj", "{C5C1769B-4197-4410-A160-0EEF39EDDC98}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Twilio", "Ombi.Api.Twilio\Ombi.Api.Twilio.csproj", "{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -292,6 +294,10 @@ Global
{C5C1769B-4197-4410-A160-0EEF39EDDC98}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5C1769B-4197-4410-A160-0EEF39EDDC98}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5C1769B-4197-4410-A160-0EEF39EDDC98}.Release|Any CPU.Build.0 = Release|Any CPU
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -334,6 +340,7 @@ Global
{27111E7C-748E-4996-BD71-2117027C6460} = {6F42AB98-9196-44C4-B888-D5E409F415A1}
{9266403C-B04D-4C0F-AC39-82F12C781949} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{C5C1769B-4197-4410-A160-0EEF39EDDC98} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{34E5DD1A-6A90-448B-9E71-64D1ACD6C1A3} = {9293CA11-360A-4C20-A674-B9E794431BF5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}

@ -963,6 +963,40 @@ namespace Ombi.Controllers.V1
return model;
}
/// <summary>
/// Gets the WhatsApp Notification Settings.
/// </summary>
/// <returns></returns>
[HttpGet("notifications/whatsapp")]
public async Task<WhatsAppNotificationsViewModel> WhatsAppNotificationSettings()
{
var settings = await Get<WhatsAppSettings>();
var model = Mapper.Map<WhatsAppNotificationsViewModel>(settings);
// Lookup to see if we have any templates saved
model.NotificationTemplates = BuildTemplates(NotificationAgent.WhatsApp);
return model;
}
/// <summary>
/// Saves the Mattermost notification settings.
/// </summary>
/// <param name="model">The model.</param>
/// <returns></returns>
[HttpPost("notifications/whatsapp")]
public async Task<bool> WhatsAppNotificationSettings([FromBody] WhatsAppNotificationsViewModel model)
{
// Save the email settings
var settings = Mapper.Map<WhatsAppSettings>(model);
var result = await Save(settings);
// Save the templates
await TemplateRepository.UpdateRange(model.NotificationTemplates);
return result;
}
/// <summary>
/// Saves the Mobile notification settings.
/// </summary>

@ -81,6 +81,7 @@
<ProjectReference Include="..\Ombi.Api.Github\Ombi.Api.Github.csproj" />
<ProjectReference Include="..\Ombi.Api.Lidarr\Ombi.Api.Lidarr.csproj" />
<ProjectReference Include="..\Ombi.Api.SickRage\Ombi.Api.SickRage.csproj" />
<ProjectReference Include="..\Ombi.Api.Twilio\Ombi.Api.Twilio.csproj" />
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
<ProjectReference Include="..\Ombi.DependencyInjection\Ombi.DependencyInjection.csproj" />
<ProjectReference Include="..\Ombi.Hubs\Ombi.Hubs.csproj" />

@ -2,12 +2,10 @@
using AutoMapper.EquivalencyExpression;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -24,7 +22,6 @@ using Ombi.Store.Context;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
using Serilog;
using SQLitePCL;
using System;
using System.IO;
using Microsoft.AspNetCore.StaticFiles.Infrastructure;

Loading…
Cancel
Save