forked from AcaMate/AcaMate_API
126 lines
4.1 KiB
C#
126 lines
4.1 KiB
C#
using System;
|
|
using System.Net.Http;
|
|
using System.Security.Cryptography;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
using AcaMate.V1.Models;
|
|
using Version = System.Version;
|
|
|
|
public class ApnsPushService
|
|
{
|
|
private readonly string _uri;
|
|
private readonly string _p12Path;
|
|
private readonly string _p12PWPath;
|
|
private readonly string _apnsTopic;
|
|
|
|
|
|
public ApnsPushService(string uri,string p12Path, string p12PWPath, string apnsTopic)
|
|
{
|
|
_uri = uri ?? throw new ArgumentNullException(nameof(uri));
|
|
_p12Path = p12Path ?? throw new ArgumentNullException(nameof(p12Path));
|
|
_p12PWPath = p12PWPath ?? throw new ArgumentNullException(nameof(p12PWPath));
|
|
_apnsTopic = apnsTopic ?? throw new ArgumentNullException(nameof(apnsTopic));
|
|
}
|
|
|
|
public async Task<APIResult> SendPushNotificationAsync(string deviceToken, Payload payload)
|
|
{
|
|
|
|
// 존재 안하면 예외 던져 버리는거
|
|
if (!File.Exists(_p12PWPath))
|
|
{
|
|
Console.WriteLine($"File not found: {_p12PWPath}");
|
|
return new APIResult
|
|
{
|
|
Success = false ,
|
|
Code = "003",
|
|
Message = "서버 오류 : p12 PW 파일 확인 필요"
|
|
};
|
|
}
|
|
|
|
var jsonPayload = JsonSerializer.Serialize(payload);
|
|
|
|
var keys = JsonSerializer.Deserialize<Dictionary<string, string>>(File.ReadAllText(_p12PWPath));
|
|
var p12Password = keys["Password"];
|
|
|
|
try
|
|
{
|
|
var certificate = new X509Certificate2(_p12Path, p12Password);
|
|
Console.WriteLine($"Certificate Subject: {certificate.Subject}");
|
|
Console.WriteLine($"Certificate Issuer: {certificate.Issuer}");
|
|
|
|
var handler = new HttpClientHandler();
|
|
handler.ClientCertificates.Add(certificate);
|
|
handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
|
|
|
|
using var client = new HttpClient(handler)
|
|
{
|
|
BaseAddress = new Uri(_uri),
|
|
Timeout = TimeSpan.FromSeconds(60)
|
|
};
|
|
|
|
var request = new HttpRequestMessage(HttpMethod.Post, $"/3/device/{deviceToken}")
|
|
{
|
|
Content = new StringContent(jsonPayload, Encoding.UTF8, "application/json"),
|
|
Version = new Version(2, 0) // HTTP/2 사용
|
|
};
|
|
|
|
// 필수 헤더 추가
|
|
request.Headers.Add("apns-topic", _apnsTopic);
|
|
request.Headers.Add("apns-push-type", "alert");
|
|
|
|
Console.WriteLine($"Send -> Payload: {jsonPayload}");
|
|
|
|
var response = await client.SendAsync(request);
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
return new APIResult
|
|
{
|
|
Success = true
|
|
};
|
|
}
|
|
else
|
|
{
|
|
var errorContent = await response.Content.ReadAsStringAsync();
|
|
return new APIResult
|
|
{
|
|
Success = false,
|
|
Code = "003",
|
|
Message = $"APN 통신 실패 = {response.StatusCode} : {errorContent}"
|
|
};
|
|
}
|
|
}
|
|
catch (HttpRequestException httpEx)
|
|
{
|
|
Console.WriteLine($"HttpRequestException: {httpEx.Message}");
|
|
return new APIResult
|
|
{
|
|
Success = false,
|
|
Code = "003",
|
|
Message = $"통신 실패 : {httpEx.Message}"
|
|
};
|
|
}
|
|
|
|
catch (CryptographicException ex)
|
|
{
|
|
return new APIResult
|
|
{
|
|
Success = false,
|
|
Code = "999",
|
|
Message = $"오류 발생 : {ex.Message}"
|
|
};
|
|
}
|
|
|
|
catch (Exception ex)
|
|
{
|
|
return new APIResult
|
|
{
|
|
Success = false,
|
|
Code = "999",
|
|
Message = $"오류 발생 : {ex.Message}"
|
|
};
|
|
}
|
|
}
|
|
} |