We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Direct messages to Slack Users is sent via Slack Bot instead of the configured Bot User
<!-- Before you post an issue or if you are unsure about something join our matrix channel https://riot.im/app/#/room/#opsdroid-general:matrix.org and ask away! We are more than happy to help you. -->
# Description
Sending messages directly to Slack Users is sent by the default Slack Bot instead of the configured Bot User.


## Steps to Reproduce
1. Configure Slack Connector in Opsdroid.
2. Send a message to a user instead of a channel by setting the `message.target` value (e.g. @someuser)


## Expected Functionality
The message should be sent to the user via the bot user whose API token we have configured.


## Experienced Functionality
The message is sent to the user via the default Slack Bot.

## Versions
- **Opsdroid version:** master branch in git
- **Python version:** 3.6.8
- **OS/Docker version:** Ubuntu 18.04 LTS

## Configuration File
Please include your version of the configuration file below.

```yaml
# Your code goes here.
welcome-message: true

connectors:
  - name: slack
    api-token: "<Bot OAuth Token>"

skills:
  - name: myskill
    path: /path/to/myskill

```

## Additional Details
Any other details you wish to include such as screenshots, console messages, etc.


<!-- Love opsdroid? Please consider supporting our collective:
 +👉  https://opencollective.com/opsdroid/donate -->


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `opsdroid/connector/slack/__init__.py`
Content:
```
1 """A connector for Slack."""
2 import logging
3 import re
4 import ssl
5 import certifi
6 
7 import slack
8 from emoji import demojize
9 
10 from opsdroid.connector import Connector, register_event
11 from opsdroid.events import Message, Reaction
12 from opsdroid.connector.slack.events import Blocks
13 
14 
15 _LOGGER = logging.getLogger(__name__)
16 
17 
18 class ConnectorSlack(Connector):
19     """A connector for Slack."""
20 
21     def __init__(self, config, opsdroid=None):
22         """Create the connector."""
23         super().__init__(config, opsdroid=opsdroid)
24         _LOGGER.debug(_("Starting Slack connector"))
25         self.name = "slack"
26         self.default_target = config.get("default-room", "#general")
27         self.icon_emoji = config.get("icon-emoji", ":robot_face:")
28         self.token = config["api-token"]
29         self.timeout = config.get("connect-timeout", 10)
30         self.ssl_context = ssl.create_default_context(cafile=certifi.where())
31         self.slack = slack.WebClient(
32             token=self.token, run_async=True, ssl=self.ssl_context
33         )
34         self.slack_rtm = slack.RTMClient(
35             token=self.token, run_async=True, ssl=self.ssl_context
36         )
37         self.websocket = None
38         self.bot_name = config.get("bot-name", "opsdroid")
39         self.auth_info = None
40         self.user_info = None
41         self.bot_id = None
42         self.known_users = {}
43         self.keepalive = None
44         self.reconnecting = False
45         self.listening = True
46         self._message_id = 0
47 
48         # Register callbacks
49         slack.RTMClient.on(event="message", callback=self.process_message)
50 
51     async def connect(self):
52         """Connect to the chat service."""
53         _LOGGER.info(_("Connecting to Slack"))
54 
55         try:
56             # The slack library recommends you call `self.slack_rtm.start()`` here but it
57             # seems to mess with the event loop's signal handlers which breaks opsdroid.
58             # Therefore we need to directly call the private `_connect_and_read` method
59             # instead. This method also blocks so we need to dispatch it to the loop as a task.
60             self.opsdroid.eventloop.create_task(self.slack_rtm._connect_and_read())
61 
62             self.auth_info = (await self.slack.api_call("auth.test")).data
63             self.user_info = (
64                 await self.slack.api_call(
65                     "users.info",
66                     http_verb="GET",
67                     params={"user": self.auth_info["user_id"]},
68                 )
69             ).data
70             self.bot_id = self.user_info["user"]["profile"]["bot_id"]
71 
72             _LOGGER.debug(_("Connected as %s"), self.bot_name)
73             _LOGGER.debug(_("Using icon %s"), self.icon_emoji)
74             _LOGGER.debug(_("Default room is %s"), self.default_target)
75             _LOGGER.info(_("Connected successfully"))
76         except slack.errors.SlackApiError as error:
77             _LOGGER.error(
78                 _(
79                     "Unable to connect to Slack due to %s - "
80                     "The Slack Connector will not be available."
81                 ),
82                 error,
83             )
84         except Exception:
85             await self.disconnect()
86             raise
87 
88     async def disconnect(self):
89         """Disconnect from Slack."""
90         self.slack_rtm.stop()
91         self.listening = False
92 
93     async def listen(self):
94         """Listen for and parse new messages."""
95 
96     async def process_message(self, **payload):
97         """Process a raw message and pass it to the parser."""
98         message = payload["data"]
99 
100         # Ignore message edits
101         if "subtype" in message and message["subtype"] == "message_changed":
102             return
103 
104         # Ignore own messages
105         if (
106             "subtype" in message
107             and message["subtype"] == "bot_message"
108             and message["bot_id"] == self.bot_id
109         ):
110             return
111 
112         # Lookup username
113         _LOGGER.debug(_("Looking up sender username"))
114         try:
115             user_info = await self.lookup_username(message["user"])
116         except ValueError:
117             return
118 
119         # Replace usernames in the message
120         _LOGGER.debug(_("Replacing userids in message with usernames"))
121         message["text"] = await self.replace_usernames(message["text"])
122 
123         await self.opsdroid.parse(
124             Message(
125                 message["text"],
126                 user_info["name"],
127                 message["channel"],
128                 self,
129                 raw_event=message,
130             )
131         )
132 
133     @register_event(Message)
134     async def send_message(self, message):
135         """Respond with a message."""
136         _LOGGER.debug(
137             _("Responding with: '%s' in room  %s"), message.text, message.target
138         )
139         await self.slack.api_call(
140             "chat.postMessage",
141             data={
142                 "channel": message.target,
143                 "text": message.text,
144                 "as_user": False,
145                 "username": self.bot_name,
146                 "icon_emoji": self.icon_emoji,
147             },
148         )
149 
150     @register_event(Blocks)
151     async def send_blocks(self, blocks):
152         """Respond with structured blocks."""
153         _LOGGER.debug(
154             _("Responding with interactive blocks in room  %s"), blocks.target
155         )
156         await self.slack.api_call(
157             "chat.postMessage",
158             data={
159                 "channel": blocks.target,
160                 "username": self.bot_name,
161                 "blocks": blocks.blocks,
162                 "icon_emoji": self.icon_emoji,
163             },
164         )
165 
166     @register_event(Reaction)
167     async def send_reaction(self, reaction):
168         """React to a message."""
169         emoji = demojize(reaction.emoji).replace(":", "")
170         _LOGGER.debug(_("Reacting with: %s"), emoji)
171         try:
172             await self.slack.api_call(
173                 "reactions.add",
174                 data={
175                     "name": emoji,
176                     "channel": reaction.target,
177                     "timestamp": reaction.linked_event.raw_event["ts"],
178                 },
179             )
180         except slack.errors.SlackApiError as error:
181             if "invalid_name" in str(error):
182                 _LOGGER.warning(_("Slack does not support the emoji %s"), emoji)
183             else:
184                 raise
185 
186     async def lookup_username(self, userid):
187         """Lookup a username and cache it."""
188         if userid in self.known_users:
189             user_info = self.known_users[userid]
190         else:
191             response = await self.slack.users_info(user=userid)
192             user_info = response.data["user"]
193             if isinstance(user_info, dict):
194                 self.known_users[userid] = user_info
195             else:
196                 raise ValueError("Returned user is not a dict.")
197         return user_info
198 
199     async def replace_usernames(self, message):
200         """Replace User ID with username in message text."""
201         userids = re.findall(r"\<\@([A-Z0-9]+)(?:\|.+)?\>", message)
202         for userid in userids:
203             user_info = await self.lookup_username(userid)
204             message = message.replace(
205                 "<@{userid}>".format(userid=userid), user_info["name"]
206             )
207         return message
208
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/opsdroid/connector/slack/__init__.py b/opsdroid/connector/slack/__init__.py
--- a/opsdroid/connector/slack/__init__.py
+++ b/opsdroid/connector/slack/__init__.py
@@ -27,6 +27,7 @@
         self.icon_emoji = config.get("icon-emoji", ":robot_face:")
         self.token = config["api-token"]
         self.timeout = config.get("connect-timeout", 10)
+        self.chat_as_user = config.get("chat-as-user", False)
         self.ssl_context = ssl.create_default_context(cafile=certifi.where())
         self.slack = slack.WebClient(
             token=self.token, run_async=True, ssl=self.ssl_context
@@ -141,7 +142,7 @@
             data={
                 "channel": message.target,
                 "text": message.text,
-                "as_user": False,
+                "as_user": self.chat_as_user,
                 "username": self.bot_name,
                 "icon_emoji": self.icon_emoji,
             },
@@ -157,6 +158,7 @@
             "chat.postMessage",
             data={
                 "channel": blocks.target,
+                "as_user": self.chat_as_user,
                 "username": self.bot_name,
                 "blocks": blocks.blocks,
                 "icon_emoji": self.icon_emoji,

{"golden_diff": "diff --git a/opsdroid/connector/slack/__init__.py b/opsdroid/connector/slack/__init__.py\n--- a/opsdroid/connector/slack/__init__.py\n+++ b/opsdroid/connector/slack/__init__.py\n@@ -27,6 +27,7 @@\n         self.icon_emoji = config.get(\"icon-emoji\", \":robot_face:\")\n         self.token = config[\"api-token\"]\n         self.timeout = config.get(\"connect-timeout\", 10)\n+        self.chat_as_user = config.get(\"chat-as-user\", False)\n         self.ssl_context = ssl.create_default_context(cafile=certifi.where())\n         self.slack = slack.WebClient(\n             token=self.token, run_async=True, ssl=self.ssl_context\n@@ -141,7 +142,7 @@\n             data={\n                 \"channel\": message.target,\n                 \"text\": message.text,\n-                \"as_user\": False,\n+                \"as_user\": self.chat_as_user,\n                 \"username\": self.bot_name,\n                 \"icon_emoji\": self.icon_emoji,\n             },\n@@ -157,6 +158,7 @@\n             \"chat.postMessage\",\n             data={\n                 \"channel\": blocks.target,\n+                \"as_user\": self.chat_as_user,\n                 \"username\": self.bot_name,\n                 \"blocks\": blocks.blocks,\n                 \"icon_emoji\": self.icon_emoji,\n", "issue": "Direct messages to Slack Users is sent via Slack Bot instead of the configured Bot User\n<!-- Before you post an issue or if you are unsure about something join our matrix channel https://riot.im/app/#/room/#opsdroid-general:matrix.org and ask away! We are more than happy to help you. -->\r\n# Description\r\nSending messages directly to Slack Users is sent by the default Slack Bot instead of the configured Bot User.\r\n\r\n\r\n## Steps to Reproduce\r\n1. Configure Slack Connector in Opsdroid.\r\n2. Send a message to a user instead of a channel by setting the `message.target` value (e.g. @someuser)\r\n\r\n\r\n## Expected Functionality\r\nThe message should be sent to the user via the bot user whose API token we have configured.\r\n\r\n\r\n## Experienced Functionality\r\nThe message is sent to the user via the default Slack Bot.\r\n\r\n## Versions\r\n- **Opsdroid version:** master branch in git\r\n- **Python version:** 3.6.8\r\n- **OS/Docker version:** Ubuntu 18.04 LTS\r\n\r\n## Configuration File\r\nPlease include your version of the configuration file below.\r\n\r\n```yaml\r\n# Your code goes here.\r\nwelcome-message: true\r\n\r\nconnectors:\r\n  - name: slack\r\n    api-token: \"<Bot OAuth Token>\"\r\n\r\nskills:\r\n  - name: myskill\r\n    path: /path/to/myskill\r\n\r\n```\r\n\r\n## Additional Details\r\nAny other details you wish to include such as screenshots, console messages, etc.\r\n\r\n\r\n<!-- Love opsdroid? Please consider supporting our collective:\r\n +\ud83d\udc49  https://opencollective.com/opsdroid/donate -->\r\n\n", "before_files": [{"content": "\"\"\"A connector for Slack.\"\"\"\nimport logging\nimport re\nimport ssl\nimport certifi\n\nimport slack\nfrom emoji import demojize\n\nfrom opsdroid.connector import Connector, register_event\nfrom opsdroid.events import Message, Reaction\nfrom opsdroid.connector.slack.events import Blocks\n\n\n_LOGGER = logging.getLogger(__name__)\n\n\nclass ConnectorSlack(Connector):\n    \"\"\"A connector for Slack.\"\"\"\n\n    def __init__(self, config, opsdroid=None):\n        \"\"\"Create the connector.\"\"\"\n        super().__init__(config, opsdroid=opsdroid)\n        _LOGGER.debug(_(\"Starting Slack connector\"))\n        self.name = \"slack\"\n        self.default_target = config.get(\"default-room\", \"#general\")\n        self.icon_emoji = config.get(\"icon-emoji\", \":robot_face:\")\n        self.token = config[\"api-token\"]\n        self.timeout = config.get(\"connect-timeout\", 10)\n        self.ssl_context = ssl.create_default_context(cafile=certifi.where())\n        self.slack = slack.WebClient(\n            token=self.token, run_async=True, ssl=self.ssl_context\n        )\n        self.slack_rtm = slack.RTMClient(\n            token=self.token, run_async=True, ssl=self.ssl_context\n        )\n        self.websocket = None\n        self.bot_name = config.get(\"bot-name\", \"opsdroid\")\n        self.auth_info = None\n        self.user_info = None\n        self.bot_id = None\n        self.known_users = {}\n        self.keepalive = None\n        self.reconnecting = False\n        self.listening = True\n        self._message_id = 0\n\n        # Register callbacks\n        slack.RTMClient.on(event=\"message\", callback=self.process_message)\n\n    async def connect(self):\n        \"\"\"Connect to the chat service.\"\"\"\n        _LOGGER.info(_(\"Connecting to Slack\"))\n\n        try:\n            # The slack library recommends you call `self.slack_rtm.start()`` here but it\n            # seems to mess with the event loop's signal handlers which breaks opsdroid.\n            # Therefore we need to directly call the private `_connect_and_read` method\n            # instead. This method also blocks so we need to dispatch it to the loop as a task.\n            self.opsdroid.eventloop.create_task(self.slack_rtm._connect_and_read())\n\n            self.auth_info = (await self.slack.api_call(\"auth.test\")).data\n            self.user_info = (\n                await self.slack.api_call(\n                    \"users.info\",\n                    http_verb=\"GET\",\n                    params={\"user\": self.auth_info[\"user_id\"]},\n                )\n            ).data\n            self.bot_id = self.user_info[\"user\"][\"profile\"][\"bot_id\"]\n\n            _LOGGER.debug(_(\"Connected as %s\"), self.bot_name)\n            _LOGGER.debug(_(\"Using icon %s\"), self.icon_emoji)\n            _LOGGER.debug(_(\"Default room is %s\"), self.default_target)\n            _LOGGER.info(_(\"Connected successfully\"))\n        except slack.errors.SlackApiError as error:\n            _LOGGER.error(\n                _(\n                    \"Unable to connect to Slack due to %s - \"\n                    \"The Slack Connector will not be available.\"\n                ),\n                error,\n            )\n        except Exception:\n            await self.disconnect()\n            raise\n\n    async def disconnect(self):\n        \"\"\"Disconnect from Slack.\"\"\"\n        self.slack_rtm.stop()\n        self.listening = False\n\n    async def listen(self):\n        \"\"\"Listen for and parse new messages.\"\"\"\n\n    async def process_message(self, **payload):\n        \"\"\"Process a raw message and pass it to the parser.\"\"\"\n        message = payload[\"data\"]\n\n        # Ignore message edits\n        if \"subtype\" in message and message[\"subtype\"] == \"message_changed\":\n            return\n\n        # Ignore own messages\n        if (\n            \"subtype\" in message\n            and message[\"subtype\"] == \"bot_message\"\n            and message[\"bot_id\"] == self.bot_id\n        ):\n            return\n\n        # Lookup username\n        _LOGGER.debug(_(\"Looking up sender username\"))\n        try:\n            user_info = await self.lookup_username(message[\"user\"])\n        except ValueError:\n            return\n\n        # Replace usernames in the message\n        _LOGGER.debug(_(\"Replacing userids in message with usernames\"))\n        message[\"text\"] = await self.replace_usernames(message[\"text\"])\n\n        await self.opsdroid.parse(\n            Message(\n                message[\"text\"],\n                user_info[\"name\"],\n                message[\"channel\"],\n                self,\n                raw_event=message,\n            )\n        )\n\n    @register_event(Message)\n    async def send_message(self, message):\n        \"\"\"Respond with a message.\"\"\"\n        _LOGGER.debug(\n            _(\"Responding with: '%s' in room  %s\"), message.text, message.target\n        )\n        await self.slack.api_call(\n            \"chat.postMessage\",\n            data={\n                \"channel\": message.target,\n                \"text\": message.text,\n                \"as_user\": False,\n                \"username\": self.bot_name,\n                \"icon_emoji\": self.icon_emoji,\n            },\n        )\n\n    @register_event(Blocks)\n    async def send_blocks(self, blocks):\n        \"\"\"Respond with structured blocks.\"\"\"\n        _LOGGER.debug(\n            _(\"Responding with interactive blocks in room  %s\"), blocks.target\n        )\n        await self.slack.api_call(\n            \"chat.postMessage\",\n            data={\n                \"channel\": blocks.target,\n                \"username\": self.bot_name,\n                \"blocks\": blocks.blocks,\n                \"icon_emoji\": self.icon_emoji,\n            },\n        )\n\n    @register_event(Reaction)\n    async def send_reaction(self, reaction):\n        \"\"\"React to a message.\"\"\"\n        emoji = demojize(reaction.emoji).replace(\":\", \"\")\n        _LOGGER.debug(_(\"Reacting with: %s\"), emoji)\n        try:\n            await self.slack.api_call(\n                \"reactions.add\",\n                data={\n                    \"name\": emoji,\n                    \"channel\": reaction.target,\n                    \"timestamp\": reaction.linked_event.raw_event[\"ts\"],\n                },\n            )\n        except slack.errors.SlackApiError as error:\n            if \"invalid_name\" in str(error):\n                _LOGGER.warning(_(\"Slack does not support the emoji %s\"), emoji)\n            else:\n                raise\n\n    async def lookup_username(self, userid):\n        \"\"\"Lookup a username and cache it.\"\"\"\n        if userid in self.known_users:\n            user_info = self.known_users[userid]\n        else:\n            response = await self.slack.users_info(user=userid)\n            user_info = response.data[\"user\"]\n            if isinstance(user_info, dict):\n                self.known_users[userid] = user_info\n            else:\n                raise ValueError(\"Returned user is not a dict.\")\n        return user_info\n\n    async def replace_usernames(self, message):\n        \"\"\"Replace User ID with username in message text.\"\"\"\n        userids = re.findall(r\"\\<\\@([A-Z0-9]+)(?:\\|.+)?\\>\", message)\n        for userid in userids:\n            user_info = await self.lookup_username(userid)\n            message = message.replace(\n                \"<@{userid}>\".format(userid=userid), user_info[\"name\"]\n            )\n        return message\n", "path": "opsdroid/connector/slack/__init__.py"}], "after_files": [{"content": "\"\"\"A connector for Slack.\"\"\"\nimport logging\nimport re\nimport ssl\nimport certifi\n\nimport slack\nfrom emoji import demojize\n\nfrom opsdroid.connector import Connector, register_event\nfrom opsdroid.events import Message, Reaction\nfrom opsdroid.connector.slack.events import Blocks\n\n\n_LOGGER = logging.getLogger(__name__)\n\n\nclass ConnectorSlack(Connector):\n    \"\"\"A connector for Slack.\"\"\"\n\n    def __init__(self, config, opsdroid=None):\n        \"\"\"Create the connector.\"\"\"\n        super().__init__(config, opsdroid=opsdroid)\n        _LOGGER.debug(_(\"Starting Slack connector\"))\n        self.name = \"slack\"\n        self.default_target = config.get(\"default-room\", \"#general\")\n        self.icon_emoji = config.get(\"icon-emoji\", \":robot_face:\")\n        self.token = config[\"api-token\"]\n        self.timeout = config.get(\"connect-timeout\", 10)\n        self.chat_as_user = config.get(\"chat-as-user\", False)\n        self.ssl_context = ssl.create_default_context(cafile=certifi.where())\n        self.slack = slack.WebClient(\n            token=self.token, run_async=True, ssl=self.ssl_context\n        )\n        self.slack_rtm = slack.RTMClient(\n            token=self.token, run_async=True, ssl=self.ssl_context\n        )\n        self.websocket = None\n        self.bot_name = config.get(\"bot-name\", \"opsdroid\")\n        self.auth_info = None\n        self.user_info = None\n        self.bot_id = None\n        self.known_users = {}\n        self.keepalive = None\n        self.reconnecting = False\n        self.listening = True\n        self._message_id = 0\n\n        # Register callbacks\n        slack.RTMClient.on(event=\"message\", callback=self.process_message)\n\n    async def connect(self):\n        \"\"\"Connect to the chat service.\"\"\"\n        _LOGGER.info(_(\"Connecting to Slack\"))\n\n        try:\n            # The slack library recommends you call `self.slack_rtm.start()`` here but it\n            # seems to mess with the event loop's signal handlers which breaks opsdroid.\n            # Therefore we need to directly call the private `_connect_and_read` method\n            # instead. This method also blocks so we need to dispatch it to the loop as a task.\n            self.opsdroid.eventloop.create_task(self.slack_rtm._connect_and_read())\n\n            self.auth_info = (await self.slack.api_call(\"auth.test\")).data\n            self.user_info = (\n                await self.slack.api_call(\n                    \"users.info\",\n                    http_verb=\"GET\",\n                    params={\"user\": self.auth_info[\"user_id\"]},\n                )\n            ).data\n            self.bot_id = self.user_info[\"user\"][\"profile\"][\"bot_id\"]\n\n            _LOGGER.debug(_(\"Connected as %s\"), self.bot_name)\n            _LOGGER.debug(_(\"Using icon %s\"), self.icon_emoji)\n            _LOGGER.debug(_(\"Default room is %s\"), self.default_target)\n            _LOGGER.info(_(\"Connected successfully\"))\n        except slack.errors.SlackApiError as error:\n            _LOGGER.error(\n                _(\n                    \"Unable to connect to Slack due to %s - \"\n                    \"The Slack Connector will not be available.\"\n                ),\n                error,\n            )\n        except Exception:\n            await self.disconnect()\n            raise\n\n    async def disconnect(self):\n        \"\"\"Disconnect from Slack.\"\"\"\n        self.slack_rtm.stop()\n        self.listening = False\n\n    async def listen(self):\n        \"\"\"Listen for and parse new messages.\"\"\"\n\n    async def process_message(self, **payload):\n        \"\"\"Process a raw message and pass it to the parser.\"\"\"\n        message = payload[\"data\"]\n\n        # Ignore message edits\n        if \"subtype\" in message and message[\"subtype\"] == \"message_changed\":\n            return\n\n        # Ignore own messages\n        if (\n            \"subtype\" in message\n            and message[\"subtype\"] == \"bot_message\"\n            and message[\"bot_id\"] == self.bot_id\n        ):\n            return\n\n        # Lookup username\n        _LOGGER.debug(_(\"Looking up sender username\"))\n        try:\n            user_info = await self.lookup_username(message[\"user\"])\n        except ValueError:\n            return\n\n        # Replace usernames in the message\n        _LOGGER.debug(_(\"Replacing userids in message with usernames\"))\n        message[\"text\"] = await self.replace_usernames(message[\"text\"])\n\n        await self.opsdroid.parse(\n            Message(\n                message[\"text\"],\n                user_info[\"name\"],\n                message[\"channel\"],\n                self,\n                raw_event=message,\n            )\n        )\n\n    @register_event(Message)\n    async def send_message(self, message):\n        \"\"\"Respond with a message.\"\"\"\n        _LOGGER.debug(\n            _(\"Responding with: '%s' in room  %s\"), message.text, message.target\n        )\n        await self.slack.api_call(\n            \"chat.postMessage\",\n            data={\n                \"channel\": message.target,\n                \"text\": message.text,\n                \"as_user\": self.chat_as_user,\n                \"username\": self.bot_name,\n                \"icon_emoji\": self.icon_emoji,\n            },\n        )\n\n    @register_event(Blocks)\n    async def send_blocks(self, blocks):\n        \"\"\"Respond with structured blocks.\"\"\"\n        _LOGGER.debug(\n            _(\"Responding with interactive blocks in room  %s\"), blocks.target\n        )\n        await self.slack.api_call(\n            \"chat.postMessage\",\n            data={\n                \"channel\": blocks.target,\n                \"as_user\": self.chat_as_user,\n                \"username\": self.bot_name,\n                \"blocks\": blocks.blocks,\n                \"icon_emoji\": self.icon_emoji,\n            },\n        )\n\n    @register_event(Reaction)\n    async def send_reaction(self, reaction):\n        \"\"\"React to a message.\"\"\"\n        emoji = demojize(reaction.emoji).replace(\":\", \"\")\n        _LOGGER.debug(_(\"Reacting with: %s\"), emoji)\n        try:\n            await self.slack.api_call(\n                \"reactions.add\",\n                data={\n                    \"name\": emoji,\n                    \"channel\": reaction.target,\n                    \"timestamp\": reaction.linked_event.raw_event[\"ts\"],\n                },\n            )\n        except slack.errors.SlackApiError as error:\n            if \"invalid_name\" in str(error):\n                _LOGGER.warning(_(\"Slack does not support the emoji %s\"), emoji)\n            else:\n                raise\n\n    async def lookup_username(self, userid):\n        \"\"\"Lookup a username and cache it.\"\"\"\n        if userid in self.known_users:\n            user_info = self.known_users[userid]\n        else:\n            response = await self.slack.users_info(user=userid)\n            user_info = response.data[\"user\"]\n            if isinstance(user_info, dict):\n                self.known_users[userid] = user_info\n            else:\n                raise ValueError(\"Returned user is not a dict.\")\n        return user_info\n\n    async def replace_usernames(self, message):\n        \"\"\"Replace User ID with username in message text.\"\"\"\n        userids = re.findall(r\"\\<\\@([A-Z0-9]+)(?:\\|.+)?\\>\", message)\n        for userid in userids:\n            user_info = await self.lookup_username(userid)\n            message = message.replace(\n                \"<@{userid}>\".format(userid=userid), user_info[\"name\"]\n            )\n        return message\n", "path": "opsdroid/connector/slack/__init__.py"}]}