Skip to content

Instantly share code, notes, and snippets.

@leocxy
Last active November 2, 2021 22:11
Show Gist options
  • Save leocxy/cb6e14df1c436133f9f422b89ce64526 to your computer and use it in GitHub Desktop.
Save leocxy/cb6e14df1c436133f9f422b89ce64526 to your computer and use it in GitHub Desktop.
fetch Shopify Customer Timeline for capture the email changes
/**
* Fetch customer's email change records and render a csv file, you must copy and pates the code at Shopify Admin console
*
* You need to update some variables
* change "url" to your store url
* change "data" to your customer ids
* change "token" to your token
*/
class httpClient {
constructor() {
// You need to capture your token
self.token = 'TOKEN'
self.headers = {
'accept': 'application/json',
'content-type': 'application/json',
'x-csrf-token': self.token
}
// You need to update your store url
self.url = 'https://your-store.myshopify.com/admin/internal/web/graphql/core?operation=Timeline'
self.query = `query Timeline($id: ID!, $first: Int, $last: Int, $after: String, $before: String) {
staffMember {
id
initials
__typename
}
node(id: $id) {
id
... on HasEvents {
events(
first: $first
last: $last
after: $after
before: $before
sortKey: CREATED_AT
reverse: true
) {
edges {
cursor
node {
...TimelineEvent
__typename
}
__typename
}
pageInfo {
hasNextPage
hasPreviousPage
__typename
}
__typename
}
__typename
}
__typename
}
}
fragment TimelineEvent on Event {
id
createdAt
criticalAlert
merchantVisible
message
... on BasicEvent {
id
attributeToApp
attributeToUser
additionalContent
secondaryMessage
appIcon {
id
altText
imgSrc: url(transform: {maxWidth: 50, maxHeight: 50})
__typename
}
__typename
}
... on NotificationSentEvent {
id
createdAt
merchantVisible
message
method
resendable
subject
appIcon {
id
altText
imgSrc: url(transform: {maxWidth: 50, maxHeight: 50})
__typename
}
__typename
}
__typename
}
`
self.csvContent = 'data:text/csv;charset=utf-8,'
self.csvContent += '"ID","From","To","Time"\n'
}
run () {
// You need to find the customer id here
const data = [123456789, 123456788, 123456787]
let promises = []
data.forEach((cid, i) => {
promises.push(this.query(cid, i))
})
Promise.all(promises).then((results) => {
results.forEach(result => {
let emails, cid
cid = result?.data.node.id.split('/').pop()
result = result?.data.node.events.edges
if (result !== null) {
result = result.filter(edge => edge.node.message.includes('eWeb Integration changed this customer\'s email from'))
if (result.length > 0) {
result.forEach(edge => {
emails = edge.node.message.substring(0, edge.node.message.length - 1).split('from')[1].split(' to ')
emails.map(email => `"${email.trim()}"` )
self.csvContent += `"${cid}",` + emails.join(',') + `,"${edge.node.createdAt}"\n`
})
}
}
})
this.download()
})
}
query (cid, i) {
return new Promise((resolve) => {
setTimeout(async () => {
const variables = {
id: `gid://shopify/Customer/${cid}`,
first: 15,
}
let result = await fetch(self.url, {
method: 'POST',
headers: self.headers,
body: JSON.stringify({query: self.query, variables, operationName: 'Timeline'})
}).then(res => res.json())
resolve(result)
}, i * 100)
})
}
download() {
const encodedUri = encodeURI(self.csvContent);
const link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "customer_email.csv");
document.body.appendChild(link); // Required for FF
link.click(); // This will download the data file named "my
}
}
const http = new httpClient()
http.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment