Sync Shopify customer data to Zendesk
Keep your Zendesk user profiles up-to-date by automatically capturing changes to customer information in Shopify. This hook handles both the creation of new profiles and updates to existing ones.
Prerequisites
- A Zendesk OAuth client and an OAuth connection named
zendeskwith theusers:writescope - Your Zendesk subdomain
Configuration
1) Set up trigger
Create a new hook in the Cloudhooks dashboard with "A customer is updated" as your trigger event. This trigger fires for both new and modified customers.
2) Configure authentication
Zendesk is retiring API tokens: new ones can no longer be created, and existing ones stop working on April 30, 2027. Authenticate with an OAuth connection instead:
- Create a Confidential OAuth client in Zendesk and an OAuth connection named
zendeskin your Cloudhooks Settings, as described in Example: Zendesk. Use theusers:writescope, which this hook needs to create and update users. - Set your Zendesk subdomain in the hook code:
const ZENDESK_SUBDOMAIN = 'YOUR_ZENDESK_SUBDOMAIN';Cloudhooks fetches and renews the access token, and the hook reads it from context.oauth.zendesk.
3) Implement the hook
Copy and paste the following code into your hook editor:
const ZENDESK_SUBDOMAIN = 'YOUR_ZENDESK_SUBDOMAIN';
module.exports = async function(payload, actions, context) {
const token = context.oauth.zendesk?.accessToken;
if (!token) {
console.error('No Zendesk access token available, see the run log for the reason');
return;
}
let userUpdate = {
name: payload.first_name + ' ' + payload.last_name,
email: payload.email,
skip_verify_email: true,
user_fields: {
shopifyCustomerId: payload.id.toString(),
},
};
const defaultAddress = payload.default_address ?? (payload.addresses && payload.addresses.find(address => address.default));
const phoneNumber = payload.phone ?? defaultAddress?.phone;
if (phoneNumber) {
userUpdate.phone = phoneNumber;
userUpdate.user_fields.phoneNumber = phoneNumber;
}
if (defaultAddress) {
const addressFields = {}
defaultAddress.address1 && (addressFields.address1 = defaultAddress.address1);
defaultAddress.address2 && (addressFields.address2 = defaultAddress.address2);
defaultAddress.city && (addressFields.city = defaultAddress.city);
defaultAddress.province && (addressFields.region = defaultAddress.province);
defaultAddress.zip && (addressFields.postalCode = defaultAddress.zip);
defaultAddress.country && (addressFields.country = defaultAddress.country);
userUpdate.user_fields = {...userUpdate.user_fields, ...addressFields}
}
try {
const result = await actions.http.post(
`https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/users/create_or_update.json`,
{ user: userUpdate },
{
headers: {
'Authorization': `Bearer ${token}`, 'Content-type': 'application/json'
}
}
);
if (result.status != '200' && result.status != '201' ) {
throw new Error(result.data);
}
} catch (err) {
console.error('Cannot update user in Zendesk: ', err);
}
}