public async Task SendChatEvent(string message, string senderName, string senderWorld, XivChatType chatType, string avatarUrl = "") { // set fields for true chat messages or custom via ipc if (chatType != XivChatTypeExtensions.IpcChatType) { // Special case for outgoing tells, these should be sent under Incoming tells if (chatType == XivChatType.TellOutgoing) { chatType = XivChatType.TellIncoming; } } else { senderWorld = null; } // default avatar url to logo link if empty if (string.IsNullOrEmpty(avatarUrl)) { avatarUrl = Constant.LogoLink; } var applicableChannels = this.plugin.Config.ChannelConfigs.Where(x => x.Value.ChatTypes.Contains(chatType)); if (!applicableChannels.Any()) { return; } message = this.specialChars.TransformToUnicode(message); try { switch (chatType) { case XivChatType.Echo: break; case (XivChatType)61: // npc talk break; case (XivChatType)68: // npc announce break; default: // don't even bother searching if it's gonna be invalid bool doSearch = true; if (string.IsNullOrEmpty(senderName)) { PluginLog.Verbose($"Sender Name was null or empty: {senderName}"); doSearch = false; } if (string.IsNullOrEmpty(senderWorld)) { PluginLog.Verbose($"Sender World was null or empty: {senderWorld}"); doSearch = false; } if (senderName == "Sonar" || !senderName.Contains(" ")) { PluginLog.Verbose($"Sender Name was a plugin or invalid: {senderName}"); doSearch = false; } if (doSearch) { var playerCacheName = $"{senderName}@{senderWorld}"; PluginLog.Verbose($"Searching for {playerCacheName}"); if (CachedResponses.TryGetValue(playerCacheName, out LodestoneCharacter lschar)) { PluginLog.Verbose($"Retrived cached data for {lschar.Name} {lschar.Avatar.ToString()}"); avatarUrl = lschar.Avatar.ToString(); } else { PluginLog.Verbose($"Searching lodestone for {playerCacheName}"); lschar = await lodestoneClient.SearchCharacter(new CharacterSearchQuery() { CharacterName = senderName, World = senderWorld, }).Result.Results.FirstOrDefault(result => result.Name == senderName).GetCharacter(); CachedResponses.TryAdd(playerCacheName, lschar); PluginLog.Verbose($"Adding cached data for {lschar.Name} {lschar.Avatar}"); avatarUrl = lschar.Avatar.ToString(); } // avatarUrl = (await XivApiClient.GetCharacterSearch(senderName, senderWorld)).AvatarUrl; } break; } } catch (Exception ex) { if (string.IsNullOrEmpty(senderName)) { PluginLog.Error($"senderName was null or empty. How did we get this far?"); senderName = "Bridge Error - sendername"; } else { PluginLog.Error(ex, $"Cannot fetch XIVAPI character search for {senderName} on {senderWorld}"); } } var displayName = senderName + (string.IsNullOrEmpty(senderWorld) || string.IsNullOrEmpty(senderName) ? "" : $"@{senderWorld}"); this.plugin.Config.PrefixConfigs.TryGetValue(chatType, out var prefix); var chatTypeText = this.plugin.Config.CustomSlugsConfigs.TryGetValue(chatType, out var x) ? x : chatType.GetSlug(); foreach (var channelConfig in applicableChannels) { var socketChannel = this.socketClient.GetChannel(channelConfig.Key); if (socketChannel == null) { PluginLog.Error("Could not find channel {0} for {1}", channelConfig.Key, chatType); var channelConfigs = this.plugin.Config.ChannelConfigs; channelConfigs.Remove(channelConfig.Key); this.plugin.Config.ChannelConfigs = channelConfigs; PluginLog.Log("Removing channel {0}'s config because it no longer exists or cannot be accessed.", channelConfig.Key); this.plugin.Config.Save(); continue; } var webhookClient = await GetOrCreateWebhookClient(socketChannel); var messageContent = chatType != XivChatTypeExtensions.IpcChatType ? $"{prefix}**[{chatTypeText}]** {message}" : $"{prefix} {message}"; // check for duplicates before sending // straight up copied from the previous bot, but I have no way to test this myself. var recentMessages = (socketChannel as SocketTextChannel).GetCachedMessages(); var recentMsg = recentMessages.FirstOrDefault(msg => msg.Content == messageContent); if (this.plugin.Config.DuplicateCheckMS > 0 && recentMsg != null) { long msgDiff = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - recentMsg.Timestamp.ToUnixTimeMilliseconds(); if (msgDiff < this.plugin.Config.DuplicateCheckMS) { PluginLog.Log($"[IN TESTING]\n DIFF:{msgDiff}ms Skipping duplicate message: {messageContent}"); return; } } await webhookClient.SendMessageAsync( messageContent, username : displayName, avatarUrl : avatarUrl, allowedMentions : new AllowedMentions(AllowedMentionTypes.Roles | AllowedMentionTypes.Users | AllowedMentionTypes.None) ); // the message to a list of recently sent messages. // If someone else sent the same thing at the same time // both will need to be checked and the earlier timestamp kept // while the newer one is removed // refer to https://discord.com/channels/581875019861328007/684745859497590843/791207648619266060 } }
public async Task SendChatEvent(string message, string senderName, string senderWorld, XivChatType chatType) { // Special case for outgoing tells, these should be sent under Incoming tells if (chatType == XivChatType.TellOutgoing) { chatType = XivChatType.TellIncoming; } var applicableChannels = this.plugin.Config.ChannelConfigs.Where(x => x.Value.ChatTypes.Contains(chatType)); if (!applicableChannels.Any()) { return; } message = this.specialChars.TransformToUnicode(message); var avatarUrl = Constant.LogoLink; try { switch (chatType) { case XivChatType.Echo: break; case (XivChatType)61: // npc talk break; case (XivChatType)68: // npc announce break; default: avatarUrl = (await XivApiClient.GetCharacterSearch(senderName, senderWorld)).AvatarUrl; break; } } catch (Exception ex) { PluginLog.Error(ex, $"Cannot fetch XIVAPI character search for {senderName} on {senderWorld}"); } var displayName = senderName + (string.IsNullOrEmpty(senderWorld) || string.IsNullOrEmpty(senderName) ? "" : $"@{senderWorld}"); this.plugin.Config.PrefixConfigs.TryGetValue(chatType, out var prefix); foreach (var channelConfig in applicableChannels) { var socketChannel = this.socketClient.GetChannel(channelConfig.Key); if (socketChannel == null) { PluginLog.Error("Could not find channel {0} for {1}", channelConfig.Key, chatType); continue; } var webhookClient = await GetOrCreateWebhookClient(socketChannel); var messageContent = $"{prefix}**[{chatType.GetSlug()}]** {message}"; // check for duplicates before sending // straight up copied from the previous bot, but I have no way to test this myself. var recentMessages = (socketChannel as SocketTextChannel).GetCachedMessages(); var recentMsg = recentMessages.FirstOrDefault(msg => msg.Content == messageContent); if (this.plugin.Config.DuplicateCheckMS > 0 && recentMsg != null) { long msgDiff = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - recentMsg.Timestamp.ToUnixTimeMilliseconds(); if (msgDiff < this.plugin.Config.DuplicateCheckMS) { PluginLog.Log($"[IN TESTING]\n DIFF:{msgDiff}ms Skipping duplicate message: {messageContent}"); return; } } await webhookClient.SendMessageAsync(messageContent, username : displayName, avatarUrl : avatarUrl); // the message to a list of recently sent messages. // If someone else sent the same thing at the same time // both will need to be checked and the earlier timestamp kept // while the newer one is removed // refer to https://discord.com/channels/581875019861328007/684745859497590843/791207648619266060 } }