using Church.Net.DAL.EFCoreDBF; using Church.Net.Entity; 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; 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, PastoralDomain = 1 << 2, HappinessGroup = 1 << 3, [Description("U97e9e579a41a5222e33bf68a3bf479a0")] Chris = ~(~0 << 20), } public class LineAutoBotService { private readonly IEnumerable autoReplyCommands; private readonly ILoggingService loggingService; private readonly ICrudLogic clientLogic; private readonly LineMessagingAccountLogic lineMessagingAccountLogic; private readonly ICrudDAL lineAccountCrudDAL; private string chatToken; private PastoralDomain cellGroup; public LineAutoBotService( IEnumerable autoReplyCommands, ILoggingService loggingService, ICrudLogic clientLogic, LineMessagingAccountLogic lineMessagingAccountLogic, ICrudDAL lineAccountCrudDAL ) { this.autoReplyCommands = autoReplyCommands; this.loggingService = loggingService; this.clientLogic = clientLogic; this.lineMessagingAccountLogic = lineMessagingAccountLogic; this.lineAccountCrudDAL = lineAccountCrudDAL; } public void SendTextMessage(string text, LineGroup target) { var test = new LineMessagingClient(this.chatToken); 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 lineId, string textMessages) { var test = new LineMessagingClient(this.chatToken); //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.PushMessage(lineId, new LineTextMessage() { Text = textMessages }); return true; } catch (Exception ex) { this.loggingService.Error(ex, "ReplyTextMessage:75", textMessages); if (ex.Message == "You have reached your monthly limit.") { this.SendTextMessage("Line Bot Exist Monthly Limit!!!", LineGroup.Chris); } return false; } } public async Task ReplyJsonMessage(string lineId, string jsonMessage) { var test = new LineMessagingClient(this.chatToken); //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.PushJsonMessage(lineId, jsonMessage); return true; } catch (Exception ex) { this.loggingService.Error(ex, "ReplyTextMessage:75", jsonMessage); 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 lineId, IEnumerable lineMessages) { var test = new LineMessagingClient(this.chatToken); var replyMessage = new LinePushMessage() { To = lineId }; 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(LineMessagingAccount lineAccount, LineWebhookContent content) { chatToken = lineAccount.ChatToken; 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(this.chatToken); switch (e.Source.Type) { case WebhookRequestSourceType.User: target = e.Source.UserId; isGroup = false; break; case WebhookRequestSourceType.Group: target = e.Source.GroupId; cellGroup = lineMessagingAccountLogic.GetCellGroup(target); break; case WebhookRequestSourceType.Room: default: target = e.Source.RoomId; return false; break; } try { 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); } } } catch (Exception) { } if (!String.IsNullOrWhiteSpace(replyToken) && text.IndexOf("#") == 0) { text = text.ToLower().Substring(1); LineGroup group = LineGroup.Chris; if (cellGroup == null) { return false; } var autoReply = autoReplyCommands.Where(ar => ar.SupportGroups.Contains(cellGroup.Type) && ar.Enabled(cellGroup, text) ).FirstOrDefault(); if (autoReply != null) { if (autoReply.LineMessage != null) { await ReplyLineMessage(target, autoReply.LineMessage); } else if (autoReply.ReplyJsonMessage != null) { await ReplyJsonMessage(target, autoReply.ReplyJsonMessage); } else { await ReplyTextMessage(replyToken, autoReply.ReplyTextMessage); } return true; } else if (text == "help" || text == "?") { StringBuilder commandText = new StringBuilder(); commandText.AppendLine("NLCC資訊部 - 指令清單"); foreach (var ar in autoReplyCommands.Where(ar => ar.SupportGroups.Contains(cellGroup.Type))) { commandText.AppendLine($"{string.Join(", ", ar.Commands.Select(s => $"#{s}"))} - {ar.Description}"); } commandText.Append($"#help, #? - 顯示指令清單"); await ReplyTextMessage(replyToken, 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(PastoralDomain group, string command) { try { cellGroup = group; if (command.IndexOf("#") == 0) { command = command.ToLower().Substring(1); var autoReply = autoReplyCommands.Where(ar => ar.SupportGroups.Contains(cellGroup.Type) && ar.Enabled(cellGroup, command)).FirstOrDefault(); if (autoReply != null) { this.chatToken = this.lineAccountCrudDAL.First(x => x.Id == group.LineAccountId)?.ChatToken; if (false == string.IsNullOrEmpty(this.chatToken)) { if (autoReply.LineMessage != null) { await ReplyLineMessage(cellGroup.LineGroupId, autoReply.LineMessage); } else { await ReplyTextMessage(cellGroup.LineGroupId, autoReply.ReplyTextMessage); } } 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; } } }