Skip to content

Instantly share code, notes, and snippets.

@tomsmeding
Created October 8, 2023 19:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomsmeding/367d8326ed833bde37244fb4db520253 to your computer and use it in GitHub Desktop.
Save tomsmeding/367d8326ed833bde37244fb4db520253 to your computer and use it in GitHub Desktop.
Weechat plugin for reformatting messages from bridged users
# -*- coding:utf-8 -*-
################################################################################
# Copyright (C) 2023 Tom Smeding
# https://tomsmeding.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
################################################################################
#
# A bridge bot relays messages between IRC and other chat networks such as Slack
# and Discord. Since messages from the users of such networks are sent from the
# bot, the name of the sender is contained within the message text, the format
# of which is up to the admin of the bot.
#
# This script intercepts messages before WeeChat displays them and reformats
# them so that it seems as if the message actually came from IRC.
#
################################################################################
# Change Log:
#
# 0.1.0 - 2023-10-08 - Tom Smeding
# * This script was (heavily) edited from:
# https://github.com/thecliguy/format_bridge_bot_output/blob/master/format_bridge_bot_output/format_bridge_bot_output.py
# which itself was a heavily edited version of 'weechat_bot2human.py'
# (version 0.1.1) from the scripts repository of the TUNA (Tsinghua
# University TUNA Association) organization on Github:
# https://github.com/tuna/scripts.
#
# The source script was GPLv3, hence this script is too.
#
################################################################################
import weechat as w
import re
SCRIPT_NAME = "reformat_bridgebot"
SCRIPT_AUTHOR = "Tom Smeding (https://tomsmeding.com)"
SCRIPT_DESC = "Reformats messages received from a bridge bot to appear as though they came from an IRC user."
SCRIPT_VERSION = "0.1.0"
SCRIPT_LICENSE = "GPLv3"
# Example message:
# @time=2023-10-08T18:32:16.334Z :haskellbridge!~haskellbr@example.com PRIVMSG #haskell :<U\u200bser> A long message
# The parsed table then looks as follows:
# {
# 'tags': 'time=2023-10-08T18:32:16.334Z',
# 'tag_time': '2023-10-08T18:32:16.334Z',
# 'message_without_tags': ":haskellbridge!~haskellbr@example.com PRIVMSG #haskell :<U\u200bser> A long message",
# 'nick': 'haskellbridge',
# 'user': '~haskellbr',
# 'host': 'haskellbridge!~haskellbr@example.com',
# 'command': 'PRIVMSG',
# 'channel': '#haskell',
# 'arguments': "#haskell :<U\u200bser> A long message",
# 'text': "<U\u200bser> A long message",
# 'num_params': '2',
# 'param1': '#haskell',
# 'param2': "<U\u200bser> A long message",
# 'pos_command': '69',
# 'pos_arguments': '77',
# 'pos_channel': '77',
# 'pos_text': '87'
# }
def msg_cb(data, modifier, modifier_data, string):
parsed = w.info_get_hashtable("irc_message_parse", {"message": string})
# w.prnt("", w.prefix("error") + SCRIPT_NAME + ": " + repr(string) + " ; " + repr(parsed))
# @tags :nick!user@....... COMMAND channel :text
# ^^^^^^^^^^^^^^^^^
# host
# Check if we need to do anything
if modifier_data not in ["liberachat"]: return string # See the documentation: https://weechat.org/files/doc/weechat/stable/weechat_plugin_api.en.html#_hook_modifier
if parsed["channel"] not in ["#haskell"]: return string
if parsed["nick"] not in ["haskellbridge"]: return string
# Parse out the nick and message; don't do anything if that fails
m = re.match(r"<(.+?)> (.*)", parsed["text"])
if m is None: return string
new_nick = m.group(1)
new_text = m.group(2)
# Sanitise the nick
new_nick = new_nick.replace("\u200b", "") # bridge bots put ZWSP in nicks to prevent self-pinging when using a bridged service as well as IRC
new_nick = new_nick.replace(" ", "") # IRC syntax doesn't allow spaces ni nicks
if len(new_nick) > 15: # other platforms have looser constraints on nick length
new_nick = new_nick[:15] + "…"
new_nick = "↑" + new_nick # prefix with a marker to show it's a bridged message
# Collect the tags prefix
tags_prefix = "@{tags} ".format(**parsed) if "tags" in parsed and len(parsed["tags"]) > 0 else ""
# Build the new host value
if parsed["host"].startswith("{nick}!".format(**parsed)):
new_host = new_nick + parsed["host"][len(parsed["nick"]):]
else:
new_host = "{}!{}@unknown.example.com".format(new_nick, parsed["user"])
return f"{tags_prefix}:{new_host} {parsed['command']} {parsed['channel']} :{new_text}"
if __name__ == '__main__':
w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", "")
w.hook_modifier("irc_in2_privmsg", "msg_cb", "")
# vim: ts=4 sw=4 et:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment