@hubot-friends/hubot-slack 0.0.0-development

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/.github/CODE_OF_CONDUCT.md +11 -0
  2. package/.github/contributing.md +60 -0
  3. package/.github/issue_template.md +48 -0
  4. package/.github/maintainers_guide.md +91 -0
  5. package/.github/pull_request_template.md +8 -0
  6. package/.github/workflows/ci-build.yml +74 -0
  7. package/LICENSE +22 -0
  8. package/README.md +29 -0
  9. package/docs/Gemfile +2 -0
  10. package/docs/README.md +15 -0
  11. package/docs/_config.yml +29 -0
  12. package/docs/_includes/analytics.html +7 -0
  13. package/docs/_includes/head.html +33 -0
  14. package/docs/_includes/page_header.html +20 -0
  15. package/docs/_includes/side_nav.html +22 -0
  16. package/docs/_includes/tag_manager.html +13 -0
  17. package/docs/_layouts/changelog.html +15 -0
  18. package/docs/_layouts/default.html +47 -0
  19. package/docs/_layouts/page.html +10 -0
  20. package/docs/_pages/FAQ.md +63 -0
  21. package/docs/_pages/about.md +16 -0
  22. package/docs/_pages/advanced_usage.md +102 -0
  23. package/docs/_pages/auth.md +44 -0
  24. package/docs/_pages/basic_usage.md +302 -0
  25. package/docs/_pages/changelog.html +17 -0
  26. package/docs/_pages/upgrading.md +49 -0
  27. package/docs/_posts/2016-07-15-v4.0.0.md +14 -0
  28. package/docs/_posts/2016-07-19-v4.0.1.md +5 -0
  29. package/docs/_posts/2016-08-03-v4.0.2.md +4 -0
  30. package/docs/_posts/2016-09-12-v4.0.3.md +8 -0
  31. package/docs/_posts/2016-09-12-v4.0.4.md +4 -0
  32. package/docs/_posts/2016-09-14-v4.0.5.md +4 -0
  33. package/docs/_posts/2016-09-21-v4.1.0.md +4 -0
  34. package/docs/_posts/2016-10-12-v4.2.0.md +4 -0
  35. package/docs/_posts/2016-10-12-v4.2.1.md +4 -0
  36. package/docs/_posts/2016-11-05-v4.2.2.md +8 -0
  37. package/docs/_posts/2017-01-05-v4.3.0.md +5 -0
  38. package/docs/_posts/2017-01-09-v4.3.1.md +5 -0
  39. package/docs/_posts/2017-02-15-v4.3.2.md +5 -0
  40. package/docs/_posts/2017-02-17-v4.3.3.md +4 -0
  41. package/docs/_posts/2017-03-29-v4.3.4.md +5 -0
  42. package/docs/_posts/2017-08-24-v4.4.0.md +7 -0
  43. package/docs/_posts/2018-06-08-v4.5.0.md +13 -0
  44. package/docs/_posts/2018-06-14-v4.5.1.md +4 -0
  45. package/docs/_posts/2018-07-03-v4.5.2.md +5 -0
  46. package/docs/_posts/2018-07-17-v4.5.3.md +12 -0
  47. package/docs/_posts/2018-08-10-v4.5.4.md +7 -0
  48. package/docs/_posts/2018-10-01-v4.5.5.md +7 -0
  49. package/docs/_posts/2018-12-21-v4.6.0.md +6 -0
  50. package/docs/_posts/2019-04-29-v4.7.0.md +6 -0
  51. package/docs/_posts/2019-04-30-v4.7.1.md +5 -0
  52. package/docs/_posts/2020-04-03-v4.7.2.md +6 -0
  53. package/docs/_posts/2020-05-19-v4.8.0.md +10 -0
  54. package/docs/_posts/2020-10-19-v4.8.1.md +7 -0
  55. package/docs/_posts/2021-01-26-v4.9.0.md +8 -0
  56. package/docs/_posts/2022-01-12-v4.10.0.md +8 -0
  57. package/docs/index.md +93 -0
  58. package/docs/styles/docs.css +37 -0
  59. package/package.json +50 -0
  60. package/slack.js +20 -0
  61. package/src/SlackAdapter.mjs +302 -0
  62. package/src/SlackAdapter.test.mjs +342 -0
  63. package/src/bot.js +526 -0
  64. package/src/client.js +445 -0
  65. package/src/extensions.js +82 -0
  66. package/src/mention.js +15 -0
  67. package/src/message.js +307 -0
  68. package/src/testing.mjs +24 -0
  69. package/test/bot.js +769 -0
  70. package/test/client.js +446 -0
  71. package/test/message.js +329 -0
  72. package/test/stubs.js +388 -0
@@ -0,0 +1,16 @@
1
+ ---
2
+ layout: page
3
+ title: About
4
+ permalink: /about
5
+ order: 9999
6
+ ---
7
+ # {{ site.product_name }}
8
+
9
+ {{ site.description }}
10
+
11
+ {{ site.product_name }} is proudly maintained with :sparkling_heart: by the Slack Developer Tools team
12
+
13
+ * [License](https://github.com/{{ site.github_username }}/{{ site.repo_name }}/blob/master/LICENSE)
14
+ * [Code of Conduct](https://slackhq.github.io/code-of-conduct)
15
+ * [Contributing](https://github.com/{{ site.github_username }}/{{ site.repo_name }}/blob/master/.github/contributing.md)
16
+ * [Contributor License Agreement](https://cla-assistant.io/slackapi/hubot-slack)
@@ -0,0 +1,102 @@
1
+ ---
2
+ layout: page
3
+ title: Advanced Usage
4
+ permalink: /advanced_usage
5
+ order: 5
6
+ headings:
7
+ - title: Customizing rtm.start options
8
+ - title: Customizing the RTM Client
9
+ - title: Activate logging for debugging
10
+ - title: Accessing more API methods and distribution
11
+ - title: Running Hubot behind an HTTP Proxy
12
+ - title: Customizing for shared channels
13
+ ---
14
+
15
+ ## Customizing rtm.start options
16
+
17
+ Under the hood, each Hubot using this adapter is connected to Slack using the [RTM API](https://api.slack.com/rtm). A
18
+ connection to the RTM API is initiated using [`rtm.start`](https://api.slack.com/methods/rtm.start).
19
+ By default, the adapter calls this method with only the required `token` parameter. If you have more specialized needs,
20
+ such as opting into MPIM data, you can add additional parameters to that Web API call by setting an environment
21
+ variable. The variable is called `HUBOT_SLACK_RTM_START_OPTS`, and its value should be a JSON-encoded string with
22
+ the additional parameters as key-value pairs. Here is an example of running hubot with that environment variable set:
23
+
24
+ ```
25
+ $ HUBOT_SLACK_TOKEN=xoxb-xxxxx HUBOT_SLACK_RTM_START_OPTS='{ "mpim_aware": true }' ./bin/hubot --adapter slack
26
+ ```
27
+
28
+ ## Customizing the RTM Client
29
+
30
+ The RTM connection is handled by the `RTMClient` class from our handy
31
+ **Slack Developer Kit for Node.js version 3**. By default, the adapter instantiates the client with the required
32
+ `token` parameter, but more options are available. You can customize the options for the `RTMClient` instance by setting
33
+ an environment variable. The variable is called `HUBOT_SLACK_RTM_CLIENT_OPTS`, and its value should be a JSON-encoded
34
+ string with the additional parameters as key-value pairs. Note that not every option can only be set to JSON-encodable
35
+ values; you won't be able to create an instance of `SlackDataStore` and pass it in via a JSON string but you can set the
36
+ option to `false` to opt out of using a Data Store (not recommended). Here is an example of running hubot with a custom
37
+ retry configuration:
38
+
39
+ ```
40
+ $ HUBOT_SLACK_TOKEN=xoxb-xxxxx HUBOT_SLACK_RTM_CLIENT_OPTS='{ "retryConfig": { "retries": 20 } }' ./bin/hubot --adapter slack
41
+ ```
42
+
43
+ ## Activate logging for debugging
44
+
45
+ Hubot has a flag for setting a log level, called `HUBOT_LOG_LEVEL`. This adapter peforms all of its logging through
46
+ Hubot, so setting it to its most detailed level, `debug`, can give you much more detailed information about activity
47
+ at runtime. Here is an example of running hubot with its log level set to `debug`:
48
+
49
+ ```
50
+ $ HUBOT_SLACK_TOKEN=xoxb-xxxxx HUBOT_LOG_LEVEL=debug ./bin/hubot --adapter slack
51
+ ```
52
+
53
+ The underlying **Slack Developer Kit for Node.js** can also be supplied with a log level to get _even more_ information
54
+ at runtime. Here is an example of combining both of these options:
55
+
56
+ ```
57
+ $ HUBOT_SLACK_TOKEN=xoxb-xxxxx HUBOT_LOG_LEVEL=debug HUBOT_SLACK_RTM_CLIENT_OPTS='{ "logLevel": "debug" }' ./bin/hubot --adapter slack
58
+ ```
59
+
60
+ ## Accessing more API methods and distribution
61
+
62
+ You might find your Hubot unable to access a Web API method. For some methods, you can resolve this by transitioning
63
+ from an App Bot to a Custom Bot (these methods are [listed here](https://api.slack.com/bot-users#bot_methods)). If the
64
+ method isn't available to a Custom Bot, you'll have to use an App Bot and also manage a new token.
65
+
66
+ You will also need to manage a new token if you're considering distributing your Hubot powered app in the App Directory.
67
+
68
+ Start by finding the new scope that your app will require. Required scopes are specified on the documentation for each
69
+ [Web API method](https://api.slack.com/methods). Add this scope to your app on the "OAuth and Permissions" page of your
70
+ app configuration. Once you save the changes, you need to install the app on your development workspace once again.
71
+
72
+ After installing the app and authorizing the new scope, you'll notice a new **OAuth Access Token** (begins with `xoxp`).
73
+ This is the new token that you'll need to manage. We recommend putting the new token in another environment variable,
74
+ and using it to initialize a new `WebClient` object, as described in
75
+ [Using the Slack Web API]({{ site.baseurl }}{% link _pages/basic_usage.md %}#{{ "Using the Slack Web API" | slugify }}). For
76
+ example, if you put the new token in an environment variable called `SLACK_OAUTH_TOKEN`, you'd simply change the
77
+ initialization of the `WebClient` object to the following:
78
+
79
+ ```javascript
80
+ const web = new WebClient(process.env.SLACK_OAUTH_TOKEN)
81
+ ```
82
+
83
+ ## Running Hubot behind an HTTP Proxy
84
+
85
+ You might find the need to run Hubot inside a firewall, where the internet is only accessible via a specific proxy.
86
+ Have no fear, environment variable configuration is here. Just add the `https_proxy` environment variable to your
87
+ startup (we'll just do this on the command line for this example) with the address and authentication information of
88
+ your proxy.
89
+
90
+ ```
91
+ $ https_proxy="http://user:pass@localhost:8888" HUBOT_SLACK_TOKEN=xoxb-xxxxx ./bin/hubot --adapter slack
92
+ ```
93
+
94
+ ## Customizing for shared channels
95
+
96
+ Generally, it's not supposed to invite Hubot to external shared channels. That said, the situation may arise regardless of intention.
97
+
98
+ If your workspace admins would like to surely turn off Hubot's reactions to other workspace users, set `INSTALLED_TEAM_ONLY` env variable as `true`. With this option, this adapter reacts to only the messages generated by its own installed workspace users while it skips all from other workspaces.
99
+
100
+ ```
101
+ $ HUBOT_SLACK_TOKEN=xoxb-xxxxx INSTALLED_TEAM_ONLY=true ./bin/hubot --adapter slack
102
+ ```
@@ -0,0 +1,44 @@
1
+ ---
2
+ layout: page
3
+ title: Tokens & Authentication
4
+ permalink: /auth
5
+ order: 2
6
+ hidden: true
7
+ headings:
8
+ - title: Handling tokens and other sensitive data
9
+ ---
10
+
11
+ ## Handling tokens and other sensitive data
12
+
13
+ Slack tokens are the keys to your—or your customers'—teams. Keep them secret. Keep them safe. One way to do that is
14
+ to never explicitly hardcode them.
15
+
16
+ Try to avoid this when possible:
17
+
18
+ ```js
19
+ var token = 'xoxp-abc-1232';
20
+ ```
21
+
22
+ If you commit this code to GitHub, the world gains access to this token's team. Rather, we recommend you pass tokens as
23
+ environment variables, or persist them in a database that is accessed at runtime. You can add a token to the
24
+ environment by starting your app as:
25
+
26
+ ```bash
27
+ SLACK_API_TOKEN=xoxp-abc-123 node index.js
28
+ ```
29
+
30
+ You can then get the token in your code simply:
31
+
32
+ ```js
33
+ var token = process.env.SLACK_API_TOKEN || '';
34
+ ```
35
+
36
+ This will ensure that your app has a Slack token before it proceeds. If it doesn't, it will set a default empty string
37
+ for the token, which will cause calls to the Web API to fail (which is what we want).
38
+
39
+ You can use the same technique for other kinds of sensitive data that ne'er-do-wells could use in nefarious ways, including
40
+
41
+ * Incoming webhook URLs
42
+ * Slash command verification tokens
43
+ * Bot verification tokens
44
+ * App client ids and client secrets
@@ -0,0 +1,302 @@
1
+ ---
2
+ layout: page
3
+ title: Basic Usage
4
+ permalink: /basic_usage
5
+ order: 4
6
+ headings:
7
+ - title: Listening for a message
8
+ - title: Messages directed to your Hubot
9
+ - title: Sending a response
10
+ - title: User and conversation mentions
11
+ - title: Using the Slack Web API
12
+ - title: Working with threads
13
+ - title: Message reactions
14
+ - title: Presence changes
15
+ - title: Send a message to a different channel
16
+ - title: Text formatting and raw messages
17
+ ---
18
+
19
+ Most Hubots are designed to react to user input – a user makes a request, and Hubot responds, often after going out
20
+ into the world to trigger some action (building your code, deploying to production, and so on). Many of the tasks
21
+ you'd like to accomplish are already well documented in the [official Hubot documentation](https://hubot.github.com/docs/).
22
+ Nevertheless, we'll cover the basics, as well as some interesting Slack-specific use cases.
23
+
24
+ --------
25
+
26
+ ## Listening for a message
27
+
28
+ You can listen for messages in any channel that your Hubot has been invited into very simply, by using `robot.hear` with
29
+ a RegExp to match against. Any message that matches the RegExp will trigger the function.
30
+
31
+ ```javascript
32
+ module.exports = robot => // Any message that contains "badger" will trigger the following function
33
+ robot.hear(
34
+ /badger/i,
35
+ res => // res.message is a SlackTextMessage instance that represents the incoming message Hubot just heard
36
+ robot.logger.debug(`Received message ${res.message.text}`)
37
+ );
38
+ ```
39
+
40
+ Hubot will only hear messages in converastions where it is a member. A human must invite Hubot into conversations
41
+ (shortcut: `/invite @username`).
42
+
43
+ --------
44
+
45
+ ## Messages directed to your Hubot
46
+
47
+ If you want to specifically listen for messages that mention your Hubot, use the `robot.respond` method. You can also
48
+ be more specific using a RegExp (or don't be more specific, `/.*/` will match all messages).
49
+
50
+ ```javascript
51
+ module.exports = robot => // Any message that contains "badger" and is directed at Hubot (in a DM or starting with its name)
52
+ // will trigger the following function
53
+ robot.respond(
54
+ /badger/i,
55
+ res => robot.logger.debug(`Received message ${res.message.text}`)
56
+ );
57
+ ```
58
+
59
+ --------
60
+
61
+ ## Sending a response
62
+
63
+ Responding to a message is straightforward, regardless of whether the message was sent to your Hubot specifically or to
64
+ anyone in general.
65
+
66
+ ```javascript
67
+ module.exports = robot => robot.hear(/badger/i, res => // Hubot sends a response to the same channel it heard the incoming message
68
+ res.send("Yes, more badgers please!"));
69
+ ```
70
+
71
+ --------
72
+
73
+ ## User and conversation mentions
74
+
75
+ When your Hubot hears a message, it might contain mentions of other users, channels, or groups. The `text` property is
76
+ pretty and human-readable. But this isn't great for scripting because
77
+ [usernames are deprecated](https://api.slack.com/changelog/2017-09-the-one-about-usernames), and display names and
78
+ conversation names can change. What you really want is an ID; it's stable to store and gives your Hubot an easy way to
79
+ write mentions that have the user's preferred display name.
80
+
81
+ Each incoming message has a `mentions` array that contains the ID and any other information known about the user or
82
+ conversation that was mentioned.
83
+
84
+ ```javascript
85
+ mmodule.exports = function(robot) {
86
+ // A map of user IDs to scores
87
+ const thank_scores = {};
88
+
89
+ return robot.hear(/thanks/i, function(res) {
90
+ // filter mentions to just user mentions
91
+ const user_mentions = (Array.from(res.message.mentions).filter((mention) => mention.type === "user"));
92
+
93
+ // when there are user mentions...
94
+ if (user_mentions.length > 0) {
95
+ let response_text = "";
96
+
97
+ // process each mention
98
+ for (let { id } of Array.from(user_mentions)) {
99
+ // increment the thank score
100
+ thank_scores[id] = (thank_scores[id] != null) ? (thank_scores[id] + 1) : 1;
101
+ // show the total score in the message with a properly formatted mention (uses display name)
102
+ response_text += `<@${id}> has been thanked ${thank_scores[id]} times!\n`;
103
+ }
104
+
105
+ // send the response
106
+ return res.send(response_text);
107
+ }
108
+ });
109
+ };
110
+ ```
111
+
112
+ --------
113
+
114
+ ## Using the Slack Web API
115
+
116
+ You can access the [Slack Web API](https://api.slack.com/web_api) from your Hubot. Start by installing the
117
+ [Slack Developer Kit for Node.js](https://slackapi.github.io/node-slack-sdk/) package into your Hubot project:
118
+
119
+ ```
120
+ npm install --save @slack/client
121
+ ```
122
+
123
+ Next, modify your script to instatiate a `WebClient` object using the same token your Hubot used to connect.
124
+
125
+ ```javascript
126
+ // Import the Slack Developer Kit
127
+ const {WebClient} = require("@slack/client");
128
+
129
+ module.exports = function(robot) {
130
+ let web;
131
+ return web = new WebClient(robot.adapter.options.token);
132
+ };
133
+ ```
134
+
135
+ Finally, anytime you'd like to call a Web API method, call it like a method on `web`.
136
+
137
+ ```javascript
138
+ // Import the Slack Developer Kit
139
+ const {WebClient} = require("@slack/client");
140
+
141
+ module.exports = function(robot) {
142
+ const web = new WebClient(robot.adapter.options.token);
143
+
144
+ return robot.hear(/test/i, res => web.api.test()
145
+ .then(() => res.send("Your connection to the Slack API is working!"))
146
+ .catch(error => res.send("Your connection to the Slack API failed :(")));
147
+ };
148
+ ```
149
+
150
+ You only have access to the Web API methods that your bot token is authorized to use. Depending on
151
+ [how you installed Hubot]({{ site.baseurl }}{% link index.md %}#{{ "Getting a Slack token" | slugify }}), the
152
+ exact list of methods is either those checked for Custom Bots or App Bots in the
153
+ [bot methods table](https://api.slack.com/bot-users#bot_methods). If you have an App Bot and need to access a method
154
+ only available to a Custom Bot, now might be the right time to switch. If you need access to a method that isn't listed
155
+ in the table at all, see
156
+ [Accessing more API methods and distribution]({{ site.baseurl }}{% link _pages/advanced_usage.md %}#{{ "Accessing more API methods and distribution" | slugify }}).
157
+
158
+ --------
159
+
160
+ ## Working with threads
161
+
162
+ Slack has the concept of [threaded messages](https://api.slack.com/docs/message-threading), which Hubot wasn't
163
+ directly designed to support. However, with a little bit of knowledge about the underlying messages, you can create
164
+ new threads and send messages into a thread using Hubot.
165
+
166
+
167
+ ```javascript
168
+ module.exports = robot => robot.hear(/badger/i, function(res) {
169
+ if (res.message.thread_ts != null) {
170
+ // The incoming message was inside a thread, responding normally will continue the thread
171
+ return res.send("Did someone say BADGER?");
172
+ } else {
173
+ // The incoming message was not inside a thread, so lets respond by creating a new thread
174
+ res.message.thread_ts = res.message.rawMessage.ts;
175
+ return res.send("Slight digression, we need to talk about these BADGERS");
176
+ }
177
+ });
178
+ ```
179
+
180
+ If you want to use the `reply_broadcast` feature of threads, you'll have to
181
+ [use the Web API directly](#{{"Using the Slack Web API" | slugify}}) for the `chat.postMessage` method.
182
+
183
+ --------
184
+
185
+ ## Message reactions
186
+
187
+ Of course, Slack is more than just text messages. Users can send
188
+ [emoji reactions](https://get.slack.help/hc/en-us/articles/206870317-Emoji-reactions) to messages as well. Your Hubot
189
+ can both listen for these from other users, and send reactions of its own. Here is a recipe to listen for
190
+ emoji reactions and add the same reaction back to the same message.
191
+
192
+ ```javascript
193
+ const {WebClient} = require("@slack/client");
194
+
195
+ module.exports = function(robot) {
196
+ const web = new WebClient(robot.adapter.options.token);
197
+
198
+ return robot.hearReaction(function(res) {
199
+
200
+ // res.message is a ReactionMessage instance that represents the reaction Hubot just heard
201
+ if ((res.message.type === "added") && (res.message.item.type === "message")) {
202
+
203
+ // res.messsage.reaction is the emoji alias for the reaction Hubot just heard
204
+ return web.reactions.add({
205
+ name: res.message.reaction,
206
+ channel: res.message.item.channel,
207
+ timestamp: res.message.item.ts
208
+ });
209
+ }
210
+ });
211
+ };
212
+ ```
213
+
214
+ When using `robot.hearReaction` as shown above, the `res.message` value is of type `ReactionMessage`. In addition to the normal
215
+ message properties, this type has a few really helpful properties you might want to use in your script:
216
+
217
+ * `type`: This is either `"added"` or `"removed"`, depending on whether, you guessed it, the reaction was added or
218
+ removed.
219
+ * `reaction`: The name of the emoji reaction. For example, when adding a 👍 reaction, this value is
220
+ `"thumbsup"`.
221
+ * `item`: This is either the message, the file, or the comment where this reaction took place.
222
+ * `item_user`: The user who created the item. This value can be `undefined` if the item was created by a custom
223
+ integration (not a Slack App).
224
+ * `event_ts`: The timestamp of when this reaction message took place.
225
+
226
+ --------
227
+
228
+ ## Presence changes (deprecated)
229
+
230
+ Each time a user changes from away to active, or vice-versa, Hubot can listen that event.
231
+
232
+ ```javascript
233
+ module.exports = robot => robot.presenceChange(function(res) {
234
+
235
+ // res.message is a PresenceMessage instance that represents the presence change Hubot just heard
236
+ const names = (Array.from(res.message.users).map((user) => user.name)).join(", ");
237
+
238
+ const message = res.message.presence === "away" ? `Bye bye ${names}` : `Glad you are back ${names}`;
239
+ return robot.logger.debug(message);
240
+ });
241
+ ```
242
+
243
+ --------
244
+
245
+ ## Send a message to a different channel
246
+
247
+ Responding right back to an incoming message is great, but sometimes you want send a message to a different channel.
248
+ Hubot calls channels "rooms" and this adapter identifies rooms by channel ID, **not by channel name**. If your Hubot
249
+ wants to send a message into another channel, it first needs to find that channel ID. You might get a channel ID from
250
+ a previous message or you might use the Web API to translate a channel name to a channel ID. In the following example,
251
+ we use the Web API to translate to default named channel to an ID and then store it in a variable. There's a listener
252
+ set up that can update that variable based on an incoming message. Then a new listener is used to send data into
253
+ the current channel in the variable, no matter where the incoming message is received.
254
+
255
+ ```javascript
256
+ const {WebClient} = require("@slack/client");
257
+
258
+ module.exports = function(robot) {
259
+ const web = new WebClient(robot.adapter.options.token);
260
+
261
+ // When the script starts up, there is no notification room
262
+ let notification_room = undefined;
263
+
264
+ // Immediately, a request is made to the Slack Web API to translate a default channel name into an ID
265
+ const default_channel_name = "general";
266
+ web.channels.list()
267
+ .then(function(api_response) {
268
+ // List is searched for the channel with the right name, and the notification_room is updated
269
+ const room = api_response.channels.find(channel => channel.name === default_channel_name);
270
+ if (room != null) { return notification_room = room.id; }}).catch(error => robot.logger.error(error.message));
271
+
272
+ // Any message that says "send updates here" will change the notification room
273
+ robot.hear(/send updates here/i, res => notification_room = res.message.rawMessage.channel.id);
274
+
275
+ // Any message that says "my update" will cause Hubot to echo that message to the notification room
276
+ return robot.hear(/my update/i, function(res) {
277
+ if (notification_room != null) {
278
+ return robot.messageRoom(notification_room, `An update from: <@${res.message.user.id}>: '${res.message.text}'`);
279
+ }
280
+ });
281
+ };
282
+ ```
283
+
284
+ --------
285
+
286
+ ## Text formatting and raw messages
287
+
288
+ When your Hubot receives a message, the adapter does its best to make the `text` easy to work with by formatting links
289
+ and mentions. This formatting sometimes removes meaningful information from the text. If you want to access the
290
+ unaltered text in the incoming message, you can use the `rawText` property. Similarly, if you need to access any other
291
+ property of the incoming Slack message, use the `rawMessage` property.
292
+
293
+ ```javascript
294
+ module.exports = robot => // listen to all incoming messages
295
+ robot.hear(/.*/, function(res) {
296
+ // find URLs in the rawText
297
+ const urls = res.message.rawText.match(/https?:\/\/[^\|>\s]+/gi);
298
+
299
+ // log each link found
300
+ if (urls) { return robot.logger.debug((Array.from(urls).map((url) => `link shared: ${url}`)).join("\n")); }
301
+ });
302
+ ```
@@ -0,0 +1,17 @@
1
+ ---
2
+ layout: page
3
+ title: Changelog
4
+ permalink: /changelog
5
+ order: 8
6
+ ---
7
+
8
+ {% for post in site.posts %}
9
+ <h2 id="{{ post.date | date: "%b-%-d-%Y" }}">{{ post.title }}</h2>
10
+ <p>{{ post.date | date: "%b %-d, %Y" }}</p>
11
+ <p>
12
+ {{ post.content }}
13
+ </p>
14
+
15
+ {% endfor %}
16
+
17
+ <p class="rss-subscribe">subscribe <a href="{{ "/feed.xml" | prepend: site.baseurl }}">via RSS</a></p>
@@ -0,0 +1,49 @@
1
+ ---
2
+ layout: page
3
+ title: Upgrading from a Previous Version
4
+ permalink: /upgrading
5
+ order: 10
6
+ headings:
7
+ - title: Upgrading from version 2 or earlier
8
+ - title: Upgrading from version 3 or earlier
9
+ ---
10
+
11
+ ## Upgrading from version 3 or earlier
12
+
13
+ Version 4 of the {{ site.product_name }} adapter uses a more recent version of the Slack Developer Kit for Node.js. As a
14
+ result, there are some syntax changes within Hubot:
15
+
16
+ 1. Before version 4, `msg.message.room` would return the name of the room(e.g. `general`). `msg.message.room` now
17
+ returns a room identifier (e.g. `C03NM270D`). If you need to translate the room id to a room name, you can look it up as
18
+ shown in
19
+ [Send a message to a different channel]({{ site.baseurl }}{% link _pages/basic_usage.md %}#{{ "Send a message to a different channel" | slugify }}).
20
+
21
+ 2. Version 3 of {{ site.product_name }} supported attachments by emitting a `slack.attachment` event. In version 4, you
22
+ use `msg.send`, passing an object with an `attachments` array:
23
+
24
+ ```javascript
25
+ robot.respond(/send attachments/i, msg => msg.send({
26
+ attachments: [
27
+ {
28
+ text: '*error*: something bad happened',
29
+ fallback: 'error: something bad happened',
30
+ color: 'danger',
31
+ mrkdwn_in: ['text']
32
+ }
33
+ ]
34
+ }));
35
+ ```
36
+
37
+ ## Upgrading from version 2 or earlier
38
+
39
+ Version 3 of the {{ site.product_name }} requires different server support from previous versions. If you have an
40
+ existing "hubot" integration set up you'll need to upgrade it:
41
+
42
+ - Go to https://my.slack.com/services/new/hubot and create a new hubot integration
43
+ - Run `npm install hubot-slack --save` to update your code.
44
+ - Test your bot locally using: `HUBOT_SLACK_TOKEN=xoxb-1234-5678-91011-00e4dd ./bin/hubot --adapter slack`
45
+ - Update your production startup scripts to pass the new `HUBOT_SLACK_TOKEN`. You can remove the other `HUBOT_SLACK_*`
46
+ environment variables if you want.
47
+ - Deploy your new hubot to production.
48
+ - Once you're happy it works, disable the old hubot integration from https://my.slack.com/services
49
+
@@ -0,0 +1,14 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * Now uses the latest version of `node-slack-sdk` (v3.4.1 as of this writing), inheriting all the improvements therein.
5
+ * Better (and automatically enabled) reconnect logic. As in, it actually reconnects automatically at all.
6
+ * Now you can upload files!
7
+ * Significantly improved handling of messages with attachments, which is to say, we can deliver them.
8
+ * Message formatting of links, usernames and channel names is now working far better than it ever did, which is damning with faint praise, but hey.
9
+ * Long messages are now left for Slack to handle, bless their hearts.
10
+ * Slack usernames with `.` and `-` are now treated with the respect and dignity due to all usernames.
11
+ * Messages from bots are no longer filtered out, which is both cool and potentially terrifying, but we should never have silenced the robots in the first place.
12
+ * Remember how if you tried to hack on this adapter and used `npm link` to plug that into a live bot? And how that didn't work? Yeah? Well now it does. Stupid `instanceof`.
13
+ * Total refactoring of the functionality, exposing a slightly different interface. So watch out for that.
14
+ * You can now access the underlying Slack client directly, for when you really need low-level functionality therein.
@@ -0,0 +1,5 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * Usernames with `-` and `.` no longer borked
5
+ * You could craft a bot that would crash Hubot by simply having it send a message. Wow! That got fixed.
@@ -0,0 +1,4 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * v4 shipped with this amazing feature whereby we would silently destroy any non-string fields in a message object before sending it out. Y'all loved that feature so much, we just had to build on it. Now we silently destroy you entire message object before sending it out. J/K, that was actually a bug, and we fixed it.
@@ -0,0 +1,8 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * So, you know how Hubot would crash when you tried to set the topic in a private channel? Yeah, me too. Fixed. (#350)
5
+ * As it happens, we were taking on some of the message formatting work that the Slack servers can do on our behalf. Fixed. (#236, #356)
6
+ * `robot.messageRoom` now accepts room names, not just IDs. Because sometimes all you have is a name. (#346)
7
+ * Treely ruly ignore all self-generated messages, for realz this time.
8
+ * Send all messages with `as_user=true` by default now.
@@ -0,0 +1,4 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * Oh, so it turns out that the solution to using Slack's message formatting was incorrectly conceived. Fixed.
@@ -0,0 +1,4 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * Sometimes you could send a message to an @username or a #channelname, but most of the time you couldn't. We have found the problem, and politely asked it to leave.
@@ -0,0 +1,4 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * Somewhere out there, someone has been pining to handle message reactions. If that someone is you, this release lets you do that. Preprare to receive new `ReactionMessage` messages when reactions are added or removed from messages! To the rest of you: Carry on.
@@ -0,0 +1,4 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * And now we have an even easier way of watching for message reactions
@@ -0,0 +1,4 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * Emergency bugfix because typos.
@@ -0,0 +1,8 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * Fixed a surprisingly wide range of bugs whereby we incorrectly formatted incoming messages that tagged
5
+ channels or users. Now if someone says "@foobar", your bot will here "@foobar", just as you'd expect.
6
+ * So, it turns out you can't have both an event handler in a base class called `topic` and a setter method
7
+ in a derived class called `topic`. Who knew? Stupid dynamically typed languages.
8
+ * v4.2.1 was retconned by the recently updated documentation. The retcon has been retconned.
@@ -0,0 +1,5 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * loads slack users into `robot.brain`. (#381) thanks @NKMR6194!
5
+ * fixes various typos and inaccuracies in the docs (#383, #378, #376).
@@ -0,0 +1,5 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * fixes a bug where hubot's using a token without permission to read a user's email would
5
+ cause a crash (#388). thanks @aoberoi.
@@ -0,0 +1,5 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * fixes a bug where `user_change` events would cause hubot to crash (#391). thanks @aoberoi,
5
+ @DonEmil, and @pearswj.
@@ -0,0 +1,4 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * Adds support for message threads. Thanks @ndaversa!
@@ -0,0 +1,5 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * Fixes issue when events arrive from user's who are outside the team/workspace you are connected
5
+ to (#404).
@@ -0,0 +1,7 @@
1
+ ---
2
+ layout: changelog
3
+ ---
4
+ * Restore ability to inspect `rawText` and `rawMessage` on SlackMessage objects (#413) - thanks @mistydemeo
5
+ * Relieve extraneous `users.list` Web API method calls from occurring due to hubot brain (#419) - thanks @chapmanc
6
+ * Add ability to set RTMClient options and `rtm.start` options via env vars (#431, #421) - thanks @aoberoi
7
+ * Documentation fix (#426) - thanks @TonioOoOo