def handle_slack_context(): try: rtm_client = RTMClient(token=token) logger.info("Opening connection to slack.") rtm_client.start() except SlackApiError: logger.exception("Error establishing connection to slack.")
async def run_client(loop, **kwargs): """Run slack RTM server.""" logging.info("starting client") slack_token = config.get('TOKEN') rtm_client = RTMClient(token=slack_token, loop=loop, run_async=True) rtm_client.start() logging.info("started client server") return
async def test_issue_611(self): channel_id = os.environ[SLACK_SDK_TEST_RTM_TEST_CHANNEL_ID] text = "This message was sent by <https://slack.dev/python-slackclient/|python-slackclient>! (test_issue_611)" self.message_count, self.reaction_count = 0, 0 async def process_messages(**payload): self.logger.info(payload) if ("subtype" in payload["data"] and payload["data"]["subtype"] == "message_replied"): return # skip self.message_count += 1 raise Exception("something is wrong!" ) # This causes the termination of the process async def process_reactions(**payload): self.logger.info(payload) self.reaction_count += 1 rtm = RTMClient(token=self.bot_token, run_async=True) RTMClient.on(event="message", callback=process_messages) RTMClient.on(event="reaction_added", callback=process_reactions) web_client = WebClient(token=self.bot_token, run_async=True) message = await web_client.chat_postMessage(channel=channel_id, text=text) ts = message["ts"] await asyncio.sleep(3) # intentionally not waiting here rtm.start() try: await asyncio.sleep(3) first_reaction = await web_client.reactions_add(channel=channel_id, timestamp=ts, name="eyes") self.assertFalse("error" in first_reaction) await asyncio.sleep(2) should_be_ignored = await web_client.chat_postMessage( channel=channel_id, text="Hello?", thread_ts=ts) self.assertFalse("error" in should_be_ignored) await asyncio.sleep(2) second_reaction = await web_client.reactions_add( channel=channel_id, timestamp=ts, name="tada") self.assertFalse("error" in second_reaction) await asyncio.sleep(2) self.assertEqual(self.message_count, 1) self.assertEqual(self.reaction_count, 2) finally: if not rtm._stopped: rtm.stop()
def run(): try: rtm_client = RTMClient(token=os.getenv("SLACK_TOKEN")) rtm_client.start() except ClientConnectorError as e: logger.error("Possibly no internet connection available") logger.error(str(e)) time.sleep(5 * 60) exit(1)
def main(): ssl_context = ssl_lib.create_default_context(cafile=certifi.where()) # Real-time messaging client with Slack global rtm_client rtm_client = RTMClient(token=SLACK_TOKEN, ssl=ssl_context) try: print("[SUCCESS] Your bot is running!") rtm_client.start() except: print("[ERROR] Your bot is not running.")
async def test_issue_558(self): channel_id = os.environ[SLACK_SDK_TEST_RTM_TEST_CHANNEL_ID] text = "This message was sent by <https://slack.dev/python-slackclient/|python-slackclient>! (test_issue_558)" self.message_count, self.reaction_count = 0, 0 async def process_messages(**payload): self.logger.debug(payload) self.message_count += 1 await asyncio.sleep(10) # this used to block all other handlers async def process_reactions(**payload): self.logger.debug(payload) self.reaction_count += 1 rtm = RTMClient(token=self.bot_token, run_async=True) RTMClient.on(event="message", callback=process_messages) RTMClient.on(event="reaction_added", callback=process_reactions) web_client = WebClient(token=self.bot_token, run_async=True) message = await web_client.chat_postMessage(channel=channel_id, text=text) self.assertFalse("error" in message) ts = message["ts"] await asyncio.sleep(3) # intentionally not waiting here rtm.start() await asyncio.sleep(3) try: first_reaction = await web_client.reactions_add(channel=channel_id, timestamp=ts, name="eyes") self.assertFalse("error" in first_reaction) await asyncio.sleep(2) message = await web_client.chat_postMessage(channel=channel_id, text=text) self.assertFalse("error" in message) # used to start blocking here # This reaction_add event won't be handled due to a bug second_reaction = await web_client.reactions_add( channel=channel_id, timestamp=ts, name="tada") self.assertFalse("error" in second_reaction) await asyncio.sleep(2) self.assertEqual(self.message_count, 1) self.assertEqual(self.reaction_count, 2) # used to fail finally: if not rtm._stopped: rtm.stop()
class TestRTMClient(unittest.TestCase): """Runs integration tests with real Slack API https://github.com/slackapi/python-slack-sdk/issues/605 """ def setUp(self): self.logger = logging.getLogger(__name__) self.bot_token = os.environ[SLACK_SDK_TEST_CLASSIC_APP_BOT_TOKEN] self.channel_id = os.environ[SLACK_SDK_TEST_RTM_TEST_CHANNEL_ID] self.rtm_client = RTMClient(token=self.bot_token, run_async=False) def tearDown(self): # Reset the decorators by @RTMClient.run_on RTMClient._callbacks = collections.defaultdict(list) @pytest.mark.skipif(condition=is_not_specified(), reason="To avoid rate_limited errors") def test_issue_605(self): self.text = "This message was sent to verify issue #605" self.called = False @RTMClient.run_on(event="message") def process_messages(**payload): self.logger.info(payload) self.called = True def connect(): self.logger.debug("Starting RTM Client...") self.rtm_client.start() t = threading.Thread(target=connect) t.daemon = True try: t.start() self.assertFalse(self.called) time.sleep(3) self.web_client = WebClient( token=self.bot_token, run_async=False, ) new_message = self.web_client.chat_postMessage( channel=self.channel_id, text=self.text) self.assertFalse("error" in new_message) time.sleep(5) self.assertTrue(self.called) finally: t.join(0.3)
def test_issue_530(self): try: rtm_client = RTMClient( token="I am not a token", run_async=False, loop=asyncio.new_event_loop() ) rtm_client.start() self.fail("Raising an error here was expected") except Exception as e: self.assertEqual( "The request to the Slack API failed.\n" "The server responded with: {'ok': False, 'error': 'invalid_auth'}", str(e), ) finally: if not rtm_client._stopped: rtm_client.stop()
async def slack_client_and_sleeps(): # real-time-messaging Slack client client = RTMClient(token=token, run_async=True) sleepy_count_task = asyncio.create_task(sleepy_count("first counter", 1)) sleepy_count_task2 = asyncio.create_task(sleepy_count("second counter", 3)) await asyncio.gather(client.start(), sleepy_count_task, sleepy_count_task2)
class Bellchan: def __init__(self): setup_logger() self.settings = Settings self.rtm_client = RTMClient(token=self.settings.SLACK_API_TOKEN) self.web_client = LegacyWebClient(token=self.settings.SLACK_API_TOKEN) self.schedule = schedule for func in self.scheduled_plugins: func(self, self.schedule, self.handle_schedule_error) logger.info(f'Set schedule function [{func.__name__}]') @property def scheduled_plugins(self): return scheduled_plugins.__all__ def push_message(self, text: str, with_channel: bool = False) -> None: if with_channel: text = f'<!channel> {text}' self.web_client.chat_postMessage( username=Settings.BOT_NAME, icon_url=Settings.BOT_ICON_URL, channel=Settings.DEFAULT_CHANNEL_ID, text=text, ) def handle_schedule_error(self): def receive_func(func): @functools.wraps(func) def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception as e: handle_error(self.web_client, Settings.DEFAULT_CHANNEL_ID, e) return wrapper return receive_func def run(self): Process(target=run_schedule, args=(self,)).start() self.rtm_client.start()
async def slack_client(): # real-time-messaging Slack client client = RTMClient(token=token, run_async=True) await asyncio.gather(client.start())
openRes = client.conversations_open(users=userIds) # openRes = client.conversations_open(users=['U01K53KBBEC', 'U01KAV74U57']) # print(openRes) # send message in the app's channel # response = client.api_call( # api_method='chat.postMessage', # json={'channel': openRes["channel"]["id"], # "text": "Tets for sending message to both Beena and Sachin."} # ) # print(response) # send message each users separately for userId in userIds: response = client.api_call(api_method='chat.postMessage', json={ 'channel': userId, "text": "Tets for sending message." }) # send message as slackbot # response = client.api_call( # api_method='chat.postMessage', # json={'channel': userId, "text": "Hi Beena, This is a test."} # ) # print(response) rtm_client = RTMClient(token=slack_token) rtm_client.start() print("END")
# When a user sends a DM, the event type will be 'message'. # Here we'll link the message callback to the 'message' event. @RTMClient.run_on(event="message") async def message(**payload): """Display the onboarding welcome message after receiving a message that contains "start". """ data = payload["data"] web_client = payload["web_client"] channel_id = data.get("channel") user_id = data.get("user") text = data.get("text") if text and text.lower() == "start": return await start_onboarding(web_client, user_id, channel_id) if __name__ == "__main__": logger = logging.getLogger() logger.setLevel(logging.DEBUG) logger.addHandler(logging.StreamHandler()) ssl_context = ssl_lib.create_default_context(cafile=certifi.where()) slack_token = os.environ["SLACK_BOT_TOKEN"] loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) rtm_client = RTMClient(token=slack_token, ssl=ssl_context, run_async=True, loop=loop) loop.run_until_complete(rtm_client.start())
class TestRTMClient(unittest.TestCase): """Runs integration tests with real Slack API https://github.com/slackapi/python-slack-sdk/issues/569 """ def setUp(self): if not hasattr(self, "logger"): self.logger = logging.getLogger(__name__) self.channel_id = os.environ[SLACK_SDK_TEST_RTM_TEST_CHANNEL_ID] self.bot_token = os.environ[SLACK_SDK_TEST_CLASSIC_APP_BOT_TOKEN] if not hasattr( self, "cpu_monitor") or not TestRTMClient.cpu_monitor.is_alive(): def run_cpu_monitor(self): self.logger.debug("Starting CPU monitor in another thread...") TestRTMClient.cpu_usage = 0 while True: p = psutil.Process(os.getpid()) current_cpu_usage: float = p.cpu_percent(interval=0.5) self.logger.debug(current_cpu_usage) if current_cpu_usage > TestRTMClient.cpu_usage: TestRTMClient.cpu_usage = current_cpu_usage TestRTMClient.cpu_monitor = threading.Thread( target=run_cpu_monitor, args=[self]) TestRTMClient.cpu_monitor.daemon = True TestRTMClient.cpu_monitor.start() self.rtm_client = None self.web_client = None def tearDown(self): # Reset the decorators by @RTMClient.run_on RTMClient._callbacks = collections.defaultdict(list) # Stop the Client if hasattr(self, "rtm_client") and not self.rtm_client._stopped: self.rtm_client.stop() @pytest.mark.skipif(condition=is_not_specified(), reason="To avoid rate_limited errors") def test_cpu_usage(self): self.rtm_client = RTMClient(token=self.bot_token, run_async=False, loop=asyncio.new_event_loop()) self.web_client = WebClient(token=self.bot_token) self.call_count = 0 TestRTMClient.cpu_usage = 0 @RTMClient.run_on(event="message") def send_reply(**payload): self.logger.debug(payload) event = payload["data"] if "text" in event: if not str(event["text"]).startswith("Current CPU usage:"): web_client = payload["web_client"] for i in range(0, 3): new_message = web_client.chat_postMessage( channel=event["channel"], text= f"Current CPU usage: {TestRTMClient.cpu_usage} % (test_cpu_usage)", ) self.logger.debug(new_message) self.call_count += 1 def connect(): self.logger.debug("Starting RTM Client...") self.rtm_client.start() rtm = threading.Thread(target=connect) rtm.daemon = True rtm.start() time.sleep(5) text = "This message was sent by <https://slack.dev/python-slackclient/|python-slackclient>! (test_cpu_usage)" new_message = self.web_client.chat_postMessage(channel=self.channel_id, text=text) self.assertFalse("error" in new_message) time.sleep(5) self.assertLess(TestRTMClient.cpu_usage, 30, "Too high CPU usage detected") self.assertEqual(self.call_count, 3, "The RTM handler failed") # > self.assertLess(TestRTMClient.cpu_usage, 30, "Too high CPU usage detected") # E AssertionError: 100.2 not less than 30 : Too high CPU usage detected # # integration_tests/rtm/test_rtm_client.py:160: AssertionError @async_test async def test_cpu_usage_async(self): self.rtm_client = RTMClient(token=self.bot_token, run_async=True) self.web_client = LegacyWebClient(token=self.bot_token, run_async=True) self.call_count = 0 TestRTMClient.cpu_usage = 0 @RTMClient.run_on(event="message") async def send_reply_async(**payload): self.logger.debug(payload) event = payload["data"] if "text" in event: if not str(event["text"]).startswith("Current CPU usage:"): web_client = payload["web_client"] for i in range(0, 3): new_message = await web_client.chat_postMessage( channel=event["channel"], text= f"Current CPU usage: {TestRTMClient.cpu_usage} % (test_cpu_usage_async)", ) self.logger.debug(new_message) self.call_count += 1 # intentionally not waiting here self.rtm_client.start() await asyncio.sleep(5) text = "This message was sent by <https://slack.dev/python-slackclient/|python-slackclient>! (test_cpu_usage_async)" new_message = await self.web_client.chat_postMessage( channel=self.channel_id, text=text) self.assertFalse("error" in new_message) await asyncio.sleep(5) self.assertLess(TestRTMClient.cpu_usage, 30, "Too high CPU usage detected") self.assertEqual(self.call_count, 3, "The RTM handler failed")
class TestRTMClient(unittest.TestCase): """Runs integration tests with real Slack API https://github.com/slackapi/python-slack-sdk/issues/631 """ def setUp(self): if not hasattr(self, "logger"): self.logger = logging.getLogger(__name__) self.channel_id = os.environ[SLACK_SDK_TEST_RTM_TEST_CHANNEL_ID] self.bot_token = os.environ[SLACK_SDK_TEST_CLASSIC_APP_BOT_TOKEN] def tearDown(self): # Reset the decorators by @RTMClient.run_on RTMClient._callbacks = collections.defaultdict(list) # Stop the Client if hasattr(self, "rtm_client") and not self.rtm_client._stopped: self.rtm_client.stop() @pytest.mark.skipif( condition=is_not_specified(), reason="to avoid rate_limited errors" ) def test_issue_631_sharing_event_loop(self): self.success = None self.text = "This message was sent to verify issue #631" self.rtm_client = RTMClient( token=self.bot_token, run_async=False, loop=asyncio.new_event_loop(), # TODO: this doesn't work without this ) # @RTMClient.run_on(event="message") # def send_reply(**payload): # self.logger.debug(payload) # data = payload['data'] # web_client = payload['web_client'] # web_client._event_loop = self.loop # # Maybe you will also need the following line uncommented # # web_client.run_async = True # # if self.text in data['text']: # channel_id = data['channel'] # thread_ts = data['ts'] # try: # self.success = web_client.chat_postMessage( # channel=channel_id, # text="Thanks!", # thread_ts=thread_ts # ) # except Exception as e: # # slack.rtm.client:client.py:446 When calling '#send_reply()' # # in the 'test_rtm_client' module the following error was raised: This event loop is already running # self.logger.error(traceback.format_exc()) # raise e # Solution (1) for #631 @RTMClient.run_on(event="message") def send_reply(**payload): self.logger.debug(payload) data = payload["data"] web_client = payload["web_client"] try: if "text" in data and self.text in data["text"]: channel_id = data["channel"] thread_ts = data["ts"] self.success = web_client.chat_postMessage( channel=channel_id, text="Thanks!", thread_ts=thread_ts ) except Exception as e: self.logger.error(traceback.format_exc()) raise e def connect(): self.logger.debug("Starting RTM Client...") self.rtm_client.start() t = threading.Thread(target=connect) t.daemon = True t.start() try: self.assertIsNone(self.success) time.sleep(5) self.web_client = WebClient( token=self.bot_token, run_async=False, ) new_message = self.web_client.chat_postMessage( channel=self.channel_id, text=self.text ) self.assertFalse("error" in new_message) time.sleep(5) self.assertIsNotNone(self.success) finally: t.join(0.3) # Solution (2) for #631 @pytest.mark.skipif( condition=is_not_specified(), reason="this is just for reference" ) @async_test async def test_issue_631_sharing_event_loop_async(self): self.success = None self.text = "This message was sent to verify issue #631" # To make run_async=True, the test method needs to be an async function + @async_test decorator self.rtm_client = RTMClient(token=self.bot_token, run_async=True) self.web_client = WebClient(token=self.bot_token, run_async=True) @RTMClient.run_on(event="message") async def send_reply(**payload): self.logger.debug(payload) data = payload["data"] web_client = payload["web_client"] try: if "text" in data and self.text in data["text"]: channel_id = data["channel"] thread_ts = data["ts"] self.success = await web_client.chat_postMessage( channel=channel_id, text="Thanks!", thread_ts=thread_ts ) except Exception as e: self.logger.error(traceback.format_exc()) raise e # intentionally not waiting here self.rtm_client.start() self.assertIsNone(self.success) await asyncio.sleep(5) self.web_client = WebClient( token=self.bot_token, run_async=True, # all need to be async here ) new_message = await self.web_client.chat_postMessage( channel=self.channel_id, text=self.text ) self.assertFalse("error" in new_message) await asyncio.sleep(5) self.assertIsNotNone(self.success)
class TestRTMClient(unittest.TestCase): """Runs integration tests with real Slack API""" def setUp(self): if not hasattr(self, "logger"): self.logger = logging.getLogger(__name__) self.channel_id = os.environ[SLACK_SDK_TEST_RTM_TEST_CHANNEL_ID] self.bot_token = os.environ[SLACK_SDK_TEST_CLASSIC_APP_BOT_TOKEN] def tearDown(self): # Reset the decorators by @RTMClient.run_on RTMClient._callbacks = collections.defaultdict(list) # Stop the Client if hasattr(self, "rtm_client") and not self.rtm_client._stopped: self.rtm_client.stop() def test_basic_operations(self): self.sent_text: str = None self.rtm_client = RTMClient( token=self.bot_token, run_async=False, loop=asyncio.new_event_loop( ), # TODO: this doesn't work without this ) self.web_client = LegacyWebClient(token=self.bot_token) @RTMClient.run_on(event="message") def send_reply(**payload): self.logger.debug(payload) self.sent_text = payload["data"]["text"] def connect(): self.logger.debug("Starting RTM Client...") self.rtm_client.start() t = threading.Thread(target=connect) t.setDaemon(True) t.start() try: self.assertIsNone(self.sent_text) time.sleep(5) text = "This message was sent by <https://slack.dev/python-slackclient/|python-slackclient>! (test_basic_operations)" new_message = self.web_client.chat_postMessage( channel=self.channel_id, text=text) self.assertFalse("error" in new_message) time.sleep(5) self.assertEqual(self.sent_text, text) finally: t.join(0.3) @async_test async def test_basic_operations_async(self): self.sent_text: str = None self.rtm_client = RTMClient(token=self.bot_token, run_async=True) self.async_web_client = LegacyWebClient(token=self.bot_token, run_async=True) @RTMClient.run_on(event="message") async def send_reply(**payload): self.logger.debug(payload) self.sent_text = payload["data"]["text"] # intentionally not waiting here self.rtm_client.start() self.assertIsNone(self.sent_text) await asyncio.sleep(5) text = "This message was sent by <https://slack.dev/python-slackclient/|python-slackclient>! (test_basic_operations_async)" new_message = await self.async_web_client.chat_postMessage( channel=self.channel_id, text=text) self.assertFalse("error" in new_message) await asyncio.sleep(5) self.assertEqual(self.sent_text, text)
class TestRTMClient(unittest.TestCase): """Runs integration tests with real Slack API https://github.com/slackapi/python-slack-sdk/issues/701 """ def setUp(self): self.logger = logging.getLogger(__name__) self.bot_token = os.environ[SLACK_SDK_TEST_CLASSIC_APP_BOT_TOKEN] def tearDown(self): # Reset the decorators by @RTMClient.run_on RTMClient._callbacks = collections.defaultdict(list) # @pytest.mark.skipif(condition=is_not_specified(), reason="to avoid rate_limited errors") @pytest.mark.skip() def test_receiving_all_messages(self): self.rtm_client = RTMClient(token=self.bot_token, loop=asyncio.new_event_loop()) self.web_client = WebClient(token=self.bot_token) self.call_count = 0 @RTMClient.run_on(event="message") def send_reply(**payload): self.logger.debug(payload) web_client, data = payload["web_client"], payload["data"] web_client.reactions_add(channel=data["channel"], timestamp=data["ts"], name="eyes") self.call_count += 1 def connect(): self.logger.debug("Starting RTM Client...") self.rtm_client.start() rtm = threading.Thread(target=connect) rtm.daemon = True rtm.start() time.sleep(3) total_num = 10 sender_completion = [] def sent_bulk_message(): for i in range(total_num): text = f"Sent by <https://slack.dev/python-slackclient/|python-slackclient>! ({i})" self.web_client.chat_postMessage(channel="#random", text=text) time.sleep(0.1) sender_completion.append(True) num_of_senders = 3 senders = [] for sender_num in range(num_of_senders): sender = threading.Thread(target=sent_bulk_message) sender.daemon = True sender.start() senders.append(sender) while len(sender_completion) < num_of_senders: time.sleep(1) expected_call_count = total_num * num_of_senders wait_seconds = 0 max_wait = 20 while self.call_count < expected_call_count and wait_seconds < max_wait: time.sleep(1) wait_seconds += 1 self.assertEqual(total_num * num_of_senders, self.call_count, "The RTM handler failed") @pytest.mark.skipif(condition=is_not_specified(), reason="to avoid rate_limited errors") @async_test async def test_receiving_all_messages_async(self): self.rtm_client = RTMClient(token=self.bot_token, run_async=True) self.web_client = WebClient(token=self.bot_token, run_async=False) self.call_count = 0 @RTMClient.run_on(event="message") async def send_reply(**payload): self.logger.debug(payload) web_client, data = payload["web_client"], payload["data"] await web_client.reactions_add(channel=data["channel"], timestamp=data["ts"], name="eyes") self.call_count += 1 # intentionally not waiting here self.rtm_client.start() await asyncio.sleep(3) total_num = 10 sender_completion = [] def sent_bulk_message(): for i in range(total_num): text = f"Sent by <https://slack.dev/python-slackclient/|python-slackclient>! ({i})" self.web_client.chat_postMessage(channel="#random", text=text) time.sleep(0.1) sender_completion.append(True) num_of_senders = 3 senders = [] for sender_num in range(num_of_senders): sender = threading.Thread(target=sent_bulk_message) sender.daemon = True sender.start() senders.append(sender) while len(sender_completion) < num_of_senders: await asyncio.sleep(1) expected_call_count = total_num * num_of_senders wait_seconds = 0 max_wait = 20 while self.call_count < expected_call_count and wait_seconds < max_wait: await asyncio.sleep(1) wait_seconds += 1 self.assertEqual(total_num * num_of_senders, self.call_count, "The RTM handler failed")
class LowLevelSlackClient(metaclass=Singleton): def __init__(self): _settings, _ = import_settings() slack_api_token = _settings.get('SLACK_API_TOKEN', None) http_proxy = _settings.get('HTTP_PROXY', None) self.rtm_client = RTMClient(token=slack_api_token, proxy=http_proxy) self.web_client = WebClient(token=slack_api_token, proxy=http_proxy) self._bot_info = {} self._users = {} self._channels = {} @staticmethod def get_instance() -> 'LowLevelSlackClient': return LowLevelSlackClient() def _register_user(self, user_response): user = User.from_api_response(user_response) self._users[user.id] = user return user def _register_channel(self, channel_response): channel = Channel.from_api_response(channel_response) self._channels[channel.id] = channel return channel def ping(self): # Ugly hack because some parts of slackclient > 2.0 are async-only (like the ping function) # and Slack Machine isn't async yet loop = asyncio.new_event_loop() result = self.rtm_client.ping() loop.run_until_complete(result) def _on_open(self, **payload): # Set bot info self._bot_info = payload['data']['self'] # Build user cache all_users = call_paginated_endpoint(self.web_client.users_list, 'members') for u in all_users: self._register_user(u) logger.debug("Number of users found: %s" % len(self._users)) logger.debug("Users: %s" % ", ".join([ f"{u.profile.display_name}|{u.profile.real_name}" for u in self._users.values() ])) # Build channel cache all_channels = call_paginated_endpoint( self.web_client.conversations_list, 'channels', types='public_channel,private_channel,mpim,im') for c in all_channels: self._register_channel(c) logger.debug("Number of channels found: %s" % len(self._channels)) logger.debug("Channels: %s" % ", ".join([c.identifier for c in self._channels.values()])) puts("Final initialization of plugins...") for instance, class_name in self._plugins: instance.init_final() show_valid(class_name) def _on_team_join(self, **payload): user = self._register_user(payload['data']['user']) logger.debug("User joined team: %s" % user) def _on_user_change(self, **payload): user = self._register_user(payload['data']['user']) logger.debug("User changed: %s" % user) def _on_channel_created(self, **payload): channel_resp = self.web_client.conversations_info( channel=payload['data']['channel']['id']) channel = self._register_channel(channel_resp['channel']) logger.debug("Channel created: %s" % channel) def _on_channel_updated(self, **payload): data = payload['data'] if isinstance(data['channel'], dict): channel_id = data['channel']['id'] else: channel_id = data['channel'] channel_resp = self.web_client.conversations_info(channel=channel_id) channel = self._register_channel(channel_resp['channel']) logger.debug("Channel updated: %s" % channel) def _on_channel_deleted(self, **payload): channel = self._channels[payload['data']['channel']] del self._channels[payload['data']['channel']] logger.debug("Channel %s deleted" % channel.name) @property def bot_info(self) -> Dict[str, str]: return self._bot_info def start(self, plugins): self._plugins = plugins RTMClient.on(event='open', callback=self._on_open) RTMClient.on(event='team_join', callback=self._on_team_join) RTMClient.on(event='channel_created', callback=self._on_channel_created) RTMClient.on(event='group_joined', callback=self._on_channel_created) RTMClient.on(event='mpim_joined', callback=self._on_channel_created) RTMClient.on(event='im_created', callback=self._on_channel_created) RTMClient.on(event='channel_deleted', callback=self._on_channel_deleted) RTMClient.on(event='im_close', callback=self._on_channel_deleted) RTMClient.on(event='channel_rename', callback=self._on_channel_updated) RTMClient.on(event='channel_archive', callback=self._on_channel_updated) RTMClient.on(event='channel_unarchive', callback=self._on_channel_updated) RTMClient.on(event='user_change', callback=self._on_user_change) self.rtm_client.start() @property def users(self) -> Dict[str, User]: return self._users @property def channels(self) -> Dict[str, Channel]: return self._channels