bots: Init interrealm bridge bot.
This commit is contained in:
		
							parent
							
								
									480c953b98
								
							
						
					
					
						commit
						da4b830571
					
				
					 3 changed files with 121 additions and 0 deletions
				
			
		
							
								
								
									
										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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 rht
						rht