Skip to content

Instantly share code, notes, and snippets.

@mkiser
Last active September 5, 2024 20:10
Show Gist options
  • Select an option

  • Save mkiser/fabcb9c5a8480ff96e58ee6cd5d54760 to your computer and use it in GitHub Desktop.

Select an option

Save mkiser/fabcb9c5a8480ff96e58ee6cd5d54760 to your computer and use it in GitHub Desktop.
function getContextualAddOn(e) {
let card = CardService.newCardBuilder();
// Log the event object
Logger.log("Event object: " + JSON.stringify(e));
// Check if the event object has the threadId
if (e && e.gmail && e.gmail.threadId) {
let threadId = e.gmail.threadId;
// Use the GmailApp to fetch the thread by ID
let thread = GmailApp.getThreadById(threadId);
// Get the first message in the thread
let message = thread.getMessages()[0];
// Retrieve the "from" address (sender email with display name)
let fromField = message.getFrom();
// Extract the email address using a regular expression
let email = extractEmailAddress(fromField);
// Call Mailchimp API
let mailchimpInfo = getMailchimpInfo(email);
// Call Memberful API
let memberfulInfo = getMemberfulInfo(email);
// Display the email address in the card
card.addSection(
CardService.newCardSection().addWidget(
CardService.newTextParagraph().setText("Email: " + email)
)
);
// Display Mailchimp Info
card.addSection(
CardService.newCardSection()
.setHeader("Mailchimp Status")
.addWidget(CardService.newTextParagraph().setText(mailchimpInfo))
);
// Display Memberful Info
card.addSection(
CardService.newCardSection()
.setHeader("Memberful Plan")
.addWidget(CardService.newTextParagraph().setText(memberfulInfo))
);
} else {
// Fallback error if no threadId is available
Logger.log("Could not retrieve threadId");
card.addSection(
CardService.newCardSection().addWidget(
CardService.newTextParagraph().setText("Could not retrieve the email address. Make sure you're viewing an email.")
)
);
}
return card.build();
}
// Extract the email address from a string
function extractEmailAddress(fromField) {
// Regex extracts the email address from the "From" field
let emailMatch = fromField.match(/<(.+)>/);
if (emailMatch && emailMatch[1]) {
return emailMatch[1];
}
return fromField; // If no match, return the whole string
}
// Get Mailchimp info for the email
function getMailchimpInfo(email) {
let apiKey = '<API KEY>';
let serverPrefix = '<SERVER PREFIX>'; // e.g., 'us19'
let listUrl = `https://${serverPrefix}.api.mailchimp.com/3.0/lists`;
let headers = {
"Authorization": `Bearer ${apiKey}`
};
let options = {
"method": "get",
"headers": headers,
"muteHttpExceptions": true // Prevents script from failing on non-200 responses
};
try {
// Step 1: Fetch all lists
let listResponse = UrlFetchApp.fetch(listUrl, options);
if (listResponse.getResponseCode() !== 200) {
return "Error fetching Mailchimp lists: " + listResponse.getContentText();
}
let listsData = JSON.parse(listResponse.getContentText());
let lists = listsData.lists;
let subscribedLists = [];
// Step 2: Check each list if the email is subscribed
for (let i = 0; i < lists.length; i++) {
let listId = lists[i].id;
let listName = lists[i].name;
// Use the subscriber hash to check if a member exists on a specific list
let subscriberHash = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, email.toLowerCase()).map(function(byte) {
return (byte < 0 ? byte + 256 : byte).toString(16).padStart(2, '0');
}).join('');
let memberUrl = `https://${serverPrefix}.api.mailchimp.com/3.0/lists/${listId}/members/${subscriberHash}`;
let memberResponse = UrlFetchApp.fetch(memberUrl, options);
// 404 error handling if the member is not found
if (memberResponse.getResponseCode() === 404) {
Logger.log(`Email not found in list: ${listName}`);
continue; // Skip to the next list if member not found
} else if (memberResponse.getResponseCode() !== 200) {
return `Error fetching member data from list ${listName}: ${memberResponse.getContentText()}`;
}
let memberData = JSON.parse(memberResponse.getContentText());
// Only add to the list if the user is subscribed
if (memberData.status === "subscribed") {
subscribedLists.push(`- ${listName}`); // Add the list name to the subscribed list with bullet points
}
}
// Step 3: Return formatted subscribed list names
if (subscribedLists.length > 0) {
return `Subscribed to:\n${subscribedLists.join("\n")}`;
} else {
return "No subscriptions found.";
}
} catch (error) {
Logger.log("Error fetching Mailchimp data: " + error);
return "Error fetching Mailchimp data.";
}
}
// Get Memberful info for the email
function getMemberfulInfo(email) {
let apiKey = '<API KEY>';
let url = 'https://<URL>.memberful.com/api/graphql';
let query = `
query {
memberByEmail(email: "${email}") {
fullName
subscriptions {
plan {
name
}
active
}
}
}
`;
let options = {
"method": "post",
"headers": {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
"payload": JSON.stringify({ query: query })
};
try {
let response = UrlFetchApp.fetch(url, options);
let data = JSON.parse(response.getContentText());
// Log the entire response for debugging
Logger.log("Memberful API Response: " + JSON.stringify(data));
// Check if member data exists
if (data && data.data && data.data.memberByEmail) {
let member = data.data.memberByEmail;
// Store active and inactive subscriptions
let activeSubscriptions = [];
let inactiveSubscriptions = [];
// Loop through all subscriptions and categorize them
if (member.subscriptions.length > 0) {
for (let i = 0; i < member.subscriptions.length; i++) {
let subscription = member.subscriptions[i];
let planName = subscription.plan.name;
let isActive = subscription.active;
// Format the subscription and categorize them
if (isActive) {
activeSubscriptions.push(`- ${planName}`);
} else {
inactiveSubscriptions.push(`- ${planName}`);
}
}
}
// Format the output string
let formattedSubscriptions = [];
if (activeSubscriptions.length > 0) {
formattedSubscriptions.push("Active:\n" + activeSubscriptions.join("\n"));
}
if (inactiveSubscriptions.length > 0) {
formattedSubscriptions.push("Inactive:\n" + inactiveSubscriptions.join("\n"));
}
// Return the formatted string
if (formattedSubscriptions.length > 0) {
return formattedSubscriptions.join("\n\n"); // Separate active/inactive with a newline
} else {
return "No membership found.";
}
} else {
return "No membership found.";
}
} catch (error) {
Logger.log("Error fetching Memberful data: " + error);
return "Error fetching Memberful data.";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment