Skip to content

Lesson 5: Send messages safely

Goal: reply to !echo text without flooding or passing along unsafe text.

--! name: Safe echo
--! description: !echo <text> with a per-nick cooldown
--! api: 1
--! permissions: send
local COOLDOWN_MS = 5000
local lastUse: {[string]: number} = {}
local function clean(text: string): string
text = swizzin.strip(text) -- remove IRC colours and formatting
text = string.gsub(text, "[\r\n]+", " ") -- one line only
return string.sub(text, 1, 300) -- keep it short
end
swizzin.on("message", function(e)
if not swizzin.wildmatch("!echo *", e.text) then return end
local last = lastUse[e.nick]
if last ~= nil and e.time - last < COOLDOWN_MS then return end
lastUse[e.nick] = e.time
swizzin.send(e.target, "You said: " .. clean(string.sub(e.text, 7)))
end)

It ignores everything except !echo ..., allows one use per nick every 5 seconds (using the event’s own time), and cleans the text before sending.

  • Text must be one line of 1 to 2000 characters.
  • Text that looks like an authentication command (IDENTIFY, LOGIN, PASS, …) is refused, and so are messages to ZNC *module users.
  • At most 10 messages per second (burst of 20) per script.
  • Without a network context an action is refused rather than guessed.

!echo hello is answered with You said: hello. Repeating it within 5 seconds from the same nick is ignored.

  • Echoing user text unchanged: it can be long, multi-line or try to trigger other bots.
  • Replying to bots, which can start message loops.
  • Sending from a timer in a tight loop.
  • A send does nothing: the reason is written to the Console (permission, empty or too-long text, line break, rate limit).