Discord webhook not sending

This is the second time I’m writing about this script, oof

I’m trying to have a custom command for Adonis post an embed in a Discord channel. I reviewed DevForum posts on how to make webhooks send embeds and formatted accordingly, but the embed just won’t go through.

This is the code for the command:

service = nil
TrelloAPI = require(game.ServerScriptService.TrelloAPI)
board = TrelloAPI:GetBoardID("Adonis Board")
permlist = TrelloAPI:GetListID("Bans",board)
templist = TrelloAPI:GetListID("Bans (Temporary)",board)
servlist = TrelloAPI:GetListID("Bans (Server)",board)
local http = game:GetService("HttpService")

-- Converts time to ISO8601
function getISO8601Time(epochTime)
	local currentTime = os.date("!*t",epochTime)

	local hour = currentTime.hour
	local minute = currentTime.min
	local second = currentTime.sec

	local day = currentTime.day
	local month = currentTime.month
	local year = currentTime.year

	-- ISO8601 support
	if hour < 10 then
		hour = 0 .. hour
	end
	if minute < 10 then
		minute = 0 .. minute
	end
	if second < 10 then
		second = 0 .. second
	end
	if day < 10 then
		day = 0 .. day
	end
	if month < 10 then
		month = 0 .. month
	end
	if year < 10 then
		year = 0 .. year
	end

	return ("%s-%s-%sT%s:%s:%sZ"):format(year, month, day, hour, minute, second)
end

local function banEmbed(moderator,bannedPlayer,banlength,banreason) --length is a string
	local function NewJSON(username,userId,mod,length,reason,content)
		local obj = {
			["content"] = content,
			["embeds"] = {{
				["title"] = "Player Banned",
				["description"] = "["..username.."](https://www.roblox.com/users/"..userId.."/profile)".." has been banned.",
				["type"] = "rich",
				["color"] = 15066830,
				["timestamp"] = getISO8601Time(),
				["footer"] = {
					["icon_url"] = "",
					["text"] = "Ban Logs",
				},
				["fields"] = {
					{
						["name"] = "__Moderator__",
						["value"] = mod,
						["inline"] = true
					},
					{
						["name"] = "__Length__",
						["value"] = length,
						["inline"] = true
					},
					{
						["name"] = "__Reason__",
						["value"] = reason,
						["inline"] = true
					}
				}
			}},
			["avatar_url"] = "https://cdn.discordapp.com/avatars/249399670638379008/3755914fea3f6ec0ebdc4c7048d7b636.png"
		}
		return http:JSONEncode(obj)
	end
	
	local msgObj = NewJSON(bannedPlayer.Name,bannedPlayer.UserId,moderator,banlength,banreason,bannedPlayer.Name.." banned by "..moderator.Name..".")
	http:PostAsync(standardTargetUrl, msgObj)
end


return function()
	server.Commands.TrelloBan = {
		Prefix = server.Settings.Prefix;	-- Prefix to use for command
		Commands = {"trelloban"};	-- Commands
		Args = {"player","length", "reason"};	-- Command arguments
		Description = "The second argument (length) is in days. The third argument (reason) can be 'server', 'perm', or a length in days from 1 to 14.";	-- Command Description
		Hidden = false; -- Is it hidden from the command list?
		Fun = false;	-- Is it fun?
		AdminLevel = "Moderators";	    -- Admin level; If using settings.CustomRanks set this to the custom rank name (eg. "Baristas")
		Function = function(plr,args)    -- Function to run for command
			for i,v in next,service.GetPlayers(plr,args[1],true,false,true) do
				player = args[1]
				length = args[2]
				reason = args[3]
				if tostring(length) == "perm" then
					local level = server.Admin.GetLevel(plr)
					if level >= 3 then
						server.Admin.AddBan(v, true)
						server.Functions.Hint("Permanently banned "..v.Name,{plr})
						local desc = tostring("Banned by "..plr.Name.." for "..reason.." permanently.")
						TrelloAPI:AddCard(v.Name..":"..v.UserId,desc,permlist)
						banEmbed(plr,v,"Permanent",reason)
					else
						server.Remote.MakeGui(plr,'Output',{Title = ''; Message = 'You are not allowed to run this command.'; Color = Color3.new(1,0,0)})
					end
				elseif tostring(length) == "server" then
					local level = server.Admin.GetLevel(plr)
					if level > server.Admin.GetLevel(v) then 
						server.Admin.AddBan(v)
						server.Functions.Hint("Server banned "..v.Name,{plr})
						local desc = tostring("Server banned by "..plr.Name.." for "..reason..".")
						TrelloAPI:AddCard(v.Name..":"..v.UserId,desc,servlist)
						banEmbed(plr,v,"Server",reason)
					end
				elseif tonumber(length) <= 14 then
					local level = server.Admin.GetLevel(plr)
						if level > server.Admin.GetLevel(v) then 
							local time = ((tonumber(length)*60)*60)*24
							assert(args[1] and args[2], "Argument missing or nil")
							for i,v in next,service.GetPlayers(plr, args[1], false, false, true) do
								endTime = getISO8601Time(tonumber(os.time())+tonumber(time))
								local timebans = server.Core.Variables.TimeBans
								local data = {
									Name = v.Name;
									UserId = v.UserId;
									EndTime = endTime;
								}
								
								table.insert(timebans, data)
								server.Core.DoSave({
									Type = "TableAdd";
									Table = "TimeBans";
									Parent = "Variables";
									Value = data;
								})
								local desc = tostring("Banned by "..plr.Name.." for "..reason.." for "..tonumber(length).." days until "..endTime..".")
								TrelloAPI:AddCard(v.Name..":"..v.UserId,desc,templist)
								v:Kick("Banned until "..endTime)
								server.Functions.Hint("Banned "..v.Name.." for "..time,{plr})
							end
							banEmbed(plr,v,length.." days",reason)
						end
					else
					server.Functions.Hint("Your ban length was invalid. Please try again with 'perm', 'server', or a length (in days) between 1 and 14.",{plr})
				end
			end
		end
	}
end

It bothers me that I’m not home and can’t provide full help but try googling the Discord embed visualizer and customize it to how you would like it to appear than copy over the data to your script and I’m not clear on this part but maybe try using a proxy to post the data I havent heard anything about Discord unblocking roblox from posting but I may be wrong, but once I’m home and the problem hasn’t been resolved I’ll be glad to help. :smile:

I did use the Embed Visualizer, and followed the format (converting to the format listed in a previous article). Previous Discord webhooks (that I currently use) have worked without a proxy.

Hmm, Are you sure that script that executes when the command is called? Try putting prints in spots and see what executes and what doesn’t and I’ll try to work from there.

After testing the script with prints in place, the following results appear:
Permanent Ban Section
Errors when reaching the banEmbed function.
Server Ban Section
Errors when reaching the banEmbed function.
Time Ban Section
Errors when reaching the banEmbed function.

As such, I think the error is the banEmbed function. (Nothing else is erroring.)

I don’t know why but I’ve never seen that error in roblox, but anyway I’m pretty sure this may not or may make a difference but move the newjson function out or remove it and add it to the ban embed function.

I ran print() tests on the banEmbed function. Apparently, everything’s well and good up until http:PostAsync(standardTargetUrl, msgObj), where the print after that does not show. Any insight into why that might be happening?
Note: HTTP requests are enabled!

Oh, for me on my discord posts I usually put a pcall and I print what comes out.

Not sure if that will help you in this case but maybe try doing that.

After using some code of Kampfkarren’s to wrap PostAsync in a pcall, I get the following message repeatedly: HTTP 400. I’ve even tried regenerating the webhook link - I’m not sure what exactly is happening, but it looks like there’s a client-side (being Roblox-side, as opposed to Discord) error in how I’m using PostAsync.

As a web developer HTTP 400 means bad request so try generating a new web hook and see if that resolves the issue if not it maybe a server issue.

I did try regenerating the webhook link - even with that, the request is returned to me with an HTTP 400. Also, it can’t be that the JSON string passed as the second argument of PostAsync is too large (the limit is about 2,000 times the size of the string I have). I’m at a loss to explain what’s going on with this. Additionally, according to a repeatedly-quoted Twitter thread about Discord rate limits, HTTP 403 is the rate limit error for a blocked request?

Ok I’m home now just give me one moment I’m loading my laptop.

Ok, I just tried my script and it works I’ll go ahead and provide you it and see if you can modify it to work with your embed function
I wasn’t sure how to cross out where the text was before this one but I’m gonna search what content is for on the embed

Try removing the bannedPlayer.Name.." banned by "..moderator.Name.."." when calling the function and add it to the function itself so

local content = bannedPlayer.Name.." banned by "..moderator.Name.."."

Also, I am very sorry if this isn’t working right I just haven’t had this issue so I’m just suggesting fixes that may work as I have never encountered this issue myself :grimacing:

And after setting the content variable manually in the data table and changing some stuff, I found the hiding error.

local msgObj = NewJSON(bannedPlayer.Name,bannedPlayer.UserId,moderator,banlength,banreason,bannedPlayer.Name.." banned by "..moderator.Name..".")

should have been

local msgObj = NewJSON(bannedPlayer.Name,bannedPlayer.UserId,moderator.Name,banlength,banreason,bannedPlayer.Name.." banned by "..moderator.Name..".").

By passing moderator (a userdata value) instead of moderator.Name (a string value), I threw off… the ENTIRE SCRIPT! Awesome…


Thank you so much for all the insight, I couldn’t have fixed it without you.
Here’s a screenshot of the successful webhook entry!

1 Like

I did not notice that myself :joy:Although I am very happy that your problem is solved!