Last active
November 7, 2023 10:57
-
-
Save edlaver/aad8220f1ee17fa45dc1246a499a35d7 to your computer and use it in GitHub Desktop.
Add as an update effect to a Gadget record that has your metafield.
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
module.exports = async ({ api, record, params, logger, connections }) => { | |
const metafieldNamespace = "<Your metafield namespace>"; | |
const metafieldKey = "<Your metafield key>"; | |
const metafieldType = "json" | |
const metafieldOwnerId = `gid://shopify/Shop/${record.id}`; // `record.id` here is the ID of our `shop` record | |
const gadgetFieldName = "<The matching field name in your gadget record, e.g. myMetafield>"; | |
// Check if record change includes our metafield data | |
if (record.changed(gadgetFieldName)) { | |
logger.info( | |
`"${gadgetFieldName}" record was changed, attempting to save to Shopify` | |
); | |
const recordChanges = record.changes(); | |
logger.debug({ record, recordChanges }, "Record changes"); | |
logger.debug("Checking for current Shopify connection"); | |
if (connections.shopify.current) { | |
// Check we're using an embedded app with shopify session token / tenancy. Should also prevent action from running on sync from Shopify... | |
const shopifyApi = connections.shopify.current; | |
// @ts-ignore | |
// shopifyApi.options.apiVersion = "2022-07"; // Override the version for this effect | |
let response; | |
try { | |
response = await shopifyApi.graphql( | |
` | |
mutation setMetafield($metafieldsSetInput: [MetafieldsSetInput!]!) { | |
metafieldsSet(metafields: $metafieldsSetInput) { | |
metafields { | |
id | |
namespace | |
key | |
} | |
userErrors { | |
field | |
message | |
} | |
} | |
} | |
`, | |
{ | |
metafieldsSetInput: [ | |
{ | |
namespace: metafieldNamespace, | |
key: metafieldKey, | |
type: metafieldType, | |
ownerId: metafieldOwnerId, | |
value: record[gadgetFieldName], | |
}, | |
], | |
} | |
); | |
} catch (err) { | |
logger.error( | |
err, | |
`Error running graphQL mutation - saving metafield "${gadgetFieldName}" to Shopify` | |
); | |
throw err; | |
} | |
if (response?.metafieldsSet?.userErrors?.length) { | |
const message = `User error(s) saving "${gadgetFieldName}" metafield to Shopify`; | |
logger.error(response?.metafieldsSet?.userErrors, message); | |
throw new Error(message); | |
} else { | |
logger.info( | |
response, | |
`"${gadgetFieldName}" metafield saved successfully to Shopify!` | |
); | |
} | |
} else { | |
logger.warn("Missing current Shopify connection"); | |
} | |
} else { | |
// Settings were not changed | |
logger.debug(`"${gadgetFieldName}" not changed, nothing to do...`); | |
} | |
}; |
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
// More generic version of original function, that takes params rather than hardcoding the variables | |
export async function writeMetafieldsFromGadgetRecord({ | |
metafieldNamespace, // <Your metafield namespace> | |
metafieldKey, // <Your metafield key> | |
metafieldType, // i.e. "json"; | |
metafieldOwnerId, // i.e. `gid://shopify/Shop/${record.id}`; // `record.id` here is the ID of our `shop` record | |
gadgetFieldName, // The matching field name in your gadget record, e.g. myMetafield | |
metafieldValue, // The value to set the metafield to, coerced to the correct type. See: https://shopify.dev/docs/apps/custom-data/metafields/types; | |
force, // Force the metafield to be written to Shopify, even if the value hasn't changed | |
record, // Context from Gadget | |
logger, // Context from Gadget | |
connections, // Context from Gadget | |
}) { | |
// Check if record change includes our metafield data | |
if (force || record.changed(gadgetFieldName)) { | |
logger.info( | |
`"${gadgetFieldName}" record was changed (or 'force' is set), attempting to save to Shopify` | |
); | |
const recordChanges = record.changes(); | |
logger.debug( | |
{ record, recordChanges }, | |
"writeMetafieldsFromGadgetRecord > Record changes" | |
); | |
logger.debug( | |
"writeMetafieldsFromGadgetRecord > Checking for current Shopify connection" | |
); | |
// Check we're using an embedded app with shopify session token / tenancy. Should also prevent action from running on sync from Shopify... | |
let shopifyApi = connections?.shopify?.current; | |
// Otherwise, try to get a connection for the shopId, assuming it's attached to the record | |
// TODO: Allow the shopId to be passed in as a param | |
// TODO: Work with a passed in `domain` as well, i.e. | |
// `const shopifyApi = await connections.shopify.forShopDomain("mycoolshop.myshopify.com");` | |
if (!shopifyApi && record.shopId) { | |
shopifyApi = await connections.shopify.forShopId(record.shopId); | |
} | |
if (!shopifyApi) { | |
logger.error( | |
{ connections, record }, | |
"writeMetafieldsFromGadgetRecord > Missing required Shopify connection" | |
); | |
return; | |
} | |
let response; | |
try { | |
response = await shopifyApi.graphql( | |
`#graphql | |
mutation setMetafield($metafieldsSetInput: [MetafieldsSetInput!]!) { | |
metafieldsSet(metafields: $metafieldsSetInput) { | |
metafields { | |
id | |
namespace | |
key | |
} | |
userErrors { | |
field | |
message | |
} | |
} | |
} | |
`, | |
{ | |
metafieldsSetInput: [ | |
{ | |
namespace: metafieldNamespace, | |
key: metafieldKey, | |
type: metafieldType, | |
ownerId: metafieldOwnerId, | |
value: metafieldValue, | |
}, | |
], | |
} | |
); | |
} catch (err) { | |
logger.error( | |
{ err }, | |
`writeMetafieldsFromGadgetRecord > Error running graphQL mutation - saving metafield "${gadgetFieldName}" to Shopify` | |
); | |
throw err; | |
} | |
if (response?.metafieldsSet?.userErrors?.length) { | |
const message = `writeMetafieldsFromGadgetRecord > User error(s) saving "${gadgetFieldName}" metafield to Shopify`; | |
logger.error( | |
{ userErrors: response?.metafieldsSet?.userErrors }, | |
message | |
); | |
throw new Error(message); | |
} else { | |
logger.info( | |
response, | |
`writeMetafieldsFromGadgetRecord > "${gadgetFieldName}" metafield saved successfully to Shopify!` | |
); | |
} | |
} else { | |
// Settings were not changed | |
logger.debug( | |
`writeMetafieldsFromGadgetRecord > "${gadgetFieldName}" not changed, nothing to do...` | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment