The things that power your Gitter activity feed.
Gitter.im uses this library to instruct a user on how to set up webhooks for a particular external service (Jenkins, HuBoard etc). Then, when that service POSTs to gitter.im, this library is again used to parse the incoming data and get a human readable message. Gitter.im then displays the message in the user's activity feed.
If it is in the lib
folder, we support it.
git clone [email protected]:gitterHQ/services.git
cd services
npm install
npm test
If everything passes, then you are ready!
.
└── lib
└── YOUR_SERVICE_NAME
├── index.js
├── icons
│ ├── logo.png
│ └── [email protected]
├── instructions.md
├── settings.json
├── examples
│ └── some_example_webhook.json
└── test
└── index.js
index.js
: This module has to export the following:apiVersion
: (number) the major version of this api.name
: (string) how you would like your service named to the user (e.g github's name isGitHub
).parse
: (function) the function called every time we receive an incoming webhook from your service. If it is an event that the user wants to see, then return a message object. If not, return something falsy.- has the signature
function(headers, body, settings)
where:headers
: (object) the headers of the webhook POST request e.g{ "content-type": "application/json", ... }
.body
: (object) the body of the webhook POST request.settings
: (object) the settings that have been picked by the user e.g{ events: {"someId": true, ... } }
.events
will be a map of the the eventid
's that a user has picked.
- returns a message object with these properties:
message
: (string) the message do be displayed (in markdown) e.g"Some *Amazing* event has occured"
.icon
: (string) the name of an icon in theicons
dir to display e.g"logo"
.errorLevel
: (string) either"normal"
or"error"
. Error messages get styled red, and so theicon
that you pick for this message must be red too (#e74c3c).
- has the signature
icons
: This directory contains all the png icons that can be used by this service. They must follow the following rules:- each icon must exist as both a 16x16 png and a 32x32 png (
name.png
and[email protected]
respectively). - there must be a logo icon (
logo.png
and[email protected]
). - icons must be either black and white, or #e74c3c and white (for error messages).
- each icon must exist as both a 16x16 png and a 32x32 png (
instructions.md
: The instructions that will be displayed when someone needs to set up your service to emit webhooks.settings.json
: This represents the settings available to the user when creating an integration. At the moment, it's only list of events. Format is{ "events": [event1, event2, ... ] }
where each event is an object that has these properties:id
: (string) a unique id that will be passed into theparse
function if selected e.g"high_five"
.name
: (string) a friendly name for your event e.g"High Five"
.description
: (string) an explanation of the event e.g"Single clap made by two people"
.selected
: (boolean) whether or not this event option is enabled by default.
examples
: This directory contains examples to be used in your tests (and our sanity testing). You will need to intercept some hooks if you cant find any documented. You can use the playground for this. Again, rules:- all examples must be in
json
. - all examples must be in the format
{ headers: {...}, body: {...} }
.
- all examples must be in
test
: directory of standard mocha tests. Cool people write tests. You are cool, aren't you?
As shown above, settings available to the user are declared in a service's settings.json
. These choices are then sent with every incoming webhook to that service's parse
function. It is up to the parse() function to decide if that hook is relevant to the users choices.
For example, if you have the following settings.json:
{
"events": [
{
"id": "kitten_yawn",
"name": "Kitten Yawn",
"description": "Whenever a kitten yawns.",
"selected": true
},
{
"id": "kitten_purr",
"name": "Kitten Purr",
"description": "Whenever a kitten purrs.",
"selected": true
}
]
}
Then if the user only wants to be notified of kitten_purr
events and not kitten_yawn
events, then the parse(headers, body, settings)
function will be called with a settings
object like this:
{
"events": {
"kitten_yawn": false,
"kitten_purr": true
}
}
The parse
function then has to compare the headers
and body
with the settings
to see what should be returned (if anything).
The playground exists as tool to try out your service with some real hooks (and your examples) to see how it behaves.
Start it with node playground/server.js
and go to http://localhost:3333
in your browser. It will also start a proxy that is globally available at https://[id].localtunnel.me
that anyone can reach and post hooks to.
If you find yourself restarting the server often, install nodemon and run the server with nodemon playground/server.js
to have the server restart on file change. Warning: localtunnel will give you a new tunnel address on every restart.
Let's say you want your service on Gitter to have a button like:
Which opens a configuration modal like:
Which then outputs something like:
Then your index.js
needs to look like (we've cut it down a bit, have a look at the real one with all its comments):
module.exports = {
apiVersion: 1,
name: 'Jenkins',
parse: function(headers, body, settings) {
return {
message: 'Jenkins [webhooks-handler](http://users-jenkins.server.com/job/webhooks-handler/6/) success',
icon: 'smile',
errorLevel: 'normal'
};
}
};
Your settings.json
needs to look like this:
{
"events": [
{
"id": "started",
"name": "Started",
"description": "When a build is started.",
"selected": false },
{
"id": "success",
"name": "Success",
"description":
"When a build finishes successfully.",
"selected": false
},
{
"id": "failure",
"name": "Failure",
"description": "When a build fails. Sad face.",
"selected": true
}
]
}
Your instructions.md
should look like this:
1. Select your job in Jenkins
2. Click the "Configure" link
3. Scroll down to Job notifications
4. Click the "Add Endpoint" button
5. Make sure Format is "JSON"
6. Make sure protocol is "HTTP"
7. Paste in your webhook url into "URL"
8. Click "Apply"
And finally, your icons
directory needs to contain these:
Are things going wrong? Are things going right? Do you have an awesome idea that you need a hand with?
Come and chat with everyone at gitter.im/gitterHQ/services.
Started by malditogeek, shuffled around by trevorah.
MIT