EOS-WebAPI/Common/FirebaseNotificationSender.cs
Nidhi Bhargava d0ac8a7790 Code Commit
2025-09-04 17:30:22 +05:30

304 lines
10 KiB
C#

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using DBHelper;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Parameters;
using System.Configuration;
using System.Web.Script.Serialization;
namespace VECV_WebApi.Common
{
public class FirebaseNotificationSender
{
private static string serviceAccountPath = (ConfigurationManager.AppSettings["FCMJson"]);
private static string firebaseProjectId = (ConfigurationManager.AppSettings["ProjectId"]);
//private static string fcmUrl = $"https://fcm.googleapis.com/v1/projects/" + firebaseProjectId + "/messages:send";
private string fcmUrl;
public FirebaseNotificationSender()
{
fcmUrl = $"https://fcm.googleapis.com/v1/projects/{firebaseProjectId}/messages:send";
}
public string GetAccessTokenValue()
{
// var jwtGenerator = new GetAccessToken();
return GetAccessToken();
}
public void SendNotification(string accessToken, string deviceToken, string title, string body)
{
var payload = new
{
message = new
{
token = deviceToken,
notification = new
{
title = title,
body = body
}
}
};
string jsonPayload = JsonConvert.SerializeObject(payload);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fcmUrl);
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("Authorization", "Bearer " + accessToken);
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(jsonPayload);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string responseContent = reader.ReadToEnd();
Console.WriteLine("FCM Response: " + responseContent);
}
}
private static string GetAccessToken()
{
string json = File.ReadAllText(serviceAccountPath);
var keyData = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
string clientEmail = keyData["client_email"].ToString();
string privateKey = keyData["private_key"].ToString();
string tokenUri = "https://oauth2.googleapis.com/token";
// Create JWT Header & Payload
var now = DateTime.UtcNow;
var payload = new Dictionary<string, object>
{
{ "iss", clientEmail },
{ "scope", "https://www.googleapis.com/auth/firebase.messaging" },
{ "aud", tokenUri },
{ "iat", (int)(now - new DateTime(1970, 1, 1)).TotalSeconds },
{ "exp", (int)(now.AddMinutes(60) - new DateTime(1970, 1, 1)).TotalSeconds }
};
string jwt = CreateJwt(privateKey, payload);
// Exchange JWT for OAuth Token
using (var webClient = new WebClient())
{
var requestParams = new Dictionary<string, string>
{
{ "grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer" },
{ "assertion", jwt }
};
string postData = new JavaScriptSerializer().Serialize(requestParams);
webClient.Headers[HttpRequestHeader.ContentType] = "application/json";
string response = webClient.UploadString(tokenUri, postData);
var responseObj = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(response);
return responseObj["access_token"].ToString();
}
}
private static string CreateJwt(string privateKey, Dictionary<string, object> payload)
{
var rsaParams = GetRsaParameters(privateKey);
var rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParams);
var header = new { alg = "RS256", typ = "JWT" };
string encodedHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header)));
string encodedPayload = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload)));
string unsignedToken = $"{encodedHeader}.{encodedPayload}";
byte[] signature = rsa.SignData(Encoding.UTF8.GetBytes(unsignedToken), CryptoConfig.MapNameToOID("SHA256"));
return $"{unsignedToken}.{Convert.ToBase64String(signature)}";
}
private static RSAParameters GetRsaParameters(string privateKey)
{
var pemReader = new PemReader(new StringReader(privateKey));
var keyObject = pemReader.ReadObject();
// Handle the case where the private key is directly a RsaPrivateCrtKeyParameters
if (keyObject is RsaPrivateCrtKeyParameters privateRsaParams)
{
return DotNetUtilities.ToRSAParameters(privateRsaParams);
}
// Handle AsymmetricCipherKeyPair (private and public key)
if (keyObject is AsymmetricCipherKeyPair keyPair)
{
privateRsaParams = (RsaPrivateCrtKeyParameters)keyPair.Private;
return DotNetUtilities.ToRSAParameters(privateRsaParams);
}
throw new InvalidOperationException("Unsupported private key format.");
}
}
}
/*static string jsonFilePath = @"path-to-your-service-account.json"; // Path to JSON file
string accessToken = GetAccessTokenFromJsonFile(jsonFilePath);
static string GetAccessTokenFromJsonFile(string jsonFilePath)
{
// Read JSON file
string json = File.ReadAllText(jsonFilePath);
var serviceAccountData = JsonConvert.DeserializeObject<ServiceAccount>(json);
if (serviceAccountData == null)
{
throw new Exception("Invalid service account JSON file.");
}
// Generate JWT
string jwtToken = GenerateJwt(serviceAccountData);
// Request access token
string token = RequestAccessToken(jwtToken);
return token;
}
static string RequestAccessToken(string jwtToken)
{
string tokenUrl = "https://oauth2.googleapis.com/token";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(tokenUrl);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string postData = $"grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={jwtToken}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentLength = byteArray.Length;
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
try
{
using (WebResponse response = request.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string responseString = reader.ReadToEnd();
var jsonResponse = JsonConvert.DeserializeObject<dynamic>(responseString);
return jsonResponse.access_token;
}
}
}
catch (WebException ex)
{
using (var errorResponse = ex.Response)
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string errorText = reader.ReadToEnd();
Console.WriteLine($"Error: {errorText}");
}
return null;
}
}
static string GenerateJwt(ServiceAccount serviceAccount)
{
long iat = GetUnixTimestamp();
long exp = iat + 3600;
var header = new { alg = "RS256", typ = "JWT" };
var payload = new Dictionary<string, object>
{
{ "iss", serviceAccount.client_email },
{ "sub", serviceAccount.client_email },
{ "aud", "https://oauth2.googleapis.com/token" },
{ "iat", iat },
{ "exp", exp },
{ "scope", "https://www.googleapis.com/auth/firebase.messaging" }
};
string headerBase64 = Base64UrlEncode(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header)));
string payloadBase64 = Base64UrlEncode(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload)));
string unsignedToken = $"{headerBase64}.{payloadBase64}";
string signedJwt = SignJwt(unsignedToken, serviceAccount.private_key);
return $"{unsignedToken}.{signedJwt}";
}
public static long GetUnixTimestamp()
{
DateTimeOffset dateTimeOffset = DateTimeOffset.UtcNow;
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
TimeSpan elapsedTime = dateTimeOffset.UtcDateTime - epoch;
return (long)elapsedTime.TotalSeconds;
}
static string SignJwt(string unsignedJwt, string privateKey)
{
byte[] privateKeyBytes = Convert.FromBase64String(
privateKey
.Replace("-----BEGIN PRIVATE KEY-----", "")
.Replace("-----END PRIVATE KEY-----", "")
.Replace("\n", "")
);
using (RSACryptoServiceProvider rsa = ImportPrivateKey(privateKey))
{
byte[] hash = HashData(unsignedJwt);
byte[] signature = rsa.SignHash(hash, CryptoConfig.MapNameToOID("SHA256"));
return Base64UrlEncode(signature);
}
}
//static RSACryptoServiceProvider DecodePrivateKey(byte[] privateKeyBytes)
//{
// var rsa = new RSACryptoServiceProvider();
// rsa.ImportPkcs8PrivateKey(privateKeyBytes, out _); // If fails, try importing with OpenSSL-converted private key.
// return rsa;
//}
public static RSACryptoServiceProvider ImportPrivateKey(string pem)
{
PemReader pr = new PemReader(new StringReader(pem));
AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
RSAParameters rsaParams =
DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)KeyPair.Private);
RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
csp.ImportParameters(rsaParams);
return csp;
}
static string Base64UrlEncode(byte[] input)
{
return Convert.ToBase64String(input)
.TrimEnd('=')
.Replace('+', '-')
.Replace('/', '_');
}
static byte[] HashData(string data)
{
using (SHA256 sha256 = SHA256.Create())
{
return sha256.ComputeHash(Encoding.UTF8.GetBytes(data));
}
}
class ServiceAccount
{
public string type { get; set; }
public string project_id { get; set; }
public string private_key_id { get; set; }
public string private_key { get; set; }
public string client_email { get; set; }
public string client_id { get; set; }
public string auth_uri { get; set; }
public string token_uri { get; set; }
public string auth_provider_x509_cert_url { get; set; }
public string client_x509_cert_url { get; set; }
}
}
}
*/