Last active
August 29, 2015 14:09
-
-
Save grncdr/e44b465f6e76c0bace8e to your computer and use it in GitHub Desktop.
Turn Contentful webhooks into Gengo jobs
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
var Bluebird = require('bluebird'); | |
var createContentfulClient = require('contentful-management').createClient; | |
var createGengoClient = require('gengo'); | |
var collectStream = Bluebird.promisify(require('collect-stream')); | |
var keys = Object.keys; | |
module.exports = checkForUntranslatedFields; | |
module.exports.schema = { | |
cmaAccessToken: { | |
type: 'string', | |
minLength: 32 | |
}, | |
gengoPublicKey: { | |
type: 'string', | |
minLength: 4 | |
}, | |
gengoPrivateKey: { | |
type: 'string', | |
minLength: 4 | |
}, | |
gengoSandbox: 'boolean', | |
gengoCallback: { | |
type: 'string', | |
default: 'http://hook.io/grncdr/gengo2contentful' | |
}, | |
spaceIdOverride: 'string', | |
entryIdOverride: 'string' | |
}; | |
function checkForUntranslatedFields (hook) { | |
var contentful = createContentfulClient({ accessToken: hook.params.cmaAccessToken }); | |
var gengoJobsAPI = Bluebird.promisifyAll( | |
createGengoClient(hook.params.gengoPublicKey, | |
hook.params.gengoPrivateKey, | |
hook.params.gengoSandbox).jobs | |
); | |
getEntry(hook, contentful).then(function (entry) { | |
if (entry) { | |
return getGengoJobs(entry).then(gengoJobsAPI.createAsync); | |
} else { | |
return { message: 'ignored' }; | |
} | |
}).then(function (result) { | |
hook.res.setHeader({ 'content-type': 'application/json' }); | |
hook.res.end(JSON.stringify(result)); | |
}).catch(function (err) { | |
hook.debug(err.stack); | |
hook.res.statusCode = 500; | |
hook.res.end(JSON.stringify({ message: err.message })); | |
}).done(); | |
function getGengoJobs (entry) { | |
var spacePath = '/spaces/' + entry.sys.space.sys.id; | |
var localesPath = spacePath + '/locales'; | |
var cTypePath = spacePath + '/content_types/' + entry.sys.contentType.sys.id + '/published'; | |
return Bluebird.join( | |
contentful.request(localesPath).get('items'), | |
contentful.request(cTypePath) | |
).spread(function (locales, contentType) { | |
var callbackUrl = hook.params.gengoCallback; | |
callbackUrl += (callbackUrl.indexOf('?') < 0) ? '?' : '&'; | |
callbackUrl += 'cmaAccessToken=' + hook.params.cmaAccessToken; | |
return createGengoPayload(locales, contentType, entry, callbackUrl); | |
}); | |
} | |
} | |
function getEntry (hook, contentful) { | |
if (hook.params.spaceIdOverride && hook.params.entryIdOverride) { | |
hook.debug('get entry from query params: ' + entryPath); | |
return contentful.request('/' + [ | |
'spaces', | |
hook.params.spaceIdOverride, | |
'entries', | |
hook.params.entryIdOverride, | |
'published' | |
].join('/')); | |
} | |
if (hook.req.headers['x-contentful-topic'] === "ContentManagement.Entry.publish") { | |
hook.debug('get entry from request body'); | |
return collectStream(hook.req).then(JSON.parse); | |
} | |
} | |
function createGengoPayload (locales, contentType, entry, callbackUrl) { | |
var fieldsById = lookup(contentType.fields, 'id'); | |
var fieldOrder = contentTypes.fields.map(function (f) { return f.id; }); | |
var defaultLocale = locales.filter(isDefault).pop(); | |
return keys(entry.fields).reduce(function (payload, fieldId) { | |
if (!fieldsById[fieldId].localized) { | |
return payload; | |
} | |
var field = entry.fields[fieldId]; | |
var source = field[defaultLocale.code]; | |
var fieldPostition = String(fieldOrder.indexOf(fieldId)); | |
if (!source) { | |
return payload; | |
} | |
locales.filter(function (l) { | |
return l.contentManagementApi && !l.default && !field[l.code]; | |
}).forEach(function (targetLocale) { | |
var jobId = [ | |
entry.sys.space.sys.id, | |
entry.sys.id, | |
fieldId, | |
targetLocale.code | |
].join('!'); | |
payload.as_group = true; // payload must be empty if there are no translations | |
payload[jobId] = { | |
custom_data: JSON.stringify({ | |
type: 'Field', | |
space: entry.sys.space.sys.id, | |
entry: entry.sys.id, | |
id: fieldId, | |
}), | |
src_lc: defaultLocale.code, | |
tgt_lc: locale.code, | |
body_src: source, | |
position: fieldPosition, | |
callback_url: callbackUrl, | |
}; | |
}); | |
return payload; | |
}); | |
} | |
function lookup (objects, prop) { | |
return objects.reduce(function (result, object) { | |
result[object[prop]] = object; | |
return result; | |
}, {}); | |
} | |
function isDefault (locale) { | |
return locale.default; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment