forked from firebase/functions-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Polishing, simplifying and Adding README to the GitHub to Slack sample
Change-Id: I5b935399391ead5d125b69a592344471f61523b7
- Loading branch information
Nicolas Garnier
committed
Mar 7, 2017
1 parent
5440151
commit 859841f
Showing
5 changed files
with
95 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Post GitHUb commits to Slack channel. | ||
|
||
This sample shows how to automatically post GitHub commits to a Slack channel using an HTTPS Cloud Function. | ||
|
||
Further reading: | ||
- Slack Webhooks API: https://api.slack.com/incoming-webhooks | ||
- Firebase SDK: https://firebase.google.com/docs/functions | ||
- GitHUb Webhooks: https://developer.github.com/webhooks/creating/ | ||
|
||
## Functions Code | ||
|
||
See file [functions/index.js](functions/index.js) for the code. | ||
|
||
Handling the Google Actions requests is done using the [Google Actions SDK](https://www.npmjs.com/package/actions-on-google). | ||
|
||
The dependencies are listed in [functions/package.json](functions/package.json). | ||
|
||
|
||
## Deploy and test | ||
|
||
To test this sample action: | ||
|
||
- Create a Firebase Project using the [Firebase Developer Console](https://console.firebase.google.com) | ||
- Configure this sample to use your project using `firebase --use add` and select your project. | ||
- [Add a WebHook to your GitHub repo](https://help.github.com/articles/about-webhooks/) with the following settings: | ||
- Payload URL: `https://us-central1-<FIREBASE_PROJECT_ID>.cloudfunctions.net/githubWebhook` | ||
- Content type: `application/json` | ||
- Secret: `A_SECRET_YOU_DEFINE` | ||
- Which events would you like to trigger this webhook? `Just the push event.` | ||
- [Add an **Incomming Webhook**](https://my.slack.com/services/new/incoming-webhook/) to your Slack channel and take note of the **Webhook URL**. | ||
- Set the `slack.webhook_url` and `github.secret` Google Cloud environment variables to match the email and password of the Gmail account used to send emails. For this use: | ||
```bash | ||
firebase functions:config:set slack.webhook_url="https://hooks.slack.com/services/..." github.secret="A_SECRET_YOU_DEFINED_WHEN_SETTING_UP_THE_GITHUB_WEBHOOK" | ||
``` | ||
- Deploy your project using `firebase deploy` | ||
- Make your action available for testing using the `gactions preview action.json` | ||
- Test your Action on the [Google Home Web Simulator](https://g.co/actionswebsim) by saying "Talk to My Action" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,64 @@ | ||
const pubsub = require('@google-cloud/pubsub')(functions.config().firebase); | ||
const githubTopic = functions.config().github.topic; | ||
/** | ||
* Copyright 2016 Google Inc. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
'use strict'; | ||
|
||
const functions = require('firebase-functions'); | ||
const rp = require('request-promise'); | ||
const crypto = require('crypto'); | ||
|
||
exports.githubWebhook = functions.https.onRequest((request, response) => { | ||
/** | ||
* Webhook that will be called each time there is a new GitHub commit and will post a message to | ||
* Slack. | ||
*/ | ||
exports.githubWebhook = functions.https.onRequest((req, res) => { | ||
const cipher = 'sha1'; | ||
const signature = request.headers['x-hub-signature']; | ||
const hmac = require('crypto') | ||
.createHmac(cipher, functions.config().github.secret) | ||
.update(JSON.stringify(request.body, null, 2)) | ||
.digest('hex'); | ||
const signature = req.headers['x-hub-signature']; | ||
|
||
// TODO: Configure the `github.secret` Google Cloud environment variables. | ||
const hmac = crypto.createHmac(cipher, functions.config().github.secret) | ||
// The JSON body is automatically parsed by Cloud Functions so we re-stringify it. | ||
.update(JSON.stringify(req.body, null, 0)) | ||
.digest('hex'); | ||
const expectedSignature = `${cipher}=${hmac}`; | ||
|
||
// Skipping verification, since JSON.stringify fails hmac, need the raw post | ||
if (true || signature === expectedSignature) { | ||
pubsub.topic(githubTopic).publish( | ||
request.body, | ||
(err, messageIds, apiResponse) => { | ||
if (err) { | ||
console.error(err); | ||
response.status(500).send('Something went wrong.'); | ||
} else { | ||
response.status(200).send(''); | ||
} | ||
} | ||
); | ||
// Check that the body of the request has been signed with the GitHub Secret. | ||
if (signature === expectedSignature) { | ||
postToSlack(req.body.compare, req.body.commits.length, req.body.repository).then(() => { | ||
res.end(); | ||
}).catch(error => { | ||
console.error(error); | ||
res.status(500).send('Something went wrong while posting the message to Slack.'); | ||
}); | ||
} else { | ||
console.error(`x-hub-signature ${signature} did not match ${expectedSignature}`); | ||
response.status(403).send('Your x-hub-signature\'s bad and you should feel bad!'); | ||
console.error('x-hub-signature', signature, 'did not match', expectedSignature); | ||
res.status(403).send('Your x-hub-signature\'s bad and you should feel bad!'); | ||
} | ||
}); | ||
|
||
|
||
exports.githubAnnouncer = functions.pubsub.topic(githubTopic).onPublish(event => { | ||
const payload = JSON.parse(event.data.json.payload); | ||
if (payload.ref === null) { return null; } | ||
const commits = payload.commits.length; | ||
const repo = payload.repository; | ||
const url = payload.compare; | ||
/** | ||
* Post a message to Slack about the new GitHub commit. | ||
*/ | ||
function postToSlack(url, commits, repo) { | ||
return rp({ | ||
method: 'POST', | ||
uri: functions.config().slack.webhookurl, | ||
// TODO: Configure the `slack.webhook_url` Google Cloud environment variables. | ||
uri: functions.config().slack.webhook_url, | ||
body: { | ||
text: `<${url}|${commits} new commit${commits > 1 ? 's' : ''}> pushed to <${repo.url}|${repo.name}>.` | ||
text: `<${url}|${commits} new commit${commits > 1 ? 's' : ''}> pushed to <${repo.url}|${repo.full_name}>.` | ||
}, | ||
json: true | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,11 @@ | ||
{ | ||
"name": "functions", | ||
"description": "Firebase Functions", | ||
"name": "github-to-slack-functions", | ||
"description": "Firebase Functions that posts new GitHub commits to a Slack channel.", | ||
"dependencies": { | ||
"@google-cloud/pubsub": "^0.8.2", | ||
"firebase-admin": "^4.0.5", | ||
"crypto": "0.0.3", | ||
"firebase-admin": "^4.1.2", | ||
"firebase-functions": "https://storage.googleapis.com/firebase-preview-drop/node/firebase-functions/firebase-functions-preview.latest.tar.gz", | ||
"request": "^2.80.0", | ||
"request-promise": "^4.1.1" | ||
} | ||
} | ||
|