Recent searches


No recent searches

Reset the Primary Email Address to the original value!



Posted Mar 29, 2023

Hi, I have developed a Zendesk Support App that overwrites the primary email address of the end user with a sub email address of the actual requester. The sub email address is an identity of the end user. The app also works fine, I can change the email addresses, at a button click in the app, and switch back. However, I am currently trying to create a reset that will automatically reset the email addresses back to their original state. This reset should be triggered after the agent replies to the requester's ticket and clicks „Submit as new".

Here is my code from the main.js:

// The function to retrieve the primary email address of the end user.
async function getPrimaryEmailAddress(client) {
const{"ticket.requester.id": requesterId }=await client.get(
"ticket.requester.id"
);
const response =await client.request({
url:`/api/v2/users/${requesterId}`,
type:"GET",
});
const userData = response.user;
return userData.email;
}

// The function to retrieve the ticket field ID for "Primary address".
async function getPrimaryCustomFieldID(client) {
const response =await client.request({
url:"/api/v2/ticket_fields",
type:"GET",
});
const ticketFields = response.ticket_fields;
const primaryField = ticketFields.find(
(field)=> field.title==="Primäradresse"
);
return primaryField.id;
}

// The function to store the primary email address in the ticket field "Primary address".
async function savePrimaryEmailAddress(
client,
primaryEmailAddress,
primaryCustomFieldID
) {
await client.set(
`ticket.customField:custom_field_${primaryCustomFieldID}`,
primaryEmailAddress
);
console.log(
"Primary email address saved to ticket field:",
primaryEmailAddress
);
}

// The function to retrieve the primary email address of the end user.
function originalPrimaryEmailAddress() {
}

async function originalPrimaryCustomFieldID(client) {
const response =await client.request({
url:"/api/v2/ticket_fields",
type:"GET",
});
const ticketFields = response.ticket_fields;
const originalPrimaryField = ticketFields.find(
(field)=> field.title==="OriginalPrimäradresse"
);
return originalPrimaryField.id;
}

async function saveOriginalPrimaryEmailAddress(
client,
originalPrimaryEmailAddress,
originalPrimaryCustomFieldID
) {
await client.set(
`ticket.customField:custom_field_${originalPrimaryCustomFieldID}`,
originalPrimaryEmailAddress
);
console.log(
"Primary email address saved to ticket field:",
originalPrimaryEmailAddress
);
}

// Function to retrieve the ticket field ID for "Secondary address".
async function getSecondaryCustomFieldID(client) {
const response =await client.request({
url:"/api/v2/ticket_fields",
type:"GET",
});
const ticketFields = response.ticket_fields;
const secondaryField = ticketFields.find(
(field)=> field.title==="Sekundäradresse"
);
return secondaryField.id;
}

// Function to store the source email address in the ticket field "Secondary address".
async function saveSourceEmailAddress(
client,
sourceEmailAddress,
secondaryCustomFieldID
) {
if(sourceEmailAddress){
await client.set(
`ticket.customField:custom_field_${secondaryCustomFieldID}`,
sourceEmailAddress
);
console.log(
"Source email address saved to ticket field:",
sourceEmailAddress
);
}else{
console.warn("No source email address found.");
}
}

// Function to retrieve all identities of the end user.
async function getUserEmailIdentities(client, userId) {
const response =await client.request({
url:`/api/v2/users/${userId}/identities.json`,
type:"GET",
});
console.log(response);
if(!response.identities|| response.identities.length===0){
console.error("Keine Identitäten gefunden.");
return[];
}

return response.identities;
}

// Function to display a notification in the HTML element.
function showNotification(type, message) {
// Show notification in HTML element
const notificationElement = document.getElementById("notification");
notificationElement.style.display = "block";
notificationElement.textContent = message;
notificationElement.style.color = type === "success" ? "green" : "red";
}

// Function to create and display the dropdown menu with identities.
function createIdentityDropdown(identities, primaryEmailAddress) {
const identitySelectorContainer = document.getElementById(
"identity-selector-container"
);
const identitySelector = document.getElementById("identity-selector");

// Empty the dropdown menu if it is already populated
identitySelector.innerHTML = "";

// show Dropdown-Menü
identitySelectorContainer.style.display = "block";
}

// Function to retrieve the ticket field ID for "alternate field
async function getAlternateCustomFieldID(client) {
const response =await client.request({
url:"/api/v2/ticket_fields",
type:"GET",
});
const ticketFields = response.ticket_fields;
const alternateField = ticketFields.find(
(field)=> field.title==="Ausweichfeld"
);
return alternateField.id;
}

// Function to save the selected e-mail address from the drop-down menu in the ticket field "Alternate field
async function saveSelectedEmailAddress(
client,
selectedEmailAddress,
alternateCustomFieldID
) {
await client.set(
`ticket.customField:custom_field_${alternateCustomFieldID}`,
selectedEmailAddress
);
console.log(
"Selected email address saved to ticket field:",
selectedEmailAddress
);
}

const email = "myemail@gmail.com";
const password = "secret-password";
const authorizationHeader = "Basic " + btoa(email + ":" + password);
const contentTypeHeader = "application/json";

const options = {
headers:{
Authorization: authorizationHeader,
"Content-Type": contentTypeHeader,
Accept:"application/json",
},
};

async function updatePrimaryEmailAddress(client, userId, newPrimaryEmail) {
const userEmailIdentities =await getUserEmailIdentities(client, userId);
console.log("UserEmailIdentities ", userEmailIdentities);
const primaryIdentity = userEmailIdentities.find(
(identity)=> identity.primary
);

if(!primaryIdentity){
console.error("Keine primäre Identität gefunden.");
return;
}
console.log("PrimaryIdentity", primaryIdentity);
const newPrimaryIdentity = userEmailIdentities.find(
(identity)=>
!identity.primary&&
identity.verified &&
identity.value === newPrimaryEmail
);
console.log("newPrimaryIdentity", newPrimaryIdentity);

if(!newPrimaryIdentity){
console.error("Keine neue primäre Identität gefunden.");
return;
}

if(!primaryIdentity ||!newPrimaryIdentity){
console.error(
"Fehler beim Finden der primären oder neuen primären Identität."
);
return;
}

try{
await client.request({
url:`/api/v2/users/${userId}/identities/${newPrimaryIdentity.id}/make_primary`,
type:"PUT",
contentType:"application/json",
data: JSON.stringify({identity:{primary:true}}),
headers: options.headers,
});

console.log("Primäre E-Mail-Adresse aktualisiert.");
return newPrimaryIdentity.value;
}catch(error){
console.error(
"Fehler beim Aktualisieren der primären E-Mail-Adresse:",
error
);
}
}

// Main function to start the process
async function main() {
const client = ZAFClient.init();
document.addEventListener("DOMContentLoaded", function () {
client.on("app.registered", async () => {
try{
const primaryEmailAddress =await getPrimaryEmailAddress(client);
const primaryCustomFieldID =await getPrimaryCustomFieldID(client);
console.log(primaryEmailAddress);
console.log(primaryCustomFieldID);
await savePrimaryEmailAddress(
client,
primaryEmailAddress,
primaryCustomFieldID
);
const requesterId =(await client.get("ticket.requester.id"))[
"ticket.requester.id"
];
console.log("Requester ID:", requesterId);
const getOriginalPrimaryEmailAddress =originalPrimaryEmailAddress();
const getOriginalPrimaryCustomFieldID =
await originalPrimaryCustomFieldID(client);
await savePrimaryEmailAddress(
client,
getOriginalPrimaryEmailAddress,
getOriginalPrimaryCustomFieldID
);
console.log(getOriginalPrimaryEmailAddress);
console.log(getOriginalPrimaryCustomFieldID);
const userEmailIdentities =await getUserEmailIdentities(
client,
requesterId
);
console.log("UserEmailIdentities:", userEmailIdentities);
const sourceEmailData =await getSourceEmailAddress(client);
console.log("Source email data:", sourceEmailData);
const originalRecipients = sourceEmailData
? sourceEmailData.original_recipients
:[];
console.log("Original recipients:", originalRecipients);
// Find a matching identity that is not the primary email address.
const secondaryEmailAddress =findMatchingIdentity(
userEmailIdentities.map((identity) => identity.value),
originalRecipients,
primaryEmailAddress
);
console.log("Secondary email address:", secondaryEmailAddress);
const secondaryCustomFieldID =await getSecondaryCustomFieldID(client);
console.log(secondaryCustomFieldID);
await saveSourceEmailAddress(
client,
secondaryEmailAddress,
secondaryCustomFieldID
);
// Compare primary address and secondary address and display notification if required.
const primaryFieldValueObject =await client.get(
`ticket.customField:custom_field_${primaryCustomFieldID}`
);
console.log("PrimaryFieldValueObject:", primaryFieldValueObject);
const primaryFieldValue =
primaryFieldValueObject[
`ticket.customField:custom_field_${primaryCustomFieldID}`
];
console.log("Primary field value:", primaryFieldValue);
const secondaryFieldValueObject =await client.get(
`ticket.customField:custom_field_${secondaryCustomFieldID}`
);
console.log("SecondaryFieldValueObject:", secondaryFieldValueObject);
const secondaryFieldValue =
secondaryFieldValueObject[
`ticket.customField:custom_field_${secondaryCustomFieldID}`
];
console.log("Secondary field value:", secondaryFieldValue);

if(
primaryFieldValue === primaryEmailAddress &&
secondaryFieldValue === null
){
showNotification(
"success",
"Die Anfrage kommt von der primären E-Mail-Adresse."
);
} else if (
primaryFieldValue === primaryEmailAddress &&
secondaryFieldValue !== primaryEmailAddress
){
showNotification(
"warning",
"Die Anfrage kommt NICHT von der primären E-Mail-Adresse."
);
createIdentityDropdown(userEmailIdentities, primaryEmailAddress);
}

// Add button click handler
const submitButton = document.getElementById("submit-button");
submitButton.addEventListener("click", async () => {
const identitySelector = document.getElementById("identity-selector");
const selectedEmailAddress = identitySelector.value;
const alternateCustomFieldID =await getAlternateCustomFieldID(
client
);
// Save selected e-mail address from the drop-down menu in the ticket field "Alternate field
await saveSelectedEmailAddress(
client,
selectedEmailAddress,
alternateCustomFieldID
);

// Check if the condition for the update is fulfilled
// and perform the necessary updates
// e.g. call the `updatePrimaryEmailAddress` function.
const updatedPrimaryEmail =await updatePrimaryEmailAddress(
client,
requesterId,
selectedEmailAddress
);
console.log(updatedPrimaryEmail);
});
}catch(error){
console.error("Error in main function:", error);
}
});
client.on("ticket.submit.done", async () => {
try{
async function origPrimaryCustomFieldID(client){
const response =await client.request({
url:"/api/v2/ticket_fields",
type:"GET",
});
const ticketFields = response.ticket_fields;
const originalPrimaryField = ticketFields.find(
(field)=> field.title==="OriginalPrimäradresse"
);
return originalPrimaryField.id;
}

const getOrigiPrimaryCustomFieldID =await origPrimaryCustomFieldID(
client
);
console.log(getOrigiPrimaryCustomFieldID);
const origiEmail=(
await client.get(
`ticket.customField:custom_field_${getOrigiPrimaryCustomFieldID}`
)
)[`ticket.customField:custom_field_${getOrigiPrimaryCustomFieldID}`];
console.log(`Original email address: ${origiEmail}`);

const requesterId =(await client.get("ticket.requester.id"))[
"ticket.requester.id"
];

await updatePrimaryEmailAddress(
client,
requesterId,
originalPrimaryFieldValue
);
}catch(error){
console.error("Error in main function:", error);
}
});
});
}

main();

Currently I save the original primary email address, hard coded into the ticket field "OriginalPrimaryAddress". Of course I don't want to have this. Unfortunately, I'm not sure how to restore the original primary email address!

 

 

The issue is that our customer has multiple identities for one end user. Depending on the identity from which a ticket is created, a message should also be sent to this identity from the agent. For this purpose, the support app is developed to provide this functionality and to restore the original state after each response from the agent.

 

Can you maybe help me there somehow or show me another possibility?

 

Best Regards

Wilhelm Lenz

 


0

6

6 comments

image avatar

Greg Katechis

Zendesk Developer Advocacy

Hi Wilhelm! I reviewed your post and I would like to ask some clarifying questions...

Is the issue that you're trying to solve here that you just don't want to save the original email address to a ticket field? If that's the case, you could potentially save the email address to local storage, but any other suggestions that I have would be pretty hacky and worse than what you're already doing.

If there is another issue, could you explain in some more detail what is going wrong? Are there any console errors that you can share?

0


Hello Greg,

but I want to save the email to a ticket field, the code before the "client.on("ticket.submit.done")" works fine too, I have no problems with that. The problem is...

when I open a ticket as an agent and select the correct requester address in the app to send my message to the correct person, the sub email address becomes the primary email address. So that works. But if I then send the message using the "Submit as New" or "Submit as Open" or similar button in the ticket, then the Primary Email Address should be reset to the original state. Unfortunately this doesn't work and I can't currently understand why. My code after the "submit.done" works elsewhere. Inside the "submit.done" it doesn't seem to be executed though, which I find strange. Some functions or even console outputs seem to be executed, just not what I have implemented there at the moment. But as already said, the code itself works elsewhere outside of the "submit.done".

0


image avatar

Greg Katechis

Zendesk Developer Advocacy

It's difficult to say exactly where this may be going wrong, so I'm wondering if you've stepped through this with a debugger so you can see exactly at what point in the process the code breaks down? If you haven't, could you try that and let us know if you find our where the problem is and can't figure out the solution?

0


Hi Greg, I have run through this with a debbugger. This breaks after I send the ticket as an agent to the requester. However, I want it to reset the Primary Email Address right after sending the message.

0


Is it generally possible in Zendesk to change the Primary Email Address through the Support App (which I already do with my app) and then reset it again after submitting the ticket (which is not working right now)? When changing the primary email address through the app, a secondary email address of the end user becomes the primary email address and the primary email address becomes the secondary email address. What can I do to reset this after the agent sends the message on a ticket? I use the /users endpoint for requests. Should I rather use the endpoint /end_user? And if I should use the /end_user endpoint, do I need to change only this url parameter or also all other parameters?

Also, I can't save the Primary Email Address to a fixed point when reading to be able to access it again to reset the Primary Email Address, since the Primary Email Address reading is done from the created field. But since I change the primary email address, the field is also updated. Is it possible to lock fields against updates?

Thanks a lot for your help

0


Hi Greg,

I have been able to solve my problem in a different way. But now I have another question...

When I replace the primary email address with a sub email address using "make_primary", it doesn't show up directly in the ticket fields and user data unless I refresh the browser. The same is when I start the reset function to reset the primary email address. The reset function always starts when I open a ticket and it works. Only the display in the UI is not updated directly, only when refreshing the browser. Sometimes the browser has to be refreshed two or three times to see the correct result in the UI.

The question is:

Is there a way to see the refresh directly without doing a browser refresh in the code? This is not very user friendly otherwise.

0


Please sign in to leave a comment.

Didn't find what you're looking for?

New post