C#:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace Oxide.Plugins
{
[Info("Discord Message API", "bsdinis", "0.0.9")]
class DiscordMessageAPI : CovalencePlugin
{
void SendDiscordMessage(string webhook, string username, string avatarUrl, string content, bool tts, List<List<object>> embeds)
{
if (string.IsNullOrWhiteSpace(webhook) || !IsValidUrl(webhook, out webhook))
{
PrintError("\nThe first argument (webhook) is not a valid URL. Unable to send Discord message!");
return;
}
if (string.IsNullOrWhiteSpace(username))
{
PrintError("\nThe second argument (username) must not be empty. Unable to send Discord message!");
return;
}
if (string.IsNullOrWhiteSpace(content) && (embeds == null || embeds.Count < 1))
{
PrintError("\nThe message must contain content or an embed. Unable to send an empty Discord message!");
return;
}
int characters = 0;
bool limit = false;
if (avatarUrl == null)
{
avatarUrl = string.Empty;
}
if (content == null)
{
content = string.Empty;
}
if (username.Length > 80)
{
PrintWarning("\nDiscord limits the amount of characters in message's username to 80. Only the first 80 characters from the message's username will be added to the message.");
}
if (!IsValidUrl(avatarUrl, out avatarUrl))
{
PrintWarning("\nThe message's avatar URL is not a valid URL and will not be added to the message.");
}
if (content.Length > 2000)
{
PrintWarning("\nDiscord limits the amount of characters in message's content to 2000. Only the first 2000 characters from the message's content will be added to the message.");
}
DiscordMessage message = new DiscordMessage
{
username = Concatenate(username, 80),
avatar_url = avatarUrl,
content = Concatenate(content, 2000),
tts = tts,
embeds = new List<DiscordMessage.Embed>()
};
if (embeds != null)
{
for (int i = 0; i < embeds.Count; i++)
{
List<object> embedList = embeds[i] as List<object>;
if (embedList == null)
{
PrintError($"\nUnable to read Embed[{i}].");
continue;
}
if (embedList.Count < 12)
{
PrintError($"\nEmbed[{i}] has less than 12 objects and will not be added to the message.");
continue;
}
string authorName = embedList[0] as string;
if (authorName == null)
{
PrintError($"\nThe first object (author name) from Embed[{i}] is not a string and the whole embed will not be added to the message.");
continue;
}
string authorUrl = embedList[1] as string;
if (authorUrl == null)
{
PrintError($"\nThe second object (author URL) from Embed[{i}] is not a string and the whole embed will not be added to the message.");
continue;
}
string authorIconUrl = embedList[2] as string;
if (authorIconUrl == null)
{
PrintError($"\nThe third object (author icon URL) from Embed[{i}] is not a string and the whole embed will not be added to the message.");
continue;
}
string embedTitle = embedList[3] as string;
if (embedTitle == null)
{
PrintError($"\nThe fourth object (embed title) from Embed[{i}] is not a string and the whole embed will not be added to the message.");
continue;
}
string embedURL = embedList[4] as string;
if (embedURL == null)
{
PrintError($"\nThe fifth object (URL) from Embed[{i}] is not a string and the whole embed will not be added to the message.");
continue;
}
string embedDescription = embedList[5] as string;
if (embedDescription == null)
{
PrintError($"\nThe sixth object (description) from Embed[{i}] is not a string and the whole embed will not be added to the message.");
continue;
}
if (!(embedList[6] is int))
{
PrintError($"\nThe seventh object (color) from Embed[{i}] is not an int value and the whole embed will not be added to the message.");
continue;
}
string thumbnailUrl = embedList[8] as string;
if (thumbnailUrl == null)
{
PrintError($"\nThe nineth object (thumbnail URL) from Embed[{i}] is not a string and the whole embed will not be added to the message.");
continue;
}
string imageUrl = embedList[9] as string;
if (imageUrl == null)
{
PrintError($"\nThe tenth object (image URL) from Embed[{i}] is not a string and the whole embed will not be added to the message.");
continue;
}
string footerText = embedList[10] as string;
if (footerText == null)
{
PrintError($"\nThe eleventh object (footer text) from Embed[{i}] is not a string and the whole embed will not be added to the message.");
continue;
}
string footerIconUrl = embedList[11] as string;
if (footerIconUrl == null)
{
PrintError($"\nThe twelveth object (footer icon URL) from Embed[{i}] is not a string and the whole embed will not be added to the message.");
continue;
}
DiscordMessage.Embed embed = new DiscordMessage.Embed
{
author = new DiscordMessage.Embed.Author
{
name = authorName,
url = authorUrl,
icon_url = authorIconUrl
},
title = embedTitle,
url = embedURL,
description = embedDescription,
color = (int)embedList[6],
fields = new List<DiscordMessage.Embed.Field>(),
thumbnail = new DiscordMessage.Embed.ImageURL
{
url = imageUrl
},
image = new DiscordMessage.Embed.ImageURL
{
url = thumbnailUrl
},
footer = new DiscordMessage.Embed.Footer
{
text = footerText,
icon_url = footerIconUrl
}
};
List<List<object>> fields = embedList[7] as List<List<object>>;
if (fields != null)
{
for (int ii = 0; ii < fields.Count; ii++)
{
List<object> fieldList = fields[ii] as List<object>;
if (fieldList == null)
{
PrintError($"\nUnable to read Field[{ii}] from Embed[{i}].");
continue;
}
if (fieldList.Count < 3)
{
PrintError($"\nField[{ii}] from Embed[{i}] has less than 3 objects and will not be added to the message.");
continue;
}
string fieldName = fieldList[0] as string;
if (fieldName == null)
{
PrintError($"\nThe first object (field name) from Field[{ii}] from Embed[{i}] is not a string and the whole field will not be added to the message.");
continue;
}
string fieldValue = fieldList[1] as string;
if (fieldValue == null)
{
PrintError($"\nThe second object (field value) from Field[{ii}] from Embed[{i}] is not a string and the whole field will not be added to the message.");
continue;
}
if (!(fieldList[2] is bool))
{
PrintError($"\nThe third object (field inline) from Field[{ii}] from Embed[{i}] is not a bool and the whole field will not be added to the message.");
continue;
}
if (fieldName.Length > 256)
{
PrintWarning($"\nDiscord limits the amount of characters in embed's field's name to 256. Only the first 256 characters from the name of Field[{ii}] from Embed[{i}] will be added to the message.");
}
fieldName = Concatenate(fieldName, 256);
if (fieldValue.Length > 1024)
{
PrintWarning($"\nDiscord limits the amount of characters in embed's field's value to 1024. Only the first 1024 characters from the value of Field[{ii}] from Embed[{i}] will be added to the message.");
}
fieldValue = Concatenate(fieldValue, 1024);
if ((characters + fieldName.Length + fieldValue.Length) > 6000)
{
PrintError($"\nThe message would exceed the 6000 characters limit if Field[{ii}] from Embed[{i}] is added to the message. No more fields or embeds will be added to the message.");
limit = true;
break;
}
characters += fieldName.Length;
characters += fieldValue.Length;
DiscordMessage.Embed.Field field = new DiscordMessage.Embed.Field
{
name = fieldName,
value = fieldValue,
inline = (bool)fieldList[2]
};
embed.fields.Add(field);
if (ii < 24)
{
continue;
}
limit = true;
PrintWarning($"\nDiscord limits the amount of fields to 25 per embed. Only the first 25 fields from Embed[{i}] will be added to the message.");
break;
}
}
DiscordMessage.Embed.Author author = embed.author;
if (author.name.Length > 256)
{
PrintWarning($"\nDiscord limits the amount of characters in embed's author name to 256. Only the first 256 characters from the author name of Embed[{i}] will be added to the message.");
}
author.name = Concatenate(author.name, 256);
characters += author.name.Length;
if (!IsValidUrl(author.url, out author.url))
{
PrintWarning($"\nThe author URL from Embed[{i}] is not a valid URL and will not be added to the message.");
}
if (!IsValidUrl(author.icon_url, out author.icon_url))
{
PrintWarning($"\nThe author icon URL from Embed[{i}] is not a valid URL and will not be added to the message.");
}
if (embed.title.Length > 256)
{
PrintWarning($"\nDiscord limits the amount of characters in embed's title to 256. Only the first 256 characters from the title of Embed[{i}] will be added to the message.");
}
embed.title = Concatenate(embed.title, 256);
characters += embed.title.Length;
if (!IsValidUrl(embed.url, out embed.url))
{
PrintWarning($"\nThe URL from Embed[{i}] is not a valid URL and will not be added to the message.");
}
if (embed.description.Length > 4096)
{
PrintWarning($"\nDiscord limits the amount of characters in embed's description to 4096. Only the first 4096 characters from the description of Embed[{i}] will be added to the message.");
}
embed.description = Concatenate(embed.description, 4096);
characters += embed.description.Length;
if (!IsValidUrl(embed.thumbnail.url, out embed.thumbnail.url))
{
PrintWarning($"\nThe thumbnail image URL from Embed[{i}] is not a valid URL and will not be added to the message.");
}
if (!IsValidUrl(embed.image.url, out embed.image.url))
{
PrintWarning($"\nThe image URL from Embed[{i}] is not a valid URL and will not be added to the message.");
}
DiscordMessage.Embed.Footer footer = embed.footer;
if (footer.text.Length > 2048)
{
PrintWarning($"\nDiscord limits the amount of characters in embed's footer text to 2048. Only the first 2048 characters from the footer text of Embed[{i}] will be added to the message.");
}
footer.text = Concatenate(footer.text, 2048);
characters += footer.text.Length;
if (characters > 6000)
{
PrintError($"\nThe message would exceed the 6000 characters limit if Embed[{i}] is added to the message. No more embeds will be added to the message.");
limit = true;
break;
}
if (!IsValidUrl(footer.icon_url, out footer.icon_url))
{
PrintWarning($"\nThe footer icon URL from Embed[{i}] is not a valid URL and will not be added to the message.");
}
message.embeds.Add(embed);
if (i < 9)
{
continue;
}
limit = true;
PrintWarning("\nDiscord limits the amount of embeds to 10 per message. Only the first 10 embeds will be added to the message.");
break;
}
}
webrequest.Enqueue(
webhook,
JsonConvert.SerializeObject(message),
(c, r) =>
{
if (c == 204)
{
PrintWarning("Discord message " + (limit ? "embeds PARTIALLY sent to avoid exceeding the 6000 characters limit." : "successfully sent."));
}
else
{
PrintError($"Code {c}\n{JsonConvert.DeserializeObject(r)}");
}
},
this,
Core.Libraries.RequestMethod.POST,
headers
);
}
static readonly Dictionary<string, string> headers = new Dictionary<string, string>
{
["Content-Type"] = "application/json"
};
string Concatenate(string s, int i)
{
if (string.IsNullOrEmpty(s) || s.Length <= i)
{
return s;
}
return s.Substring(0, i);
}
bool IsValidUrl(string s, out string url)
{
url = string.Empty;
if (string.IsNullOrWhiteSpace(s))
{
return true;
}
Uri uri;
if (!Uri.TryCreate(s, UriKind.Absolute, out uri) || !(uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
{
return false;
}
url = s;
return true;
}
class DiscordMessage
{
public string username;
public string avatar_url;
public string content;
public bool tts;
public List<Embed> embeds;
public class Embed
{
public Author author;
public string title;
public string url;
public string description;
public int color;
public List<Field> fields;
public ImageURL thumbnail;
public ImageURL image;
public Footer footer;
public class Author
{
public string name;
public string url;
public string icon_url;
}
public class Field
{
public string name;
public string value;
public bool inline;
}
public class ImageURL
{
public string url;
}
public class Footer
{
public string text;
public string icon_url;
}
}
}
}
}