diff --git a/BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs b/BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs index 65a273e0..4d7d97f7 100644 --- a/BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs +++ b/BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs @@ -1,9 +1,13 @@ using BetterGenshinImpact.Service.Notifier.Exception; using BetterGenshinImpact.Service.Notifier.Interface; +using System; +using System.IO; using System.Net.Http; +using System.Security.Cryptography; using System.Text; using System.Text.Json; using System.Threading.Tasks; +using BetterGenshinImpact.Helpers; using BetterGenshinImpact.Service.Notification.Model; namespace BetterGenshinImpact.Service.Notifier; @@ -31,11 +35,28 @@ public class WorkWeixinNotifier : INotifier try { - var response = await _httpClient.PostAsync(Endpoint, TransformData(content)); - - if (!response.IsSuccessStatusCode) + // If there's a screenshot, send it first as an image + if (content.Screenshot != null) { - throw new NotifierException($"WorkWeixin webhook call failed with code: {response.StatusCode}"); + var imagePayload = await TransformImageData(content.Screenshot); + var imageResponse = await _httpClient.PostAsync(Endpoint, imagePayload); + + if (!imageResponse.IsSuccessStatusCode) + { + throw new NotifierException($"WorkWeixin image webhook call failed with code: {imageResponse.StatusCode}"); + } + } + + // Then send the text message + if (!string.IsNullOrEmpty(content.Message)) + { + var textPayload = await TransformTextData(content.Message); + var textResponse = await _httpClient.PostAsync(Endpoint, textPayload); + + if (!textResponse.IsSuccessStatusCode) + { + throw new NotifierException($"WorkWeixin text webhook call failed with code: {textResponse.StatusCode}"); + } } } catch (NotifierException) @@ -48,19 +69,66 @@ public class WorkWeixinNotifier : INotifier } } - private StringContent TransformData(BaseNotificationData notificationData) + private async Task TransformImageData(System.Drawing.Image screenshot) { - var workweixinMessage = new + var base64Image = ConvertImageToBase64(screenshot); + var md5Image = ComputeMd5Hash(screenshot); + + var imageMessage = new + { + msgtype = "image", + image = new + { + base64 = base64Image, + md5 = md5Image + } + }; + await Task.Yield(); + var serializedImageData = JsonSerializer.Serialize(imageMessage); + return new StringContent(serializedImageData, Encoding.UTF8, "application/json"); + } + + private async Task TransformTextData(string message) + { + var textMessage = new { msgtype = "text", text = new { - content = notificationData.Message + content = message } }; - - var serializedData = JsonSerializer.Serialize(workweixinMessage); - - return new StringContent(serializedData, Encoding.UTF8, "application/json"); + await Task.Yield(); + var serializedTextData = JsonSerializer.Serialize(textMessage); + return new StringContent(serializedTextData, Encoding.UTF8, "application/json"); } -} \ No newline at end of file + + private string ConvertImageToBase64(System.Drawing.Image image) + { + using (var ms = new MemoryStream()) + { + // Save the image to a MemoryStream in JPEG format + image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); + byte[] imageBytes = ms.ToArray(); + + // Convert to Base64 (this will produce a single-line string) + string base64String = Convert.ToBase64String(imageBytes); + return base64String; + } + } + + private string ComputeMd5Hash(System.Drawing.Image image) + { + using (var ms = new MemoryStream()) + { + image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); + byte[] imageBytes = ms.ToArray(); + + // Compute the MD5 hash of the raw byte data + byte[] hashBytes = MD5.HashData(imageBytes); + // Convert hash bytes to a hex string + string md5Hash = BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); + return md5Hash; + } + } +}