-
-
Save mattgrah-am/0cbe9f5b9dc2a2bb08ef59f5030ef78c to your computer and use it in GitHub Desktop.
Webhook
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
import StoryblokClient, { ISbStory } from "storyblok-js-client"; | |
import algoliasearch from "algoliasearch"; | |
import crypto from "crypto"; | |
export default defineEventHandler(async (event) => { | |
const config = useRuntimeConfig(); | |
// Check sb webhook secret matches .env secret | |
const signature = getHeader(event, "webhook-signature"); | |
const reqBody = await readBody(event); | |
const webhookSecret = config.algolia.webhookSecret; | |
try { | |
const bodyHmac = crypto | |
.createHmac("sha1", webhookSecret) | |
.update(JSON.stringify(reqBody)) | |
.digest("hex"); | |
if (!signature || bodyHmac !== signature) { | |
throw createError({ | |
statusCode: 401, | |
statusMessage: "You are not allowed to access this resource", | |
}); | |
} | |
} catch (error: any) { | |
console.log(error); | |
throw createError({ | |
statusCode: error.statusCode || 500, | |
statusMessage: | |
error.message || error.statusMessage || "Internal Server Error", | |
}); | |
} | |
// init algolia | |
const algolia = algoliasearch( | |
config.public.algolia.applicationId, | |
config.algolia.writeApiKey | |
); | |
// init storyblok | |
const storyblok = new StoryblokClient({ | |
accessToken: config.algolia.sbAccessToken, | |
region: "us", | |
}); | |
try { | |
const response: ISbStory = await storyblok.get( | |
`cdn/stories/${reqBody.full_slug}`, | |
{ | |
version: "published", | |
cv: Date.now(), | |
} | |
); | |
const sbUUID = response.data.story.uuid; | |
const sbStory: any = response.data.story; | |
const index = algolia.initIndex(String(config.algolia.indexName)); | |
// Check reqBody action and if published add / update the record on algolia | |
if (reqBody.action === "published") { | |
sbStory.objectID = sbStory.uuid; | |
try { | |
await index | |
.saveObject(sbStory, { | |
autoGenerateObjectIDIfNotExist: false, | |
}) | |
.wait(); | |
} catch (error: any) { | |
console.log(error); | |
throw createError({ | |
statusCode: error.statusCode || 500, | |
statusMessage: | |
error.message || error.statusMessage || "Internal Server Error", | |
}); | |
} finally { | |
setHeader(event, "Content-Type", "application/json"); | |
setResponseStatus(event, 202, "Accepted"); | |
send(event); | |
} | |
// Check reqBody action and if unpublished or deleted, delete the record on algolia | |
} else if ( | |
reqBody.action === "unpublished" || | |
reqBody.action === "deleted" | |
) { | |
try { | |
await index.deleteObject(sbUUID).wait(); | |
} catch (error: any) { | |
console.log(error); | |
throw createError({ | |
statusCode: error.statusCode || 500, | |
statusMessage: | |
error.message || error.statusMessage || "Internal Server Error", | |
}); | |
} finally { | |
setHeader(event, "Content-Type", "application/json"); | |
setResponseStatus(event, 202, "Accepted"); | |
send(event); | |
} | |
} else { | |
throw createError({ | |
statusCode: 400, | |
statusMessage: "Something went wrong...", | |
}); | |
} | |
return ""; | |
} catch (error: any) { | |
console.log(error); | |
throw createError({ | |
statusCode: error.statusCode || 500, | |
statusMessage: | |
error.message || error.statusMessage || "Internal Server Error", | |
}); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment