Change the behaviour of service code detection
- Parse service codes if they are sent as `!code` or `nick: !code` in channels and private messages (where `!code` is an example code prefix and service code, and `nick` is the bot's nick). If the service code is not provided at the start of the message body, it will be treated as a message without a service code and passed to the target handler. - If a target handler is defined, both messages in the form `nick: message` in a channel and `message` in a private message will be sent to the handler. The `nick:` at the start of `nick: message` will no longer be filtered out. The default name of the target handler is `target`, as in `itte_handlers.target(cxt, msg)`. This can be changed in the config by setting a new `itte_config.target_handler` value.
This commit is contained in:
		
							parent
							
								
									562f112995
								
							
						
					
					
						commit
						8e84095be6
					
				
							
								
								
									
										71
									
								
								itte.lua
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								itte.lua
									
									
									
									
									
								
							@ -251,16 +251,31 @@ function itte.get_commands(svr)
 | 
			
		||||
      resp = "QUIT :",
 | 
			
		||||
    },
 | 
			
		||||
    target_private = {
 | 
			
		||||
      -- Like privmsg but targets bot nick in a direct message without a
 | 
			
		||||
      -- service code.
 | 
			
		||||
      -- Escape magic character "-"
 | 
			
		||||
      check = "PRIVMSG(.*)" .. string.gsub(svr.nick, "-", "%%-") .. "(.*):",
 | 
			
		||||
      resp = nil,
 | 
			
		||||
    },
 | 
			
		||||
    target_private_code = {
 | 
			
		||||
      -- Like privmsg but targets bot nick in a direct message
 | 
			
		||||
      -- Escape magic character "-"
 | 
			
		||||
      check = "PRIVMSG(.*)" .. string.gsub(svr.nick, "-", "%%-") .. ":",
 | 
			
		||||
      resp = "PRIVMSG ",
 | 
			
		||||
      check = "PRIVMSG(.*)" .. string.gsub(svr.nick, "-", "%%-") .. "(.*):" ..
 | 
			
		||||
        string.gsub(svr.nick, "-", "%%-") .. "(.*)" .. svr.code_prefix,
 | 
			
		||||
      resp = nil,
 | 
			
		||||
    },
 | 
			
		||||
    target_public = {
 | 
			
		||||
      -- Like privmsg but targets bot nick in a channel
 | 
			
		||||
      -- Like privmsg but targets bot nick in a channel without a service code.
 | 
			
		||||
      -- Escape magic character "-"
 | 
			
		||||
      check = "PRIVMSG(.*)#(.*):" .. string.gsub(svr.nick, "-", "%%-"),
 | 
			
		||||
      resp = "PRIVMSG ",
 | 
			
		||||
      resp = nil,
 | 
			
		||||
    },
 | 
			
		||||
    target_public_code = {
 | 
			
		||||
      -- Like privmsg but targets bot nick in a channel
 | 
			
		||||
      -- Escape magic character "-"
 | 
			
		||||
      check = "PRIVMSG(.*)#(.*):" .. string.gsub(svr.nick, "-", "%%-") ..
 | 
			
		||||
        "(.*)" .. svr.code_prefix,
 | 
			
		||||
      resp = nil,
 | 
			
		||||
    },
 | 
			
		||||
    user = {
 | 
			
		||||
      check = "NOTICE",
 | 
			
		||||
@ -610,18 +625,16 @@ function itte.parse_privmsg(cxt, str, mode)
 | 
			
		||||
  -- Separator marks the start of the message body
 | 
			
		||||
  body_sep, _ = string.find(str, ":", 2)
 | 
			
		||||
 | 
			
		||||
  -- Message in the format `[nick]: [body]`
 | 
			
		||||
  -- Message in the format `[body]` (private message) or `[nick]: [body]`
 | 
			
		||||
  if mode == "target" then
 | 
			
		||||
    msg = {
 | 
			
		||||
      sender = string.sub(str, string.find(str, "!") + 2,
 | 
			
		||||
        string.find(str, "@") - 1),
 | 
			
		||||
      -- Escape magic character "-" in the nick
 | 
			
		||||
      recipient = string.sub(str, string.find(str, "PRIVMSG") + 8,
 | 
			
		||||
        string.find(str, ":" .. string.gsub(cxt.nick, "-", "%%-")) - 2),
 | 
			
		||||
        string.find(str, " :") - 1),
 | 
			
		||||
      reply_to = string.sub(str, string.find(str, "!") + 2,
 | 
			
		||||
        string.find(str, "@") - 1),
 | 
			
		||||
      body = string.gsub(string.sub(str, body_sep + 2 +
 | 
			
		||||
        string.len(cxt.nick)), "^%s", ""),
 | 
			
		||||
      body = string.sub(str, body_sep + 1),
 | 
			
		||||
    }
 | 
			
		||||
    -- Reply to sender by default (private message), or reply in a channel if
 | 
			
		||||
    -- original message recipient is a channel.
 | 
			
		||||
@ -635,19 +648,31 @@ function itte.parse_privmsg(cxt, str, mode)
 | 
			
		||||
      ", " .. itte.config.debugs.privmsg[7] .. ": " .. msg.body ..
 | 
			
		||||
      " }", itte.config.debug)
 | 
			
		||||
 | 
			
		||||
  -- Message in the format `[code] [params]`
 | 
			
		||||
  -- Message in the format `[code] [params]` or `[nick] [code] [params]`
 | 
			
		||||
  else
 | 
			
		||||
    -- Set the code prefix position variable to a number out of range of the
 | 
			
		||||
    -- service code parsing buffer, then get the position. Check for the colon
 | 
			
		||||
    -- separator at exactly the start of the message body, i.e. `[code]`, or
 | 
			
		||||
    -- the space char for `[nick] [code]`.
 | 
			
		||||
    local code_full = ""
 | 
			
		||||
    -- Service code found with specified prefix
 | 
			
		||||
    if util.is_substr(str, ":" .. cxt.code_prefix) then
 | 
			
		||||
      code_full = string.sub(str, string.find(str, ":" ..
 | 
			
		||||
        cxt.code_prefix) + 1 + string.len(cxt.code_prefix))
 | 
			
		||||
    local cp_pos = body_sep + string.len(cxt.nick) + 4
 | 
			
		||||
    local co_sep, _ = string.find(str, ":" .. cxt.code_prefix)
 | 
			
		||||
    if co_sep == body_sep then
 | 
			
		||||
      cp_pos = string.find(str, ":" .. cxt.code_prefix)
 | 
			
		||||
    elseif string.find(str, " " .. cxt.code_prefix) ~= nil then
 | 
			
		||||
      cp_pos = string.find(str, " " .. cxt.code_prefix)
 | 
			
		||||
    end
 | 
			
		||||
    -- Only parse service code if it is near the start of the message body,
 | 
			
		||||
    -- within a small buffer in position to allow some variation in style, e.g.
 | 
			
		||||
    -- `[nick]: [code]`, `[nick] [code]`, etc.
 | 
			
		||||
    if cp_pos <= body_sep + string.len(cxt.nick) + 3 then
 | 
			
		||||
      code_full = string.sub(str, cp_pos + 1 + string.len(cxt.code_prefix))
 | 
			
		||||
    end
 | 
			
		||||
    msg = {
 | 
			
		||||
      sender = string.sub(str, string.find(str, "!") + 2,
 | 
			
		||||
        string.find(str, "@") - 1),
 | 
			
		||||
      recipient = string.sub(str, string.find(str, "PRIVMSG") + 8,
 | 
			
		||||
        string.find(str, ":" .. cxt.code_prefix) - 2),
 | 
			
		||||
        string.find(str, " :") - 1),
 | 
			
		||||
      reply_to = string.sub(str, string.find(str, "!") + 2,
 | 
			
		||||
        string.find(str, "@") - 1),
 | 
			
		||||
      body = string.sub(str, body_sep + 1),
 | 
			
		||||
@ -656,7 +681,6 @@ function itte.parse_privmsg(cxt, str, mode)
 | 
			
		||||
      msg.code = string.sub(code_full, 0, string.find(code_full, " ") - 1)
 | 
			
		||||
      msg.code_params = util.split_str(string.sub(code_full,
 | 
			
		||||
        string.find(code_full, " ") + 1))
 | 
			
		||||
 | 
			
		||||
    else
 | 
			
		||||
      msg.code = code_full
 | 
			
		||||
      msg.code_params = {}
 | 
			
		||||
@ -666,7 +690,6 @@ function itte.parse_privmsg(cxt, str, mode)
 | 
			
		||||
    if util.is_substr(msg.recipient, "#") then
 | 
			
		||||
      msg.reply_to = msg.recipient
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    -- Redact debug output for admin-only handlers to avoid logging passwords.
 | 
			
		||||
    local body = msg.body
 | 
			
		||||
    local code_params = table.concat(msg.code_params, " ")
 | 
			
		||||
@ -937,8 +960,12 @@ function itte.listen(name, str)
 | 
			
		||||
    local channel, names = itte.parse_names(cxt, str)
 | 
			
		||||
    cxt.chan_meta[channel:sub(2)] = { users = names }
 | 
			
		||||
 | 
			
		||||
  -- Respond to service code
 | 
			
		||||
  elseif util.is_substr(str, cxt.cmds.privmsg.check) then
 | 
			
		||||
  -- Respond to service code, checking for `[code]` and `[nick]: [code]`.
 | 
			
		||||
  -- Code prefix cannot be the last character in the data string.
 | 
			
		||||
  elseif (util.is_substr(str, cxt.cmds.privmsg.check) or
 | 
			
		||||
    (util.is_substr(str, cxt.cmds.target_public_code.check)) or
 | 
			
		||||
    (util.is_substr(str, cxt.cmds.target_private_code.check))) and
 | 
			
		||||
    (str:sub(string.len(str)) ~= cxt.code_prefix) then
 | 
			
		||||
    local msg = itte.parse_privmsg(cxt, str)
 | 
			
		||||
    -- Check for the service in the admin handlers table and redact the debug
 | 
			
		||||
    -- output for admin handlers.
 | 
			
		||||
@ -960,6 +987,12 @@ function itte.listen(name, str)
 | 
			
		||||
    -- Check the handlers table
 | 
			
		||||
    elseif util.has_key(itte.handlers, msg.code) then
 | 
			
		||||
      itte.handlers[msg.code](cxt, msg)
 | 
			
		||||
    -- If there is no service code found near the start of the message body,
 | 
			
		||||
    -- respond as a direct address and pass the message to the target handler
 | 
			
		||||
    -- if it exists.
 | 
			
		||||
    elseif (util.has_key(itte.handlers, itte.config.target_handler)) and
 | 
			
		||||
      (msg.code == "") then
 | 
			
		||||
      itte.handlers[itte.config.target_handler](cxt, msg)
 | 
			
		||||
    else
 | 
			
		||||
      -- Only hint with unknown code error in private messages as there may be
 | 
			
		||||
      -- prefix collision in channels.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user