bots: Init interrealm bridge bot.
This commit is contained in:
parent
480c953b98
commit
da4b830571
15
zulip_bots/zulip_bots/bots/interrealm_bridge/README.md
Normal file
15
zulip_bots/zulip_bots/bots/interrealm_bridge/README.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Inter-realm bot
|
||||
|
||||
Let `realm_1` be the first realm, `realm_2` be the second realm. Let `bot_1` be
|
||||
the relay bot in `realm_1`, `bot_2` be the relay bot in `realm_2`.
|
||||
|
||||
This bot relays each message received at a specified subject in a specified
|
||||
stream from `realm_1` to a specified subject in a specified stream in `realm_2`.
|
||||
|
||||
Steps to create an inter-realm bridge:
|
||||
1. Register a generic bot (`bot_1`) in `realm_1`
|
||||
2. Enter the api info of `bot_1` into the config file (interrealm_bridge_config.py)
|
||||
3. Create a stream in `realm_1` (`stream_1`) and a subject for the bridge
|
||||
4. Make sure `bot_1` is subscribed to `stream_1`
|
||||
5. Enter the stream and the subject into the config file.
|
||||
6. Do step 1-5 but for `bot_2` and with all occurrences of `_1` replaced with `_2`
|
|
@ -0,0 +1,14 @@
|
|||
config = {
|
||||
"bot_1": {
|
||||
"email": "tunnel-bot@realm1.zulipchat.com",
|
||||
"api_key": "key1",
|
||||
"site": "https://realm1.zulipchat.com",
|
||||
"stream": "bridges",
|
||||
"subject": "<- realm2"},
|
||||
"bot_2": {
|
||||
"email": "tunnel-bot@realm2.zulipchat.com",
|
||||
"api_key": "key2",
|
||||
"site": "https://realm2.zulipchat.com",
|
||||
"stream": "bridges",
|
||||
"subject": "<- realm1"}
|
||||
}
|
92
zulip_bots/zulip_bots/bots/interrealm_bridge/run-interrealm-bridge
Executable file
92
zulip_bots/zulip_bots/bots/interrealm_bridge/run-interrealm-bridge
Executable file
|
@ -0,0 +1,92 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import multiprocessing as mp
|
||||
import zulip
|
||||
import interrealm_bridge_config
|
||||
|
||||
from typing import Any, Callable, Dict
|
||||
|
||||
|
||||
def create_pipe_event(to_client: zulip.Client, from_bot: Dict[str, Any],
|
||||
to_bot: Dict[str, Any], stream_wide: bool
|
||||
) -> Callable[[Dict[str, Any]], None]:
|
||||
def _pipe_message(msg: Dict[str, Any]) -> None:
|
||||
isa_stream = msg["type"] == "stream"
|
||||
not_from_bot = msg["sender_email"] not in (from_bot["email"], to_bot["email"])
|
||||
in_the_specified_stream = msg["display_recipient"] == from_bot["stream"]
|
||||
|
||||
if stream_wide:
|
||||
# If tunnel granularity is at stream-wide, all subjects are
|
||||
# mirrored as-is without translation.
|
||||
at_the_specified_subject = True
|
||||
subject = msg["subject"]
|
||||
else:
|
||||
at_the_specified_subject = msg["subject"] == from_bot["subject"]
|
||||
subject = to_bot["subject"]
|
||||
|
||||
if isa_stream and not_from_bot and in_the_specified_stream and at_the_specified_subject:
|
||||
if "/user_uploads/" in msg["content"]:
|
||||
# Fix the upload URL of the image to be the source of where it
|
||||
# comes from
|
||||
msg["content"] = msg["content"].replace("/user_uploads/",
|
||||
from_bot["site"] + "/user_uploads/")
|
||||
msg_data = {
|
||||
"sender": to_client.email,
|
||||
"type": "stream",
|
||||
"to": to_bot["stream"],
|
||||
"subject": subject,
|
||||
"content": "**{0}**: {1}".format(msg["sender_full_name"], msg["content"]),
|
||||
"has_attachment": msg.get("has_attachment", False),
|
||||
"has_image": msg.get("has_image", False),
|
||||
"has_link": msg.get("has_link", False)
|
||||
}
|
||||
print(msg_data)
|
||||
print(to_client.send_message(msg_data))
|
||||
|
||||
def _pipe_event(event: Dict[str, Any]) -> None:
|
||||
# See zerver/lib/events.py for a comprehensive event list
|
||||
if event["type"] == "message":
|
||||
msg = event["message"]
|
||||
_pipe_message(msg)
|
||||
return _pipe_event
|
||||
|
||||
if __name__ == "__main__":
|
||||
usage = """run-interrealm-bridge [--stream]
|
||||
|
||||
Relay each message received at a specified subject in a specified stream from
|
||||
the first realm to a specified subject in a specified stream in the second realm.
|
||||
|
||||
If the --stream flag is added, then the tunnel granularity becomes
|
||||
stream-wide. All subjects are mirrored as-is without translation.
|
||||
"""
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
parser = argparse.ArgumentParser(usage=usage)
|
||||
parser.add_argument('--stream',
|
||||
action='store_true',
|
||||
help="",
|
||||
default=False)
|
||||
args = parser.parse_args()
|
||||
|
||||
options = interrealm_bridge_config.config
|
||||
|
||||
bot1 = options["bot_1"]
|
||||
bot2 = options["bot_2"]
|
||||
client1 = zulip.Client(email=bot1["email"], api_key=bot1["api_key"],
|
||||
site=bot1["site"])
|
||||
client2 = zulip.Client(email=bot2["email"], api_key=bot2["api_key"],
|
||||
site=bot2["site"])
|
||||
# A bidirectional tunnel
|
||||
pipe_event1 = create_pipe_event(client2, bot1, bot2, args.stream)
|
||||
p1 = mp.Process(target=client1.call_on_each_event, args=(pipe_event1, ["message"]))
|
||||
pipe_event2 = create_pipe_event(client1, bot2, bot1, args.stream)
|
||||
p2 = mp.Process(target=client2.call_on_each_event, args=(pipe_event2, ["message"]))
|
||||
p1.start()
|
||||
p2.start()
|
||||
print("Listening...")
|
||||
p1.join()
|
||||
p2.join()
|
Loading…
Reference in a new issue