-
Notifications
You must be signed in to change notification settings - Fork 122
add multiple support #22
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
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.