Ghost/core/server/services/webhooks/trigger.js
Rishabh Garg 8ad951d7f3
Added new site.changed event and webhook trigger service (#10019)
refs #9942

* Added new middleware to trigger events

* Refactored webhooks service
- added new trigger service, moved listen service to its own file
- started listening to new site.changed event
- cleaned up trigger service to work with new webhook fields
- cleaned up tests
- removed redundant trigger method in v0.1 controller
2018-10-19 00:01:30 +05:30

77 lines
2.5 KiB
JavaScript

const _ = require('lodash');
const common = require('../../lib/common');
const models = require('../../models');
const pipeline = require('../../../server/lib/promise/pipeline');
const request = require('../../../server/lib/request');
function updateWebhookTriggerData(id, data) {
models.Webhook.edit(data, {id: id}).catch(() => {
common.logging.warn(`Unable to update last_triggered for webhook: ${id}`);
});
}
function makeRequests(webhooksCollection, payload, options) {
_.each(webhooksCollection.models, (webhook) => {
const event = webhook.get('event');
const targetUrl = webhook.get('target_url');
const webhookId = webhook.get('id');
const reqPayload = JSON.stringify(payload);
common.logging.info('webhook.trigger', event, targetUrl);
const triggeredAt = Date.now();
request(targetUrl, {
body: reqPayload,
headers: {
'Content-Length': Buffer.byteLength(reqPayload),
'Content-Type': 'application/json'
},
timeout: 2 * 1000,
retries: 5
}).then((res) => {
updateWebhookTriggerData(webhookId, {
last_triggered_at: triggeredAt,
last_triggered_status: res.statusCode
});
}).catch((err) => {
// when a webhook responds with a 410 Gone response we should remove the hook
if (err.statusCode === 410) {
common.logging.info('webhook.destroy (410 response)', event, targetUrl);
return models.Webhook.destroy({id: webhookId}, options).catch(() => {
common.logging.warn(`Unable to destroy webhook ${webhookId}`);
});
}
updateWebhookTriggerData(webhookId, {
last_triggered_at: triggeredAt,
last_triggered_status: err.statusCode
});
common.logging.error(new common.errors.GhostError({
err: err,
context: {
id: webhookId,
event: event,
target_url: targetUrl,
payload: payload
}
}));
});
});
}
function trigger(event, payload, options) {
let tasks;
function doQuery(options) {
return models.Webhook.findAllByEvent(event, options);
}
tasks = [
doQuery,
_.partialRight(makeRequests, payload, options)
];
return pipeline(tasks, options);
}
module.exports = trigger;