Skip to content

Instantly share code, notes, and snippets.

@Mijago
Last active July 31, 2018 10:11
Show Gist options
  • Save Mijago/2069dd4d565c7d6259fb60181da2959a to your computer and use it in GitHub Desktop.
Save Mijago/2069dd4d565c7d6259fb60181da2959a to your computer and use it in GitHub Desktop.
Lua interface for discord webhooks. It needs no external libraries, but sends the webhook using os.execute and curl.
DiscordWebhook = {}
DiscordWebhook_metatable = { __index = DiscordWebhook }
function DiscordWebhook:new(webhook)
return setmetatable({
webhook = webhook,
enableTTS = false,
content = nil,
username = nil,
avatar_url = nil,
embeds = {}
}, DiscordWebhook_metatable)
end
function DiscordWebhook:enableTextToSpeech(newState)
self.enableTTS = newState;
return self;
end
function DiscordWebhook:withContent(newContent)
self.content = newContent:gsub('"', '\\"');
return self;
end
function DiscordWebhook:fromUsername(newName)
self.username = newName:gsub('"', '\\"');
return self;
end
function DiscordWebhook:withAvatarUrl(newUrl)
self.avatar_url = newUrl:gsub('"', '\\"');
return self;
end
function DiscordWebhook:withEmbed(newEmbed)
table.insert(self.embeds, newEmbed)
return self;
end
function DiscordWebhook:send()
-- Build the complete string and send it
local json = "{"
json = json .. string.format('"tts":%s,', self.enableTTS and "true" or "false")
if self.content ~= nil then
json = json .. string.format('"content":"%s",', self.content)
end
if self.username ~= nil then
json = json .. string.format('"username":"%s",', self.username)
end
if self.avatar_url ~= nil then
json = json .. string.format('"avatar_url":"%s",', self.avatar_url)
end
-- if table.getn(self.embeds) > 0 then -- Lua < 5.2
if #self.embeds > 0 then -- Lua >= 5.2
json = json .. '"embeds": ['
for key, value in ipairs(self.embeds) do
json = json .. value
-- if key < table.getn(self.embeds) then -- Lua < 5.2
if key < #self.embeds then -- Lua >= 5.2
json = json .. ","
end
end
json = json .. ']'
end
if json:sub(-1) == "," then
json = json:sub(1, -2)
end
json = json .. "}"
if json == '{"tts":false}' then
return false
else
local callStr = string.format('curl -H "Content-Type: application/json" -X POST -d \'%s\' \'%s\'', json, self.webhook)
-- print(callStr)
os.execute(callStr)
return true
end
end
DiscordEmbed = {}
DiscordEmbed_metatable = { __index = DiscordEmbed }
function DiscordEmbed:new(webhook)
return setmetatable({
title = nil,
description = nil,
color = nil,
url = nil,
image_url = nil,
thumbnail_url = nil,
fields = {},
footer = {
text = nil,
icon_url = nil
}
}, DiscordEmbed_metatable)
end
function DiscordEmbed:withTitle(newTitle)
self.title = newTitle:gsub('"', '\\"');
return self;
end
function DiscordEmbed:withDescription(newDescription)
self.description = newDescription:gsub('"', '\\"');
return self;
end
function DiscordEmbed:withColor(newColor)
self.color = newColor;
return self;
end
function DiscordEmbed:withUrl(newUrl)
self.url = newUrl:gsub('"', '\\"');
return self;
end
function DiscordEmbed:withImage(newUrl)
self.image_url = newUrl:gsub('"', '\\"');
return self;
end
function DiscordEmbed:withThumbnail(newUrl)
self.thumbnail_url = newUrl:gsub('"', '\\"');
return self;
end
function DiscordEmbed:withField(title, value)
table.insert(self.fields, {title = title:gsub('"', '\\"'), value = value:gsub('"', '\\"'), inline = false})
return self;
end
function DiscordEmbed:withFieldInline(title, value)
table.insert(self.fields, {title = title:gsub('"', '\\"'), value = value:gsub('"', '\\"'), inline = true})
return self;
end
function DiscordEmbed:withFooterText(newText)
self.footer.text = newText:gsub('"', '\\"');
return self;
end
function DiscordEmbed:withFooterIcon(newUrl)
self.footer.icon_url = newUrl:gsub('"', '\\"');
return self;
end
function DiscordEmbed:build()
local json = '{'
if self.title ~= nil then
json = json .. string.format('"title":"%s",', self.title)
end
if self.description ~= nil then
json = json .. string.format('"description":"%s",', self.description)
end
if self.url ~= nil then
json = json .. string.format('"url":"%s",', self.url)
end
if self.color ~= nil then
json = json .. string.format('"color":"%s",', self.color)
end
if self.image_url ~= nil then
json = json .. string.format('"image":{"url":"%s"},', self.image_url)
end
if self.thumbnail_url ~= nil then
json = json .. string.format('"thumbnail":{"url":"%s"},', self.thumbnail_url)
end
if (self.footer.text ~= nil) then
json = json .. '"footer": {'
if (self.footer.icon_url ~= nil) then
json = json .. string.format('"icon_url":"%s",', self.footer.icon_url)
end
if (self.footer.text ~= nil) then
json = json .. string.format('"text":"%s"', self.footer.text)
end
json = json .. '},'
end
-- if table.getn(self.fields) > 0 then -- Lua < 5.2
if #self.fields > 0 then -- Lua >= 5.2
json = json .. '"fields": ['
for key, value in ipairs(self.fields) do
json = json .. string.format(
'{"name":"%s", "value":"%s", "inline":%s}',
value.title,
value.value,
value.inline and "true" or "false"
)
--- if key < table.getn(self.fields) then -- Lua < 5.2
if key < #self.fields then -- Lua >= 5.2
json = json .. ","
end
end
json = json .. ']'
end
if json:sub(-1) == "," then
json = json:sub(1, -2)
end
json = json .. '}'
return json
end
-- Send a simple text message.
DiscordWebhook
:new("https://discordapp.com/api/webhooks/yourwebhook/xxx-yyy-zzz")
:withContent("Hello World!")
:send()
-- Send TTS-message with username and avatar image
DiscordWebhook
:new("https://discordapp.com/api/webhooks/yourwebhook/xxx-yyy-zzz")
:fromUsername("TestUser")
:withContent("Hello World!")
:withAvatarUrl("https://www.chip.de/ii/7/5/7/9/6/5/4/f783c7a2253da84f.jpg")
:enableTextToSpeech(true)
:send()
-- Add one or more Embeds!
DiscordWebhook
:new("https://discordapp.com/api/webhooks/yourwebhook/xxx-yyy-zzz")
:fromUsername("TestUser")
:withContent("Hello World!")
:withAvatarUrl("https://www.chip.de/ii/7/5/7/9/6/5/4/f783c7a2253da84f.jpg")
:withEmbed(DiscordEmbed:new() -- A very simple embed
:withTitle("Embed Test")
:withDescription("Gread stuff!!")
:build())
:withEmbed(DiscordEmbed:new() -- And you can add multiple embeds!
:withTitle("Embed Test")
:withDescription("Gread stuff!!")
:withUrl("https://google.com/")
:withColor(1337331)
:withField("Field A", "Text A")
:withFieldInline("Field B", "Text B") -- Yes, inline fields are also working!
:withFieldInline("Field C", "Text C")
:withField("Field D", "Text D")
:withImage("https://www.gstatic.com/images/branding/product/2x/photos_96dp.png")
:withThumbnail("https://www.gstatic.com/images/branding/product/2x/photos_96dp.png")
:withFooterText("Footer Text!")
:withFooterIcon("https://www.gstatic.com/images/branding/product/2x/photos_96dp.png")
:build())
:send()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment