-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add multiple support #22
Conversation
Thanks, @excaliburhan! This PR covers a fairly specific scenario as written, but I wonder if we could expand it to accommodate the scenarios in #16 ("add additional fields to If we allowed consumers to provide their own validation/parsing logic--or even separated webhook processing from the HTTP server itself--we could preserve the existing (simple) default but open the door for more customization downstream. Thoughts? |
OK, I realize this PR is actually 'One handler deals with multiple webhooks'. Solution A: expand var createHandler = require('github-webhook-handler')
var handler = createHandler([
{ path: '/app1', secret: 'secret1' },
{ path: '/app2', secret: 'secret2' }
]) this solution means we have to rewrite the Solution B: process over the HTTP server var handlerA = createHandler({ path: '/app1', secret: 'secret1' })
var handlerB = createHandler({ path: '/app2', secret: 'secret2' })
http.createServer(function (req, res) {
// process logic
switch (req.url) {
case '/app1':
handlerA(req, res, function (err) {
res.statusCode = 404
res.end('no such location')
})
break
case '/app2':
handlerB(req, res, function (err) {
res.statusCode = 404
res.end('no such location')
})
break
default:
break
}
}).listen(7777)
// events
handlerA.on('issues', function(event) {
// do sth
})
handlerB.on('issues', function(event) {
// do sth
}) this solution contains consumers' own process logic. I prefer the Solution A, it may make the For Solution B, what makes me unhappy is I have to write many nearly same code to keep different handlers work. I'd like to help with Solution A. @rjz what do you think about this? |
It seems like we could write A in terms of B, something like: function multiHook(handlerOpts) { // it's a silly name :^)
var handlers = handlerOpts.reduce(function (hs, opts) {
hs[opts.path] = createHandler(opts);
return hs;
}, {});
return http.createServer(function (req, res) {
var handler = handlers[req.url];
handler(req, res, function (err) {
res.statusCode = 404
res.end('no such location')
});
});
} If that's reasonable, maybe it's appropriate to leave this handler focused on a single hook but either:
|
Cool. |
One more thing, in github webhooks settings, the I think this tip should be written in the READEME.md. Just a suggestion. |
Done, and big thanks for your suggestions on this, @excaliburhan!
|
ok, here's the multi handlers complete example(have tested on my server), and an external package node-github-webhook. example for github-webhook-handlerfunction generaterHandler(handlerOpts) {
var handlers = handlerOpts.reduce(function(hs, opts) {
hs[opts.path] = createHandler(opts)
return hs
}, {})
return http.createServer(function(req, res) {
var handler = handlers[req.url]
handler(req, res, function(err) {
res.statusCode = 404
res.end('no such location')
})
}).listen(7777)
}
var http = require('http')
var createHandler = require('github-webhook-handler')
var handlerOpts = [{
path: '/app1',
secret: 'secret1'
}, {
path: '/app2',
secret: 'secret2'
}]
var handler = generaterHandler(handlerOpts)
handler.on('error', function(err) {
console.error('Error:', err.message)
})
handler.on('push', function (event) {
var url = event.url
switch (url) {
// be careful if you use query to distinguish your app, url contains the querys, otherwise, it is equal to the path
case '/app1':
// do sth for app1
break
case '/app2':
// do sth for app2
break
default:
break
}) example for node-github-webhookvar http = require('http')
var createHandler = require('node-github-webhook')
var handler = createHandler([{
path: '/app1',
secret: 'secret1'
},
{
path: '/app2',
secret: 'secret2'
}
])
http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404
res.end('no such location')
})
}).listen(7777)
// handler
handler.on('error', function (err) {
console.error('Error:', err.message)
})
handler.on('push', function (event) {
var path = event.path
switch (path) {
case '/app1':
// do sth for app1
break
case '/app2':
// do sth for app2
break
default:
break
}
}) |
multiple handlers
I need multiple handlers for different repos and I hope those handlers have different secret for each repo. And those handlers only take one port.
So I make
options.secret
to support both string and object. Ifoptions.secret
is an object, the key of the object will beappId
, and the value of the object will beappSecret
. At last, theEmitData
will return theappId
for use.Here's the example for multiple handlers:
And in github Webhooks Payload URL:
app1
app2
If
options.secret
is a string, everything remains the same.