Discord Webhook Duplication Issue

Hello,
I have a Overhead Gui located in ServerStorage and I have a script in ServerScriptService which controls it. In the script I have a discord webhook connection which makes it so when an allowed player (they are on the top of the script) types a command in chat it send a webhook message to my discord channel saying that he used the command. Everything is working perfectly but I have one problem, when an allowed player types that command the webhook bot sends two same message like it is duplicated. I want the bot to send only one message and not duplicated message. Please can you find a fix since I can’t find what’s wrong.

Here is the script:

local HttpService = game:GetService("HttpService")
local MainGroup = 35446573
local PlayerTag = game.ServerStorage:WaitForChild("NameTag")

local allowedPlayers = {
	[2752190121] = true, --Bobek858 (Borna)
	[3128499514] = true, --0perator_luka
	[3827173770] = true, --Nolex_3
	[4325414357] = true, --nikola3222324ALT (Bojan)
	[3322404474] = true, --ikfajiv2 (Marko)
	[3529318487] = true, --ilkezaa2 
	[4128970520] = true, --ANDREJJJJYY
	[4051393942] = true, --luka5957959
	[3086006594] = true, --makimungos
	[7169592985] = true, --HatefulVasilije
	[7889586255] = true, --makimungos1 alt acc
}

local webhookURL = "MYWEBHOOK"

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local NameTag = PlayerTag:Clone()
		NameTag.Parent = character:WaitForChild("Head")

		local duznostVisible = false
		local duznostFrame = NameTag:WaitForChild("Duznost")
		duznostFrame.Visible = false
		local activationTime = nil 
		local deactivationTime = nil 
		local webhookSent = false  

		local function sendWebhook(status)
			local groupRankName = player:GetRoleInGroup(MainGroup)
			local color = status == "Activated" and 3447003 or 15158332  -- Blue for activated, Red for deactivated
			local timeActivated = os.date("%Y-%m-%d %H:%M:%S", activationTime)
			local timeDeactivated = deactivationTime and os.date("%Y-%m-%d %H:%M:%S", deactivationTime) or nil
			local duration = deactivationTime and deactivationTime - activationTime or nil  -- Calculate the duration if deactivated

			local embed = {
				["title"] = "Duznost " .. status,
				["description"] = player.Name .. " " .. status:lower() .. " the duznost command.",
				["color"] = color,
				["fields"] = {
					{ ["name"] = "Player", ["value"] = player.Name, ["inline"] = true },
					{ ["name"] = "Group Rank", ["value"] = groupRankName, ["inline"] = true },
					{ ["name"] = "Status", ["value"] = status, ["inline"] = true },
					{ ["name"] = "Time Activated", ["value"] = timeActivated, ["inline"] = true },
				}
			}

			if status == "Deactivated" then
				table.insert(embed["fields"], { ["name"] = "Time Deactivated", ["value"] = timeDeactivated, ["inline"] = true })
				if duration then
					table.insert(embed["fields"], { ["name"] = "Duration", ["value"] = tostring(duration) .. " seconds", ["inline"] = true })
				end
			end

			local data = HttpService:JSONEncode({ embeds = { embed } })
			HttpService:PostAsync(webhookURL, data, Enum.HttpContentType.ApplicationJson)
		end

		-- Handle the player chat command
		player.Chatted:Connect(function(message)
			-- Only allowed players can use the command
			if allowedPlayers[player.UserId] and message:lower() == "/e duznost" then
				-- Toggle the frame visibility
				duznostVisible = not duznostVisible
				duznostFrame.Visible = duznostVisible

				-- If the command is activated (showing the frame)
				if duznostVisible then
					-- Send the activation webhook only if it hasn't been sent yet
					if not webhookSent then
						activationTime = os.time()  -- Store the activation time
						sendWebhook("Activated")  -- Send Webhook for activation
						webhookSent = true  -- Mark as sent to prevent sending again
					end
					-- If the command is deactivated (hiding the frame)
				else
					-- Send the deactivation webhook only if it's been activated
					if webhookSent then
						deactivationTime = os.time()  -- Store the deactivation time
						sendWebhook("Deactivated")  -- Send Webhook for deactivation
						webhookSent = false  -- Reset the flag to allow the next activation
					end
				end
			end
		end)

		-- Set Rank and Team Name
		local groupRankName = player:GetRoleInGroup(MainGroup)
		NameTag.Rank.TextLabel.Text = groupRankName  -- Display the group's rank name
		NameTag.NamePlayer.TextLabel.Text = player.Name  -- Display the player's name

		-- Handle Team Name based on TeamColor
		if player.TeamColor == BrickColor.new("Gold") then
			NameTag.Teams.TextLabel.Text = "Civilians"
		elseif player.TeamColor == BrickColor.new("Maroon") then
			NameTag.Teams.TextLabel.Text = "Žandarmerija"
		elseif player.TeamColor == BrickColor.new("Really black") then
			NameTag.Teams.TextLabel.Text = "Zatvor"
		elseif player.TeamColor == BrickColor.new("Bright blue") then
			NameTag.Teams.TextLabel.Text = "Policija"
		elseif player.TeamColor == BrickColor.new("White") then
			NameTag.Teams.TextLabel.Text = "Menu"
		elseif player.TeamColor == BrickColor.new("Really red") then
			NameTag.Teams.TextLabel.Text = "Insurgents"
		end

		-- Handle icons based on rank
		if player:GetRankInGroup(MainGroup) == 255 then  -- Founder
			NameTag.Icon.Owner.Visible = true
			NameTag.Icon.Dev.Visible = true
			NameTag.Icon.STAFF_ICON.Visible = true
		elseif player:GetRankInGroup(MainGroup) == 254 then  -- Holder
			NameTag.Icon.Owner.Visible = true
			NameTag.Icon.Dev.Visible = true
			NameTag.Icon.STAFF_ICON.Visible = true
		elseif player:GetRankInGroup(MainGroup) == 10 then  -- Developer
			NameTag.Icon.Dev.Visible = true
			NameTag.Icon.STAFF_ICON.Visible = true
		elseif player:GetRankInGroup(MainGroup) == 7 then  -- Admin
			NameTag.Icon.STAFF_ICON.Visible = true
		else  -- Member
			NameTag.Icon.STAFF_ICON.Visible = false
			NameTag.Icon.Owner.Visible = false
			NameTag.Icon.Dev.Visible = false
		end
	end)
end)

Here is the problem:

Thank you in advance!

It’s actually pretty simple, you’re creating a new Chatted connection every time the player respawns.
Try listening for the Chatted event out of the CharacterAdded event.

Not only that, if you keep this in your game it will also cause a memory leak. :derp:

Well I don’t know how to script, can you help me out on how to do it… I would really appreciate it.

Hey, can you please answer and help since nobody is answering to my post?

You should always clean-up an existing connection, otherwise this issue will get worse everytime a player respawns.

Just for future reference, this is a forum for receiving advice for game-development.
Don’t expect anyone to provide free code for you.

game.Players.PlayerAdded:Connect(function(player)
    local signals = {}
	player.CharacterAdded:Connect(function(character)
        for _,v in pairs(signals) do v:Disconnect() end
		local NameTag = PlayerTag:Clone()
		NameTag.Parent = character:WaitForChild("Head")

		local duznostVisible = false
		local duznostFrame = NameTag:WaitForChild("Duznost")
		duznostFrame.Visible = false
		local activationTime = nil 
		local deactivationTime = nil 
		local webhookSent = false  

		local function sendWebhook(status)
			local groupRankName = player:GetRoleInGroup(MainGroup)
			local color = status == "Activated" and 3447003 or 15158332  -- Blue for activated, Red for deactivated
			local timeActivated = os.date("%Y-%m-%d %H:%M:%S", activationTime)
			local timeDeactivated = deactivationTime and os.date("%Y-%m-%d %H:%M:%S", deactivationTime) or nil
			local duration = deactivationTime and deactivationTime - activationTime or nil  -- Calculate the duration if deactivated

			local embed = {
				["title"] = "Duznost " .. status,
				["description"] = player.Name .. " " .. status:lower() .. " the duznost command.",
				["color"] = color,
				["fields"] = {
					{ ["name"] = "Player", ["value"] = player.Name, ["inline"] = true },
					{ ["name"] = "Group Rank", ["value"] = groupRankName, ["inline"] = true },
					{ ["name"] = "Status", ["value"] = status, ["inline"] = true },
					{ ["name"] = "Time Activated", ["value"] = timeActivated, ["inline"] = true },
				}
			}

			if status == "Deactivated" then
				table.insert(embed["fields"], { ["name"] = "Time Deactivated", ["value"] = timeDeactivated, ["inline"] = true })
				if duration then
					table.insert(embed["fields"], { ["name"] = "Duration", ["value"] = tostring(duration) .. " seconds", ["inline"] = true })
				end
			end

			local data = HttpService:JSONEncode({ embeds = { embed } })
			HttpService:PostAsync(webhookURL, data, Enum.HttpContentType.ApplicationJson)
		end

		-- Handle the player chat command
		table.insert(signals, player.Chatted:Connect(function(message)
			-- Only allowed players can use the command
			if allowedPlayers[player.UserId] and message:lower() == "/e duznost" then
				-- Toggle the frame visibility
				duznostVisible = not duznostVisible
				duznostFrame.Visible = duznostVisible

				-- If the command is activated (showing the frame)
				if duznostVisible then
					-- Send the activation webhook only if it hasn't been sent yet
					if not webhookSent then
						activationTime = os.time()  -- Store the activation time
						sendWebhook("Activated")  -- Send Webhook for activation
						webhookSent = true  -- Mark as sent to prevent sending again
					end
					-- If the command is deactivated (hiding the frame)
				else
					-- Send the deactivation webhook only if it's been activated
					if webhookSent then
						deactivationTime = os.time()  -- Store the deactivation time
						sendWebhook("Deactivated")  -- Send Webhook for deactivation
						webhookSent = false  -- Reset the flag to allow the next activation
					end
				end
			end
		end))

		-- Set Rank and Team Name
		local groupRankName = player:GetRoleInGroup(MainGroup)
		NameTag.Rank.TextLabel.Text = groupRankName  -- Display the group's rank name
		NameTag.NamePlayer.TextLabel.Text = player.Name  -- Display the player's name

		-- Handle Team Name based on TeamColor
		if player.TeamColor == BrickColor.new("Gold") then
			NameTag.Teams.TextLabel.Text = "Civilians"
		elseif player.TeamColor == BrickColor.new("Maroon") then
			NameTag.Teams.TextLabel.Text = "Žandarmerija"
		elseif player.TeamColor == BrickColor.new("Really black") then
			NameTag.Teams.TextLabel.Text = "Zatvor"
		elseif player.TeamColor == BrickColor.new("Bright blue") then
			NameTag.Teams.TextLabel.Text = "Policija"
		elseif player.TeamColor == BrickColor.new("White") then
			NameTag.Teams.TextLabel.Text = "Menu"
		elseif player.TeamColor == BrickColor.new("Really red") then
			NameTag.Teams.TextLabel.Text = "Insurgents"
		end

		-- Handle icons based on rank
		if player:GetRankInGroup(MainGroup) == 255 then  -- Founder
			NameTag.Icon.Owner.Visible = true
			NameTag.Icon.Dev.Visible = true
			NameTag.Icon.STAFF_ICON.Visible = true
		elseif player:GetRankInGroup(MainGroup) == 254 then  -- Holder
			NameTag.Icon.Owner.Visible = true
			NameTag.Icon.Dev.Visible = true
			NameTag.Icon.STAFF_ICON.Visible = true
		elseif player:GetRankInGroup(MainGroup) == 10 then  -- Developer
			NameTag.Icon.Dev.Visible = true
			NameTag.Icon.STAFF_ICON.Visible = true
		elseif player:GetRankInGroup(MainGroup) == 7 then  -- Admin
			NameTag.Icon.STAFF_ICON.Visible = true
		else  -- Member
			NameTag.Icon.STAFF_ICON.Visible = false
			NameTag.Icon.Owner.Visible = false
			NameTag.Icon.Dev.Visible = false
		end
	end)

Thank you so much. I know that I should nopt expect someone to provide me free code but I always nicely ask because I don’t know how to do it myself sadly. Thank you so much, this really helped!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.