From 5ae8f998341fda4481fd8f65d9d980b4827f2300 Mon Sep 17 00:00:00 2001 From: PieterCK Date: Fri, 7 Jun 2024 22:22:41 +0700 Subject: [PATCH] slack bridge: Add legacy mode for Slack Bridge. Slack Bridge now uses the Slack Webhook integration to get messages accross from Slack instead of the legacy RTM API based connection our Slack Bridge use. This commit adds a "--legacy" argument to the script, it acts as a toggle to run the RTM API based connection to get messages accross to Zulip. It is used to ensure backwards compitability for users who want to maintain any ongoing Slack mirror. Fixes #825. --- .../bridge_with_slack_config.py | 4 +-- .../bridge_with_slack/run-slack-bridge | 35 ++++++++++++++----- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/zulip/integrations/bridge_with_slack/bridge_with_slack_config.py b/zulip/integrations/bridge_with_slack/bridge_with_slack_config.py index 9dd733313..f1a89d82f 100644 --- a/zulip/integrations/bridge_with_slack/bridge_with_slack_config.py +++ b/zulip/integrations/bridge_with_slack/bridge_with_slack_config.py @@ -13,8 +13,8 @@ "channel_mapping": { # Slack channel; must be channel ID "C5Z5N7R8A": { - # Zulip stream - "stream": "test here", + # Zulip channel + "channel": "test here", # Zulip topic "topic": "<- slack-bridge", }, diff --git a/zulip/integrations/bridge_with_slack/run-slack-bridge b/zulip/integrations/bridge_with_slack/run-slack-bridge index 32c6deb1b..efb6f404a 100755 --- a/zulip/integrations/bridge_with_slack/run-slack-bridge +++ b/zulip/integrations/bridge_with_slack/run-slack-bridge @@ -8,8 +8,8 @@ import traceback from typing import Any, Callable, Dict, Optional, Tuple import bridge_with_slack_config -import slack_sdk from slack_sdk.rtm_v2 import RTMClient +from slack_sdk.web.client import WebClient import zulip @@ -49,7 +49,7 @@ class SlackBridge: self.slack_to_zulip_map: Dict[str, Dict[str, str]] = config["channel_mapping"] self.zulip_to_slack_map: Dict[StreamTopicT, str] = { - (z["stream"], z["topic"]): s for s, z in config["channel_mapping"].items() + (z["channel"], z["topic"]): s for s, z in config["channel_mapping"].items() } # zulip-specific @@ -69,7 +69,7 @@ class SlackBridge: self.slack_client = rtm # Spawn a non-websocket client for getting the users # list and for posting messages in Slack. - self.slack_webclient = slack_sdk.WebClient(token=self.slack_config["token"]) + self.slack_webclient = WebClient(token=self.slack_config["token"]) def wrap_slack_mention_with_bracket(self, zulip_msg: Dict[str, Any]) -> None: words = zulip_msg["content"].split(" ") @@ -123,7 +123,7 @@ class SlackBridge: zulip_endpoint = self.slack_to_zulip_map[event["channel"]] msg_data = dict( type="stream", - to=zulip_endpoint["stream"], + to=zulip_endpoint["channel"], subject=zulip_endpoint["topic"], content=content, ) @@ -141,6 +141,10 @@ if __name__ == "__main__": sys.path.append(os.path.join(os.path.dirname(__file__), "..")) parser = argparse.ArgumentParser(usage=usage) + parser.add_argument( + "--legacy", action="store_true", help="Run the bridge using the legacy Slack RTM API" + ) + args = parser.parse_args() config: Dict[str, Any] = bridge_with_slack_config.config if "channel_mapping" not in config: @@ -154,6 +158,7 @@ if __name__ == "__main__": print("MAKE SURE THE BOT IS SUBSCRIBED TO THE RELEVANT ZULIP STREAM(S) & SLACK CHANNEL(S)!") # We have to define rtm outside of SlackBridge because the rtm variable is used as a method decorator. + # the RTM API is a legacy Slack SDK, we keep using them only to provide backwards compitability. rtm = RTMClient(token=config["slack"]["token"]) backoff = zulip.RandomExponentialBackoff(timeout_success_equivalent=300) @@ -164,14 +169,26 @@ if __name__ == "__main__": zp = threading.Thread( target=sb.zulip_client.call_on_each_message, args=(sb.zulip_to_slack(),) ) - sp = threading.Thread(target=sb.run_slack_listener, args=()) print("Starting message handler on Zulip client") zp.start() - print("Starting message handler on Slack client") - sp.start() - zp.join() - sp.join() + if args.legacy: + sp = threading.Thread(target=sb.run_slack_listener, args=()) + print( + "Warning! Running on legacy Slack SDK\n" + "Starting message handler on Slack client" + ) + sp.start() + sp.join() + zp.join() + else: + print( + "Warning! if you haven't moved to the new Slack app,\n" + "please run the script with the --legacy argument.\n" + "Make sure your Slack Webhook integration is running\n" + "to receive messages from Slack." + ) + zp.join() except Exception: traceback.print_exc() backoff.fail()