/// @ingroup webhook /// @file nwnx_webhook_rch.nss /// @brief Create richer webhook messages suitable for Discord #include "nwnx_webhook" /// @ingroup webhook /// @brief For more information on these fields see https://birdie0.github.io/discord-webhooks-guide/ /// @note URL fields may require NWNX_Util_EncodeStringForURL(). struct NWNX_WebHook_Message { string sUsername; ///< https://birdie0.github.io/discord-webhooks-guide/structure/username.html string sText; ///< https://birdie0.github.io/discord-webhooks-guide/structure/content.html string sAvatarURL; ///< https://birdie0.github.io/discord-webhooks-guide/structure/avatar_url.html string sColor; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/color.html string sAuthorName; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/author.html string sAuthorURL; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/author.html string sAuthorIconURL; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/author.html string sTitle; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/title.html string sURL; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/url.html string sDescription; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/description.html string sThumbnailURL; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/thumbnail.html string sImageURL; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/image.html string sFooterText; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/footer.html string sFooterURL; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/footer.html int iTimestamp; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/timestamp.html string sField1Name; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField1Value; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html int iField1Inline; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField2Name; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField2Value; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html int iField2Inline; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField3Name; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField3Value; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html int iField3Inline; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField4Name; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField4Value; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html int iField4Inline; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField5Name; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField5Value; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html int iField5Inline; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField6Name; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField6Value; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html int iField6Inline; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField7Name; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField7Value; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html int iField7Inline; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField8Name; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField8Value; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html int iField8Inline; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField9Name; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField9Value; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html int iField9Inline; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField10Name; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html string sField10Value; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html int iField10Inline; ///< https://birdie0.github.io/discord-webhooks-guide/structure/embed/fields.html }; /// @private We don't need this to be a part of the docs. /// @brief Helper function to convert 0 or 1 to false or true. /// @param iBool The integer representation of the boolean. /// @return The string representation (true or false) of the boolean. string IntToBoolString(int iBool); /// @ingroup webhook /// @brief Builds and sends a rich webhook message based on the constructed NWNX_WebHook_Message. /// @param host The web server to send the hook. /// @param path The path to the hook. /// @param stMessage A constructed NWNX_Webhook_Message. /// @param mrkdwn Set to false if you do not wish your message's markdown be parsed. /// @warning Your path must end with /slack if using a Discord webhook. string NWNX_WebHook_BuildMessageForWebHook(string host, string path, struct NWNX_WebHook_Message stMessage, int mrkdwn = 1); string IntToBoolString(int iBool) { return iBool == 0 ? "false" : "true"; } string NWNX_WebHook_BuildMessageForWebHook(string host, string path, struct NWNX_WebHook_Message stMessage, int mrkdwn = 1) { if (host == "discordapp.com" && GetStringRight(path, 6) != "/slack") { PrintString("Discord WebHook specified but path does not end with /slack"); return ""; } // Open JSON string message = "{"; string sMainText = ""; // The only way to turn off markdown for discord is to surround the text in backticks if (stMessage.sText != "") { if (host == "discordapp.com" && !mrkdwn) sMainText = "```text\\n" + stMessage.sText + "```"; else sMainText = stMessage.sText; } message = message + "\"text\": \"" + sMainText + "\""; // Slack will turn off markdown if (host != "discordapp.com" && !mrkdwn) message = message + ",\"mrkdwn\": false"; // Set the user attributes for the poster if (stMessage.sUsername != "") message = message + ",\"username\": \"" + stMessage.sUsername + "\""; if (stMessage.sAvatarURL != "") message = message + ",\"icon_url\": \"" + stMessage.sAvatarURL + "\""; // We need to construct an attachment (embed) object if (stMessage.sAuthorName != "" || stMessage.sAuthorURL != "" || stMessage.sAuthorIconURL != "" || stMessage.sTitle != "" || stMessage.sURL != "" || stMessage.sDescription != "" || stMessage.sFooterText != "" || stMessage.sFooterURL != "" || stMessage.iTimestamp > 0 || stMessage.sColor != "" || stMessage.sThumbnailURL != "" || stMessage.sImageURL != "" || stMessage.sField1Name != "") { message = message + ",\"attachments\": [{\"author_name\": \"" + stMessage.sAuthorName + "\",\"author_link\": \"" + stMessage.sAuthorURL + "\",\"author_icon\": \"" + stMessage.sAuthorIconURL + "\",\"title\": \"" + stMessage.sTitle + "\",\"title_link\": \"" + stMessage.sURL + "\",\"text\": \"" + stMessage.sDescription + "\",\"footer\": \"" + stMessage.sFooterText + "\",\"footer_icon\": \"" + stMessage.sFooterURL + "\",\"color\": \"" + stMessage.sColor + "\",\"thumb_url\": \"" + stMessage.sThumbnailURL + "\",\"image_url\": \"" + stMessage.sImageURL + "\""; // Dont post an empty timestamp if (stMessage.iTimestamp > 0) message = message + ",\"ts\": \"" + IntToString(stMessage.iTimestamp) + "\""; // Fields to handle if (stMessage.sField1Name != "") { message = message + ",\"fields\": ["; message = message + "{\"title\": \"" + stMessage.sField1Name + "\",\"value\": \"" + stMessage.sField1Value + "\",\"short\": " + IntToBoolString(stMessage.iField1Inline) + "}"; if (stMessage.sField2Name != "") message = message + ",{\"title\": \"" + stMessage.sField2Name + "\",\"value\": \"" + stMessage.sField2Value + "\",\"short\": " + IntToBoolString(stMessage.iField2Inline) + "}"; if (stMessage.sField3Name != "") message = message + ",{\"title\": \"" + stMessage.sField3Name + "\",\"value\": \"" + stMessage.sField3Value + "\",\"short\": " + IntToBoolString(stMessage.iField3Inline) + "}"; if (stMessage.sField4Name != "") message = message + ",{\"title\": \"" + stMessage.sField4Name + "\",\"value\": \"" + stMessage.sField4Value + "\",\"short\": " + IntToBoolString(stMessage.iField4Inline) + "}"; if (stMessage.sField5Name != "") message = message + ",{\"title\": \"" + stMessage.sField5Name + "\",\"value\": \"" + stMessage.sField5Value + "\",\"short\": " + IntToBoolString(stMessage.iField5Inline) + "}"; if (stMessage.sField6Name != "") message = message + ",{\"title\": \"" + stMessage.sField6Name + "\",\"value\": \"" + stMessage.sField6Value + "\",\"short\": " + IntToBoolString(stMessage.iField6Inline) + "}"; if (stMessage.sField7Name != "") message = message + ",{\"title\": \"" + stMessage.sField7Name + "\",\"value\": \"" + stMessage.sField7Value + "\",\"short\": " + IntToBoolString(stMessage.iField7Inline) + "}"; if (stMessage.sField8Name != "") message = message + ",{\"title\": \"" + stMessage.sField8Name + "\",\"value\": \"" + stMessage.sField8Value + "\",\"short\": " + IntToBoolString(stMessage.iField8Inline) + "}"; if (stMessage.sField9Name != "") message = message + ",{\"title\": \"" + stMessage.sField9Name + "\",\"value\": \"" + stMessage.sField9Value + "\",\"short\": " + IntToBoolString(stMessage.iField9Inline) + "}"; if (stMessage.sField10Name != "") message = message + ",{\"title\": \"" + stMessage.sField10Name + "\",\"value\": \"" + stMessage.sField10Value + "\",\"short\": " + IntToBoolString(stMessage.iField10Inline) + "}"; // Close fields array message = message + "]"; } // Close attachments array message = message + "}]"; } // Close JSON message = message + "}"; return message; }