Skip to content

Instantly share code, notes, and snippets.

@iamkevingreen
Last active October 20, 2023 06:55
Show Gist options
  • Save iamkevingreen/3872f5acbaf5b100a8ebc02e4d95a03e to your computer and use it in GitHub Desktop.
Save iamkevingreen/3872f5acbaf5b100a8ebc02e4d95a03e to your computer and use it in GitHub Desktop.
const sanityClient = require('@sanity/client');
const crypto = require('crypto');
const {
SANITY_API_TOKEN,
SANITY_PROJECT_ID,
SANITY_DATASET,
SHOPIFY_SECRET
} = process.env;
const client = sanityClient({
projectId: SANITY_PROJECT_ID,
dataset: SANITY_DATASET,
token: SANITY_API_TOKEN,
});
exports.handler = async (event, context) => {
if (event.httpMethod !== 'POST' || !event.body) {
return {
statusCode: 400,
body: ''
};
}
let data;
let hasVariantsToSync = false;
const hmac = event.headers['x-shopify-hmac-sha256']
try {
data = JSON.parse(event.body);
const generatedHash = crypto
.createHmac('sha256', SHOPIFY_SECRET)
.update(event.body)
.digest('base64')
if (generatedHash !== hmac) {
return {
statusCode: 400,
body: JSON.stringify({
error: 'Bad Webhook Request'
})
}
}
} catch (error) {
console.log('JSON parsing error:', error);
return {
statusCode: 400,
body: JSON.stringify({
error: 'Bad request body'
})
};
}
// Build our initial product
const product = {
_type: 'product',
_id: data.id.toString(),
productId: data.id,
title: data.title,
defaultPrice: data.variants[0].price,
slug: {
_type: 'slug',
current: data.handle
}
};
return client
.transaction()
.createIfNotExists(product)
.patch(data.id.toString(), patch => patch.set(product))
.commit()
.then(res => {
console.log(`Successfully updated/patched Product ${data.id} in Sanity`);
if (data.variants.length > 1) {
hasVariantsToSync = true;
return Promise.all(data.variants.map(variant => {
const variantData = {
_type: 'productVariant',
_id: variant.id.toString(),
productId: data.id,
variantId: variant.id,
title: data.title,
variantTitle: variant.title,
sku: variant.sku,
price: variant.price
};
return client
.transaction()
.createIfNotExists(variantData)
.patch(variant.id.toString(), patch => patch.set(variantData))
.commit()
.then(response => {
console.log(`Successfully updated/patched Variant ${variant.id} in Sanity`);
return response;
})
.catch(error => {
console.log('Sanity error:', error);
return error;
});
})).then(result => {
if (hasVariantsToSync) {
return client
.transaction()
.createIfNotExists(product)
.patch(data.id.toString(), patch => patch.set({
variants: data.variants.map(variant => ({
_type: 'reference',
_ref: variant.id.toString(),
_key: variant.id.toString(),
}))
}))
.commit()
.then(response => {
console.log(`Successfully added variant references to ${data.id} in Sanity`);
return {
statusCode: 200,
body: JSON.stringify(response)
};
})
.catch(error => {
console.log('Sanity error:', error);
return error;
});
} else {
return {
statusCode: 200,
body: JSON.stringify(res)
};
}
}).catch(error => {
console.log('Sanity error:', error);
return {
statusCode: 500,
body: JSON.stringify({
error: 'An internal server error has occurred',
})
};
});
} else {
return {
statusCode: 200,
body: JSON.stringify(res)
};
}
})
.catch(error => {
console.log('Sanity error:', error);
return {
statusCode: 500,
body: JSON.stringify({
error: 'An internal server error has occurred',
})
};
});
};
@alexcasche
Copy link

@iamkevingreen yeah right now we’re doing SSR so we can handle some server tasks. But netlify add ons could easily replace the need soon. Background jobs and some redis integration would be awesome. Fauna looks really cool too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment