@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.
- package/.github/CODE_OF_CONDUCT.md +11 -0
- package/.github/contributing.md +60 -0
- package/.github/issue_template.md +48 -0
- package/.github/maintainers_guide.md +91 -0
- package/.github/pull_request_template.md +8 -0
- package/.github/workflows/ci-build.yml +74 -0
- package/LICENSE +22 -0
- package/README.md +29 -0
- package/docs/Gemfile +2 -0
- package/docs/README.md +15 -0
- package/docs/_config.yml +29 -0
- package/docs/_includes/analytics.html +7 -0
- package/docs/_includes/head.html +33 -0
- package/docs/_includes/page_header.html +20 -0
- package/docs/_includes/side_nav.html +22 -0
- package/docs/_includes/tag_manager.html +13 -0
- package/docs/_layouts/changelog.html +15 -0
- package/docs/_layouts/default.html +47 -0
- package/docs/_layouts/page.html +10 -0
- package/docs/_pages/FAQ.md +63 -0
- package/docs/_pages/about.md +16 -0
- package/docs/_pages/advanced_usage.md +102 -0
- package/docs/_pages/auth.md +44 -0
- package/docs/_pages/basic_usage.md +302 -0
- package/docs/_pages/changelog.html +17 -0
- package/docs/_pages/upgrading.md +49 -0
- package/docs/_posts/2016-07-15-v4.0.0.md +14 -0
- package/docs/_posts/2016-07-19-v4.0.1.md +5 -0
- package/docs/_posts/2016-08-03-v4.0.2.md +4 -0
- package/docs/_posts/2016-09-12-v4.0.3.md +8 -0
- package/docs/_posts/2016-09-12-v4.0.4.md +4 -0
- package/docs/_posts/2016-09-14-v4.0.5.md +4 -0
- package/docs/_posts/2016-09-21-v4.1.0.md +4 -0
- package/docs/_posts/2016-10-12-v4.2.0.md +4 -0
- package/docs/_posts/2016-10-12-v4.2.1.md +4 -0
- package/docs/_posts/2016-11-05-v4.2.2.md +8 -0
- package/docs/_posts/2017-01-05-v4.3.0.md +5 -0
- package/docs/_posts/2017-01-09-v4.3.1.md +5 -0
- package/docs/_posts/2017-02-15-v4.3.2.md +5 -0
- package/docs/_posts/2017-02-17-v4.3.3.md +4 -0
- package/docs/_posts/2017-03-29-v4.3.4.md +5 -0
- package/docs/_posts/2017-08-24-v4.4.0.md +7 -0
- package/docs/_posts/2018-06-08-v4.5.0.md +13 -0
- package/docs/_posts/2018-06-14-v4.5.1.md +4 -0
- package/docs/_posts/2018-07-03-v4.5.2.md +5 -0
- package/docs/_posts/2018-07-17-v4.5.3.md +12 -0
- package/docs/_posts/2018-08-10-v4.5.4.md +7 -0
- package/docs/_posts/2018-10-01-v4.5.5.md +7 -0
- package/docs/_posts/2018-12-21-v4.6.0.md +6 -0
- package/docs/_posts/2019-04-29-v4.7.0.md +6 -0
- package/docs/_posts/2019-04-30-v4.7.1.md +5 -0
- package/docs/_posts/2020-04-03-v4.7.2.md +6 -0
- package/docs/_posts/2020-05-19-v4.8.0.md +10 -0
- package/docs/_posts/2020-10-19-v4.8.1.md +7 -0
- package/docs/_posts/2021-01-26-v4.9.0.md +8 -0
- package/docs/_posts/2022-01-12-v4.10.0.md +8 -0
- package/docs/index.md +93 -0
- package/docs/styles/docs.css +37 -0
- package/package.json +50 -0
- package/slack.js +20 -0
- package/src/SlackAdapter.mjs +302 -0
- package/src/SlackAdapter.test.mjs +342 -0
- package/src/bot.js +526 -0
- package/src/client.js +445 -0
- package/src/extensions.js +82 -0
- package/src/mention.js +15 -0
- package/src/message.js +307 -0
- package/src/testing.mjs +24 -0
- package/test/bot.js +769 -0
- package/test/client.js +446 -0
- package/test/message.js +329 -0
- 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,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
|
+
* 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,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,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
|