patbef-ServiceOutside/ServiceOutside/Service/Notification.cs

218 lines
9.2 KiB
C#
Raw Permalink Normal View History

2024-01-29 16:27:34 +01:00
using dotAPNS;
using FirebaseAdmin;
using FirebaseAdmin.Messaging;
using Google.Apis.Auth.OAuth2;
using Newtonsoft.Json.Linq;
using ServiceOutside.Models;
using ServiceShared;
using ServiceShared.Crypto;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using static ServiceShared.Models.Database.Device;
using static ServiceShared.Models.Database.Results;
namespace ServiceOutside.Service
{
public static class Notification
{
/// <summary>
/// PushNotificationsConfigurations for Notification Service
/// </summary>
private static PushNotificationsConfiguration Configurations { get; set; }
/// <summary>
/// Sets configurations for push service
/// </summary>
/// <param name="pushNotificationsConfiguration">PushNotificationsConfiguration object</param>
public static void SetConfigurations(PushNotificationsConfiguration pushNotificationsConfiguration)
{
Configurations = pushNotificationsConfiguration;
}
/// <summary>
/// Sends the notification message to the mobile device
/// </summary>
/// <param name="deviceToken">device token of receiver</param>
/// <param name="deviceType">device type of receivr</param>
/// <param name="message">message object, that contains title, subtitle and body</param>
/// <returns></returns>
public static async Task<bool> Send(string deviceToken, DeviceTypes deviceType, Message message)
{
bool result = false;
Log.Debug("Notification Service send to device: " + (!string.IsNullOrEmpty(deviceToken) ? deviceToken : "") + ", " + (message != null && !string.IsNullOrEmpty(message.Body) ? message.Body : ""));
if(!string.IsNullOrEmpty(deviceToken) && deviceType != DeviceTypes.NONE && message != null)
{
switch(deviceType)
{
case DeviceTypes.IOS:
result = await SendToIOS(deviceToken, message.Title, message.Subtitle, message.Body);
break;
case DeviceTypes.ANDROID:
result = await SendToAndroid(deviceToken, message.Title, message.Body);
break;
}
}
return result;
}
/// <summary>
/// Sends notification message to the ios devices
/// </summary>
/// <param name="deviceToken">device_token, that should get the notification message</param>
/// <param name="title">title of notification message</param>
/// <param name="subtitle">subtitle of notification message</param>
/// <param name="body">body of notification message</param>
/// <returns>returns true if successfully sent</returns>
public static async Task<bool> SendToIOS(string deviceToken, string title, string subtitle, string body)
{
bool result = false;
try
{
if (Configurations.Valid && !string.IsNullOrEmpty(deviceToken) &&
!string.IsNullOrEmpty(title) &&
!string.IsNullOrEmpty(subtitle) &&
!string.IsNullOrEmpty(body))
{
var options = new ApnsJwtOptions()
{
BundleId = Configurations.APNS_BUNDLE_ID,
CertFilePath = Configurations.APNS_CERT,
KeyId = Configurations.APNS_KEY_ID,
TeamId = Configurations.APNS_TEAM_ID
};
ApnsClient client = ApnsClient.CreateUsingJwt(new HttpClient(), options);
ApplePush push = new ApplePush(ApplePushType.Alert);
push.AddAlert(title, subtitle, body);
push.AddBadge(1);
push.AddSound();
push.AddToken(deviceToken);
Log.Debug("Sending notification(IOS): " + (!string.IsNullOrEmpty(deviceToken) ? deviceToken : " device token not found"));
ApnsResponse apnsResponse = await client.SendAsync(push);
result = apnsResponse.IsSuccessful;
Log.Debug("ApnsResponse: success: " + (apnsResponse != null && apnsResponse.IsSuccessful ? " true " : " false ") + " reason: "+ (apnsResponse != null && !string.IsNullOrEmpty(apnsResponse.ReasonString) ? apnsResponse.ReasonString : ""));
}
else
{
Log.Debug("Apple ApnsJwt, deviceToken or message is invalid");
}
}
catch (Exception ex)
{
Log.Debug("ServiceOutside.Service.Notification.SendToIOS EX: " + ex.Message);
}
return result;
}
private static bool ServerCertificateCustomValidation(HttpRequestMessage requestMessage, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors sslErrors)
{
return true;
}
/// <summary>
/// Sends notification message to the android devices
/// </summary>
/// <param name="deviceToken">device_token, that should get the notification message</param>
/// <param name="title">title of notification message</param>
/// <param name="body">body of notification message</param>
/// <returns>returns true if successfully sent</returns>
public static async Task<bool> SendToAndroid(string deviceToken, string title, string body)
{
bool result = false;
try
{
if (Configurations.Valid && !string.IsNullOrEmpty(deviceToken) &&
!string.IsNullOrEmpty(title) &&
!string.IsNullOrEmpty(body))
{
Log.Debug("GoogleCredential file: " + Configurations.GOOGLE_CREDENTIAL_JSON);
GoogleCredential googleCredential = GoogleCredential.FromFile(Configurations.GOOGLE_CREDENTIAL_JSON);
if(FirebaseApp.DefaultInstance == null)
{
FirebaseApp.Create(new AppOptions() { Credential = googleCredential });
}
FirebaseAdmin.Messaging.Message message = new FirebaseAdmin.Messaging.Message();
message.Token = deviceToken;
message.Notification = new FirebaseAdmin.Messaging.Notification();
message.Notification.Title = title;
message.Notification.Body = body;
//BatchResponse response = await FirebaseMessaging.DefaultInstance.SendMulticastAsync(multicastMessage).ConfigureAwait(true);
Log.Debug("Sending notification(Android): " + (!string.IsNullOrEmpty(deviceToken) ? deviceToken : " device token not found"));
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message).ConfigureAwait(true);
result = !string.IsNullOrEmpty(response);
Log.Debug(response);
}
else
{
Log.Debug("Google credential, deviceToken or message is invalid");
}
}
catch (Exception ex)
{
Log.Debug("ServiceOutside.Service.Notification.SendToAndroid EX: " + ex.Message);
}
return result;
}
/// <summary>
/// Message object that contains title, subtitle and body of push notification
/// </summary>
public class Message
{
public string Title { get; set; }
public string Subtitle { get; set; }
public string Body { get; set; }
public Message()
{
}
public Message(bool available, ResultsStatus status)
{
if(available && status == ResultsStatus.COMPLETED)
{
this.Title = "Neuigkeiten zu Ihrem Befund";
this.Subtitle = "Ihr Befund ist fertig";
this.Body = "Ihr Befund ist fertig und kann in der App abgerufen werden.";
}
else
{
// TODO: Handle other status
switch(status)
{
case ResultsStatus.REJECTED:
this.Title = "Neuigkeiten zu Ihrem Befund";
this.Subtitle = "Ihre Angaben konnten nicht eindeutig einem Auftrag zugeordnet werden";
this.Body = "Bitte wenden Sie sich an den Support";
break;
case ResultsStatus.NOT_FOUND:
this.Title = "Neuigkeiten zu Ihrem Befund";
this.Subtitle = "Die Auftragsnummer wurde nicht gefunden";
this.Body = "Bitte überprüfen Sie Ihre Auftragsnummer oder wenden Sie sich an den Support";
break;
}
}
}
}
}
}