Implementation of DiscordMessage.Content humanization (attempt number 2)
Created by: Evengard
Summary
This is the implementation of the convertation to a human-readable format of DiscordMessage snowflake tags (such as mentions and emojis). Resolves #935 (closed). This is a second (and probably final) attempt, in a hope that this way of implementing stuff would be more appropriate for the project.
Details
For some cases, a human-readable version of the message received by a bot may be useful - for example, to relay it somewhere else, eg on a website. This pull request implements the convertation to a human-readable format the most cryptic part of a bot-received message - the mentions and emojis. Now, the way I did the first PR were probably not right, sorry - I didn't knew that. I genuinely try to do it right, I'm just new to this project.
Changes proposed
- The implementation changed completely from extending Discord objects to a self contained Utility function doing everything inside itself. Only small changes are made to DiscordEmoji.EmojiUtils.cs by making the arrays internal instead of private.
- Added the
Utilities.HumanizeContentAsync
method for converting the snowflake tags into human-readable representation - Because the method of converting emojis may depend on circumstances,
HumanizeContentAsync
accepts a second parameter ofFunc<DiscordEmoji, Task<string>>
to allow specifying a method of formatting theese - The default is to skip all non-unicode emojis, and output the unicode emojis in unicode format
- Sometimes the guild emoji used in a message can't be retrieved using default Discord API because the bot doesn't know about the server from which the emote originate (eg a Nitro user posted an emoji from another server). We still have enough information to construct a dummy DiscordEmoji object which could be used for retrieving the URL of the emote, for example. We explicitely mark it as IsAvailable = false to avoid it's usage elsewhere
- Along the way fixed the Formatter.Strip to account for animated emojis as well
Notes
The HumanizeContentAsync
method is async only because of the message.Channel.Guild.GetMemberAsync
call, which is in turn a fallback for the case if if (user is DiscordMember member)
fails. Now, if for guild messages this cast is always true, I can rework it to make it non-async.