reaction_added
events to file GitHub issuesSource: https://github.com/mbland/slack-github-issues
When a Slack chat message receives a specific emoji reaction, this package creates a GitHub issue with a link to that message.
This feature is for teams who use Slack to communicate and GitHub to track issues. It provides an easy way to file an issue (just add a specific emoji to a message), which helps team members (even non-technical ones!) quickly document or act upon important parts of conversations.
When team members add an emoji reaction to a message, Slack will send your
application a reaction_added
event. Your application should
pass this event to this package's ReactionIssueFiler
class, which will match
the event against a set of configuration rules. If the event
matches a rule, the ReactionIssueFiler
will retrieve the list of
reactions for the message.
If the message doesn't have an emoji reaction indicating an issue was already
filed (the successReaction
configuration property), ReactionIssueFiler
will
create a GitHub issue
for the message. The issue will contain a link to the message. At this point,
the ReactionIssueFiler
will react to the message with a successReaction
emoji. Finally, it will return the
issue URL to the application.
Note: This plugin only handles reactions to normal messages, not file or file comment reactions. This support may be added in the future if the demand exists, but isn't straightforward, since there's no one specific channel associated with either.
This package has been refactored heavily to ensure the core logic is 100%
asynchronous and no longer depends directly on any Hubot or Slack Real Time
Messaging client details, which are now encapsulated within the
hubot/slack-github-issues.js script and the
SlackRtmDataStore
class.
mbland/hubot-slack-github-issues remains as a convenience wrapper around this package specifically for use with Hubot.
Here are instructions for installing this package and putting it into use in your application. If your bot is implemented using Hubot, see the Hubot integration instructions as well.
Install Node.js on your system. This package requires version 4.2 or greater or version 5 or greater. You may wish to first install a version manager such as nvm to manage and install different Node.js versions.
In your application repository, run:
$ npm install slack-github-issues --save
Note: The SlackRtmDataStore
class depends upon the
@slack/client package.
Make sure to install it if you intend to use the Slack Real Time Messaging
API in your application.
If you haven't done so already, create a Slack bot
user. Use the bot's API token as the value
for the slackApiToken
configuration file property (see the Note on API
tokens from the instructions for configuring the
package). If using the Hubot script, assign it to
the HUBOT_SLACK_TOKEN
environment variable instead.
Decide on a GitHub user that will file issues on behalf of the script. If you
don't wish to use an existing user, you may create a GitHub
account
dedicated to this purpose and add this account to your GitHub organization if
applicable. Create a personal access
token
for this user and use it as the value for the githubApiToken
configuration
file property (see the Note on API tokens from the instructions for
configuring the package). If using the Hubot script,
assign it to the HUBOT_GITHUB_TOKEN
environment variable instead.
If you wish to use this script with private GitHub repositories, add your GitHub user as a collaborator with read access to each repository. Alternatively, you can add your GitHub user to a team with access to private repositories instead.
Create a configuration file or object as described below.
Integrate it into your application per the instructions for configuring the
package. If using the Hubot script, assign the path
to HUBOT_SLACK_GITHUB_ISSUES_CONFIG_PATH
instead.
Run your bot locally or otherwise deploy to your preferred environment.
You can easily integrate this package into a Hubot instance using the mbland/hubot-slack-github-issues package. Alternatively, you may use the hubot/slack-github-issues.js script that ships with this package:
Create your own Hubot instance if you haven't already done so. Note that you do not need to install Redis to use this script.
Ensure that you're using Hubot v2.19.0 or greater and
hubot-slack v4.2.1 or greater by
including the following in your instance's package.json
and running npm install
:
"dependencies": {
"hubot": "^2.19.0",
"hubot-slack": "^4.2.1"
}
Set the following environment variables (how to do that depends on the operating system and shell that you use; here's an example guide for OS X with the default bash shell):
HUBOT_GITHUB_TOKEN
: personal API token for the GitHub userHUBOT_SLACK_TOKEN
: API token for the Slack bot userHUBOT_SLACK_GITHUB_ISSUES_CONFIG_PATH
(optional): the path to the
configuration file; defaults to config/slack-github-issues.json
Add the following to one of your bot's existing scripts:
require('slack-github-issues').loadHubotScript(robot);
or add a new script like the following:
'use strict';
module.exports = function(robot) {
require('slack-github-issues').loadHubotScript(robot);
};
Run hubot --adapter slack
locally or otherwise deploy to your preferred
environment.
If you're writing a bot using a different framework or your own application structure, the following explains the necessary steps:
Import this package into your application code:
var slackGitHubIssues = require('slack-github-issues');
Configure the
package by creating a configParams
object with exactly
one of these two properties:
data
: an Object containing the configuration datapath
: a path to the file containing the configuration data as JSON,
relative to the root directory of the running instance of the application:var configParams = { path: 'config/slack-github-issues.json' };
Note on API tokens: If you define your configuration in a file stored in
version control, you may wish to keep API tokens out of it. You can add an
updates
property to configParams
that you create from your application's
environment variables. Note that you should not define
configParams.updates
as an object literal, because process.env
will not
contain any values at the time the literal is instantiated. (You can also set
configParams.path
this way.)
configParams.path = process.env.SLACK_GITHUB_ISSUES_CONFIG_PATH;
configParams.updates.slackApiToken = process.env.SLACK_API_TOKEN;
configParams.updates.githubApiToken = process.env.GITHUB_API_TOKEN;
Create a data store object patterned after SlackRtmDataStore
. If you're
using an instance of RtmClient
from
@slack/client and the
Slack Real Time Messaging API, create an
instance of SlackRtmDataStore
by passing the RtmClient
to
SlackRtmDataStore
:
var slackDataStore = slackGitHubIssues.slackRtmDataStore(slackRtmClient);
If your application is running across multiple instances, you will need to
define your own Slack data store with the same interface as
SlackRtmDataStore
:
var slackDataStore = new MyDistributedAppSlackDataStore;
If not already present, add a logging object to your application that
supports the info()
and error()
methods, such as
log. You can pass this logger directly
to the methods described below, but it's recommended that you wrap it using
the Logger
class from this library, which prefixes this package's messages
with the package name:
var Log = require('log');
var logger = slackGitHubIssues.logger(new Log);
Create a ReactionIssueFiler
instance by using the appropriate factory. For
bot applications that will run as a single instance, use
singleInstanceReactionIssueFiler
:
var reactionIssueFiler = slackGitHubIssues.singleInstanceReactionIssueFiler(
configParams, slackDataStore, logger);
This factory will use the in-memory MessageLock
class to ensure only one
handler instance per matching event executes at a time. If your application
is running across multiple instances, you will need to define your own class
with the same interface as MessageLock
, then pass this to the
reactionIssueFiler()
factory:
var messageLock = new MyDistributedAppMessageLock;
var reactionIssueFiler = slackGitHubIssues.reactionIssueFiler(
configParams, slackDataStore, messageLock, logger);
Register a handler for reaction_added
events that passes the
event object to reactionIssueFiler.execute()
and responds appropriately:
reactionIssueFiler.execute(reaction_added_message)
.then(function(issueUrl) {
handleSuccess('created: ' + issueUrl);
})
.catch(function(err) {
if (err) {
handleError('error filing issue: ' + err.message);
}
});
Note that execute()
will return Promise.reject(null)
when events are
ignored, to differentiate from actual
Error
instances.
To create a configuration file template, run:
$ bin/slack-github-issues print-template > slack-github-issues.json
Edit this file as necessary, then validate the configuration by running:
$ bin/slack-github-issues validate path-to-config.json
The JSON configuration file must conform to the following schema:
NOTE: DO NOT STORE slackApiToken
and githubApiToken
IN SOURCE CONTROL! Use environment variables and programmatically set these
properties after loading the file as demonstrated in the Note on API tokens
from the instructions for configuring the package.
For example:
{
"githubUser": "mbland",
"githubApiToken": "<github-api-token>",
"slackApiToken": "<slack-api-token>",
"githubTimeout": 5000,
"slackTimeout": 5000,
"successReaction": "heavy_check_mark",
"rules": [
{
"reactionName": "book",
"githubRepository": "slack-github-issues"
}
]
}
For a more complete example, see
test/helpers/test-config.json
in this
repository.
Run the following (replacing slack-github-issues.json
with whatever file name
you chose earlier):
$ bin/slack-github-issues validate slack-github-issues.json
If it passes, you will see:
slack-github-issues.json: OK
Otherwise, an error message will report all schema and constraint violations.
To keep the configuration file readable, rules:
must be sorted according to
the following ordering rules. The script will abort otherwise:
reactionName
in lexicographic orderchannelNames
must follow any other rules for the
same reactionName
, so that more specific rules are matched firstgithubRepository
in lexicographic orderTo ensure that rules behave as expected, the script also enforces
following conditions for each set of rules pertaining to a reactionName
:
channelNames
list is sortedgithubRepository
value is uniquechannelNames
is unique across every rulechannelNames
undefined, as this rule will
match messages in every channel not matched by other rulesFeel free to comment on or file a new GitHub issue or otherwise ping @mbland with any questions or comments you may have, especially if the current documentation hasn't addressed your needs.
If you'd care to contribute to this project, be it code fixes, documentation updates, or new features, please read the CONTRIBUTING file.
This software is made available as Open Source software under the ISC License. For the text of the license, see the LICENSE file.
This package was extracted from mbland/hubot-slack-github-issues, which was forked from 18F/hubot-slack-github-issues. For the detailed source history prior to the inception of this repository, see https://github.com/mbland/hubot-slack-github-issues/commits/slack-github-issues-begin.