Skip to content

Instantly share code, notes, and snippets.

@dugjason
Last active November 2, 2023 19:42
Show Gist options
  • Save dugjason/366be0ea9b22bbb79788b97bddaa0cee to your computer and use it in GitHub Desktop.
Save dugjason/366be0ea9b22bbb79788b97bddaa0cee to your computer and use it in GitHub Desktop.
Front API: Node.js script to merge contacts by email handle

merge-contacts.js

Uses the Front POST /contacts/merge API endpoint see docs to merge multiple contacts into a single contact record.

Installation

  1. Save the merge-contacts.js file to your local machine.
  2. Navigate to the directory you saved it.
  3. Run npm install axios to install the Axios HTTP client
  4. Edit the merge-contacts.js file to save your Front API token
  5. Edit the merge-contacts.js file to save your list of contacts to merge.
  6. When setup is complete, run node merge-contacts.js to execute the file. Progress will be printed to your terminal in real-time.

You should save the contacts as an array of arrays, with the primary contact listed first in each array.

Using the example provided in the code;

const emailArrays = [
  ['Marge.Hickle@example.com', 'Marge.Hickle@example.net', 'MHickle@example.net'],
  ['Bridie.Christiansen@example.com', 'Bridie.Christiansen@example.net'],
  ['Birdie.Schiller@example.com', 'Birdie.Schiller@example.net'],
]

For the first record, handles 'Marge.Hickle@example.net' and 'MHickle@example.net' will be merged into the 'Marge.Hickle@example.com' contact record.

const axios = require('axios');
// Your Front API token. Create one at Front Settings > Developers > API Tokens
const FRONT_API_TOKEN = 'YOUR_FRONT_API_TOKEN'
// Array of arrays of emails to merge.
// The first email will be the primary email, any subsequent emails in the array will be merged into the primary email.
// For this sample, the 'Marge.Hickle@example.com' contact will gain the secondary handles 'Marge.Hickle@example.net' and 'MHickle@example.net'
const emailArrays = [
['Marge.Hickle@example.com', 'Marge.Hickle@example.net', 'MHickle@example.net'],
['Bridie.Christiansen@example.com', 'Bridie.Christiansen@example.net'],
['Birdie.Schiller@example.com', 'Birdie.Schiller@example.net'],
]
async function run() {
for (const emails of emailArrays) {
const primaryEmail = emails[0]
const secondaryEmails = emails.slice(1)
const primaryId = await getContactIdByEmail(primaryEmail)
const mergePayload = {
target_contact_id: primaryId,
contact_ids: await Promise.all(secondaryEmails.map(async (email) => getContactIdByEmail(email))),
}
const response = await axios.post('https://api2.frontapp.com/contacts/merge', mergePayload, {
headers: {
'Authorization': `Bearer ${FRONT_API_TOKEN}`,
'Content-Type': 'application/json',
}
})
const mergedContact = response.data
console.log(`✅ ID: ${mergedContact.id} Name: ${mergedContact.name}\nEmails: ${mergedContact.handles.map((handle) => handle.handle).join(', ')}\n--`)
// Snooze for 1 second to avoid rate limiting
await snooze(1_000)
}
}
/**
* Given a contact email, return the contact ID
* @param {*} email
* @returns id (string)
*/
async function getContactIdByEmail(email) {
try {
const resp = await axios.get(`https://api2.frontapp.com/contacts/alt:email:${email}`, {
headers: {
'Authorization': `Bearer ${FRONT_API_TOKEN}`,
}
})
return resp.data.id
} catch (error) {
console.error("Error:", error)
throw error
}
}
/**
* Helper function to sleep the script for a given number of milliseconds.
* Helpful in avoiding rate limits.
* @param {*} ms Milliseconds to sleep for
*/
const snooze = ms => new Promise(resolve => setTimeout(resolve, ms));
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment