Created
September 22, 2018 17:02
-
-
Save mmgj/d361ad83c99f52699a5bc3a8326fccfa to your computer and use it in GitHub Desktop.
Sanity -> Webtask.io
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
/** | |
* Cloud function triggered by changes in dataset which will generate metadata for art asset. | |
*/ | |
const Promise = require('es6-promise').Promise; | |
const sanityClient = require('@sanity/client'); | |
/** Setup */ | |
const client = token => sanityClient({ | |
projectId: '<projectId>', | |
dataset: '<dataSet>', | |
useCdn: false, | |
token | |
}); | |
function generateArtMetadata(asset, SANITY_TOKEN) { | |
return new Promise(function(resolve, reject) { | |
/** A bunch of async operations to generate metadata | |
* happens here. Omitted for sake of brevity and relevance. | |
**/ | |
}); | |
} | |
function validateAndPatch(id, SANITY_TOKEN, storage, recentRevisions = null) { | |
return new Promise((resolve, reject) => { | |
client(SANITY_TOKEN).fetch(`*[_id == "${id}"] {_id, _type, _rev, "asset": imageField.asset-> }[0]`).then(thing => { | |
/** Check for obvious fails and then go ahead with the patching */ | |
if(thing._type !== 'card') { | |
resolve(`WRONG TYPE > Exit 200`); | |
} else if (recentRevisions && recentRevisions.indexOf(thing._rev) > -1) { | |
resolve(`REVISION ID BLACKLISTED > Exit 200`); | |
} else if (thing.asset === undefined || thing.asset === null) { | |
resolve(`NO ART ASSET > Exit 200`); | |
} else { | |
/** Passed basic sanity checks. Let's roll! */ | |
generateArtMetadata(thing.asset).then(meta => { | |
client(SANITY_TOKEN) | |
.patch(thing._id) | |
.set({ | |
'imageField.palette': meta.palette, | |
'imageField.keyNumbers': meta.keyNumbers, | |
}) | |
.commit() | |
.then(patched => { | |
const blacklist = [patched._rev, ...recentRevisions].slice(0, 25); // Randomly chosen cutoff point at 25. | |
addRevisionToBlacklist(storage, blacklist).then(good => { | |
resolve(`GOOD: Document patched! Saved ${patched._rev} to blacklist!`); | |
}).catch(err => { | |
reject(`BAD: Document was patched, but failed to save revision with ID: ${patched._rev} to blacklist.` ); | |
}); | |
}) | |
.catch(err => { | |
reject('Failed at step [ patching document ] with error: ', err); | |
}); // EOF patch() | |
}) | |
.catch(err => { | |
reject('Failed at step [ generating metadata ] with error: ', err); | |
}); // EOF getArtDetails() | |
} | |
}) | |
.catch(err => { | |
reject('Failed at step [ initally fetching document ] with error: ', err); | |
}); // EOF client.fetch() | |
}); // EOF Promise() | |
} | |
/** Because we are listening to events of both 'create' and 'update' types | |
* we quickly realize that the patch operation a few lines up (if successful) will | |
* trigger its own 'update' event, and we are set for an infinite loop. | |
* There are probably several ways to deal with this, but I chose to save the | |
* revision ID (_rev) returned in patch() in the webtask storage and compare with | |
* revision ID of incoming events and exit if the revision ID originated here. | |
*/ | |
function getRevisionBlacklist(storage) { | |
return new Promise((resolve, reject) => { | |
storage.get((error, data) => { | |
if (error) reject(error); | |
resolve(data.blacklist); | |
}); | |
}); | |
} | |
function addRevisionToBlacklist(storage, blacklist) { | |
return new Promise((resolve, reject) => { | |
storage.set({ blacklist: blacklist }, (error) => { | |
if (error) reject(error); | |
resolve(); | |
}); | |
}); | |
} | |
module.exports = function(context, cb) { | |
const { storage } = context; | |
const { SANITY_TOKEN } = context.secrets; | |
const { created = [], updated = [] } = context.body.ids; | |
getRevisionBlacklist(storage).then(recentRevisions => { | |
const cards = [...created, ...updated].map(id => { | |
return validateAndPatch(id, SANITY_TOKEN, storage, recentRevisions); | |
}); | |
Promise.all(cards).then(good => { | |
console.log('Exit 200: ', good); | |
cb(null, 200); | |
}).catch(bad => { | |
console.log('Exit 500: ', bad); | |
cb(null, 500) | |
}); | |
}).catch(error => { | |
console.log('Exit 500 on first level: ', error) | |
cb(null, 500) | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment