using Church.Net.Entity.Messenger; using Church.Net.Utility; using LineMessaging; using Microsoft.Extensions.Logging.Abstractions; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using WebAPI.Logics.Interface; using WebAPI.Services.Interfaces; using static System.Net.Mime.MediaTypeNames; namespace WebAPI.Services { [Flags] public enum LineGroup { [Description("Cac4ac5a8d7fc52daa444d71dc7c360a9")] Ark = 1 << 0, [Description("Ca20e3b65aa58e676815eb13c3222591a")] ArkCowoker = 1 << 1, [Description("U97e9e579a41a5222e33bf68a3bf479a0")] Chris = ~(~0 << 20), } public class LineAutoBotService { private readonly IEnumerable autoReplyCommands; private readonly ILoggingService loggingService; private readonly ICrudLogic clientLogic; public LineAutoBotService( IEnumerable autoReplyCommands, ILoggingService loggingService, ICrudLogic clientLogic ) { this.autoReplyCommands = autoReplyCommands; this.loggingService = loggingService; this.clientLogic = clientLogic; } public void SendTextMessage(string text, LineGroup target) { var test = new LineMessagingClient(); try { var wait = test.PushMessage(EnumHelper.EnumToDescriptionString(target), new LineTextMessage() { Text = text }) .GetAwaiter(); wait.GetResult(); } catch (Exception ex) { this.loggingService.Error(ex); } } public async Task ReplyTextMessage(string replyToken, IEnumerable textMessages) { var test = new LineMessagingClient(); var replyMessage = new LineReplyMessage() { ReplyToken = replyToken }; var messages = new List(); foreach (var message in textMessages) { messages.Add(new LineTextMessage() { Text = message }); } replyMessage.Messages = messages; //test.ReplyMessage(replyMessage); try { await test.ReplyMessage(replyMessage); return true; } catch (Exception ex) { this.loggingService.Error(ex, "ReplyTextMessage:75", JsonConvert.SerializeObject(replyMessage, Formatting.Indented)); if (ex.Message == "You have reached your monthly limit.") { this.SendTextMessage("Line Bot Exist Monthly Limit!!!", LineGroup.Chris); } return false; } } public async Task ReplyLineMessage(string replyToken, IEnumerable lineMessages) { var test = new LineMessagingClient(); var replyMessage = new LinePushMessage() { To = replyToken }; replyMessage.Messages = lineMessages; try { //var wait= test.PushMessage(replyMessage).GetAwaiter(); //wait.GetResult(); await test.PushMessage(replyMessage); return true; } catch (Exception ex) { this.loggingService.Error(ex, "ReplyLineMessage:95", JsonConvert.SerializeObject(replyMessage, Formatting.Indented)); if (ex.Message == "You have reached your monthly limit.") { this.SendTextMessage("Line Bot Exist Monthly Limit!!!", LineGroup.Chris); } return false; } } public async Task AutoReply(LineWebhookContent content) { loggingService.Log("AutoReply", content); try { foreach (var e in content.Events) { if (e.Message.Type == MessageType.Text) { List textMessages = new List(); string replyToken = e.ReplyToken; string text = e.Message.Text; string target = ""; bool isGroup = true; var client = new LineMessagingClient(); switch (e.Source.Type) { case WebhookRequestSourceType.User: target = e.Source.UserId; isGroup = false; break; case WebhookRequestSourceType.Group: target = e.Source.GroupId; break; case WebhookRequestSourceType.Room: target = e.Source.RoomId; break; default: break; } if (isGroup) { if (clientLogic.First(c => c.ClientId == e.Source.GroupId) == null) { clientLogic.CreateOrUpdate(new LineMessageClient() { ClientId = target, Name = client.GetGroupProfile(e.Source.GroupId).Result.GroupName, IsGroup = true }, out string id); } //TODO:Get user by user id under group } else { if (clientLogic.First(c => c.ClientId == e.Source.UserId) == null) { clientLogic.CreateOrUpdate(new LineMessageClient() { ClientId = target, Name = client.GetProfile(e.Source.UserId).Result.DisplayName, IsGroup = false }, out string id); } } if (!String.IsNullOrWhiteSpace(replyToken) && text.IndexOf("#") == 0) { text = text.ToLower().Substring(1); var group = EnumHelper.GetEnumValueFromDescription(target); var autoReply = autoReplyCommands.Where(ar => ar.SupportGroups.Contains(group) && ar.Commands.Contains(text)).FirstOrDefault(); if (autoReply != null) { if (autoReply.LineMessage != null) { await ReplyLineMessage(target, autoReply.LineMessage); } else { await ReplyTextMessage(replyToken, autoReply.ReplyMessage); } return true; } else if (text == "help" || text == "?") { StringBuilder commandText = new StringBuilder(); commandText.AppendLine("方舟資訊部 - 指令清單"); foreach (var ar in autoReplyCommands.Where(ar => ar.SupportGroups.Contains(group))) { commandText.AppendLine($"{string.Join(", ", ar.Commands.Select(s => $"#{s}"))} - {ar.Description}"); } commandText.Append($"#help, #? - 顯示指令清單"); await ReplyTextMessage(replyToken, new string[] { commandText.ToString() }); } } } else if (e.Message.Type == MessageType.Sticker && e.Source.GroupId == LineGroup.Ark.EnumToDescriptionString() && e.Message.PackageId == "1011092" && e.Message.StickerId == "510712") { await ReplyLineMessage(e.Source.GroupId, autoReplyCommands.Where(ar => ar.Commands.Contains("pray")).FirstOrDefault().LineMessage); } } } catch (Exception ex) { loggingService.Error(ex, "AutoReply:188", JsonConvert.SerializeObject(content, Formatting.Indented)); return false; } return true; } public async Task PushCommandMessage(LineGroup group, string command) { try { if (command.IndexOf("#") == 0) { command = command.ToLower().Substring(1); var autoReply = autoReplyCommands.Where(ar => ar.SupportGroups.Contains(group) && ar.Commands.Contains(command)).FirstOrDefault(); if (autoReply != null) { if (autoReply.LineMessage != null) { await ReplyLineMessage(group.EnumToDescriptionString(), autoReply.LineMessage); } else { await ReplyTextMessage(group.EnumToDescriptionString(), autoReply.ReplyMessage); } return true; } else if (command == "help" || command == "?") { StringBuilder commandText = new StringBuilder(); commandText.AppendLine("方舟資訊部 - 指令清單"); foreach (var ar in autoReplyCommands.Where(ar => ar.SupportGroups.Contains(group))) { commandText.AppendLine($"{string.Join(", ", ar.Commands.Select(s => $"#{s}"))} - {ar.Description}"); } commandText.Append($"#help, #? - 顯示指令清單"); await ReplyTextMessage(group.EnumToDescriptionString(), new string[] { commandText.ToString() }); } } } catch (Exception ex) { loggingService.Error(ex, "AutoReply:188", command); return false; } return true; } } }