Source: 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.
Example of filing an issue by reacting to a message with a
book
emoji. After successfully filing an issue, the bot application
using this package marked the message with a heavy_check_mark
emoji
and posted the issue URL to the channel.
- How it works
- What's different from mbland/hubot-slack-github-issues?
- Installation and usage
- Configuration
- Feedback and contributions
- Open Source license
- Prior work
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 theHUBOT_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 theHUBOT_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 runningnpm 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 toconfig/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 toconfigParams
that you create from your application's environment variables. Note that you should not defineconfigParams.updates
as an object literal, becauseprocess.env
will not contain any values at the time the literal is instantiated. (You can also setconfigParams.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 ofRtmClient
from @slack/client and the Slack Real Time Messaging API, create an instance ofSlackRtmDataStore
by passing theRtmClient
toSlackRtmDataStore
: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()
anderror()
methods, such as log. You can pass this logger directly to the methods described below, but it's recommended that you wrap it using theLogger
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, usesingleInstanceReactionIssueFiler
: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 asMessageLock
, then pass this to thereactionIssueFiler()
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 toreactionIssueFiler.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 returnPromise.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:
- githubUser: GitHub organization or username owning all repositories
- githubApiToken: Personal access token for the user that will file GitHub issues on behalf of your application (see the NOTE below)
- githubTimeout: GitHub API timeout limit in milliseconds
- slackApiToken: API token for the Slack bot user under which your app will run (see the NOTE below)
- slackTimeout: Slack API timeout limit in milliseconds
- successReaction: emoji used to indicate an issue was successfully filed
- githubApiBaseUrl (optional): Override of the default GitHub API URL; chiefly used when running a local test server
- slackApiBaseUrl (optional): Override of the default Slack API URL; chiefly used when running a local test server
- rules: defines each condition that will result in a new GitHub issue
- reactionName: name of the reaction emoji triggering the rule
- githubRepository: GitHub repository belonging to githubUser to which to post issues
- channelNames (optional): name of the Slack channels triggering the rule; leave undefined to match messages in any Slack channel
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 order- rules that do not define
channelNames
must follow any other rules for the samereactionName
, so that more specific rules are matched first githubRepository
in lexicographic order
To ensure that rules behave as expected, the script also enforces
following conditions for each set of rules pertaining to a reactionName
:
- Each rule's
channelNames
list is sorted - Each
githubRepository
value is unique - Each value in
channelNames
is unique across every rule - Only the last rule can leave
channelNames
undefined, as this rule will match messages in every channel not matched by other rules
Feel 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.