API request gets duplicated within milliseconds gap in both Freshdesk and Freshservice instances

Hi All,

I faced the same issue in both Freshdesk and Freshservice instances in different projects.

We have the requirements below,

  1. Integrating two Freshservice instances
  2. Integrating Freshdesk and thirdparty instance

We have implemented the OnTicketUpdate event to send the request to the another instance. Sometimes the API requests sends multiple time to the another instance which happens within in milliseconds. So we are not able to capture the duplicated requests from the log.

But the third party instance captured all the logs that we sends from Freshdesk.

I have shared all the logs and details that we trigger from Freshdesk. From that, I can confirm that we are sending only one request. We need help in identifying where this is getting updated as a duplicate request. I do not have any visibility of that because the entry is in another instance(Cloudcherry).

  1. Freshdesk log details

  1. Observations from cloudcherry

There are two requests in thirdparty instance(cloudcherry) for these tickets.
But for the one request from Freshdesk via Trigger NPS app why there are two requests in cloudcherry.
How and from where these two calls are triggered? Can you please shed some light here?

  1. Log Details
Line 111454: 2022-05-31 17:16:16.573 [INFO] Request : {"document_type":"NRIC","division_id":"TS","marketing_segment":"CBG","customer_account_type":"Consumer",

"group":"Email","location":"Freshdesk","mobile_number":"","ticket_Id":"461301","email":[xxxx@xxxcglobal.net](mailto:xxxx@xxxcglobal.net),"customer_title":"","customer_name":[xxxx@xxxglobal.net](mailto:xxxx@xxxglobal.net),

"customer_id":"77063326376","nationality":"","transaction_date":"2022-05-31T09:15:18Z","agent_id":"77045590272","agent_name":"Roxanne CUETA CSE-HQ2","group_name":"Tier-1 Customer Affairs","transaction_type":"Mobile GE / Appt","product_type":""}

Line 111463: 2022-05-31 17:16:16.726 [INFO] Request : {"document_type":"NRIC","division_id":"TS","marketing_segment":"CBG","customer_account_type":"Consumer",

"group":"Email","location":"Freshdesk","mobile_number":"","ticket_Id":"461301","email":[xxxx@xxxglobal.net](mailto:xxxx@xxxglobal.net),"customer_title":"","customer_name":[xxxx@xxxglobal.net](mailto:xxxx@xxxglobal.net),

"customer_id":"77063326376","nationality":"","transaction_date":"2022-05-31T09:15:18Z","agent_id":"77045590272","agent_name":"Roxanne CUETA CSE-HQ2","group_name":"Tier-1 Customer Affairs","transaction_type":"Mobile GE / Appt","product_type":""}

Line 17817: 2022-06-07 11:16:26.889 [INFO] Request : {"document_type":"NRIC","division_id":"TS","marketing_segment":"CBG","customer_account_type":"Consumer",

"group":"Email","location":"Freshdesk","mobile_number":"","ticket_Id":"471476","email":[cxxx_sixxxx_1984@hotmail.com](mailto:cxxx_sixxxx_1984@hotmail.com),"customer_title":"","customer_name":[Cxxx_sixxxx_1984@hotmail.com](mailto:Cxxx_sixxxx_1984@hotmail.com),

"customer_id":"77054848652","nationality":"","transaction_date":"2022-06-07T03:14:58Z","agent_id":"77052840723","agent_name":"Netomiai Freshdesk","group_name":"Tier-1 Customer Affairs","transaction_type":"Others","product_type":""}

Line 17824: 2022-06-07 11:16:26.974 [INFO] Request : {"document_type":"NRIC","division_id":"TS","marketing_segment":"CBG","customer_account_type":"Consumer",

"group":"Email","location":"Freshdesk","mobile_number":"","ticket_Id":"471476","email":[cxxx_sixxxx_1984@hotmail.com](mailto:cxxx_sixxxx_1984@hotmail.com),"customer_title":"","customer_name":[Cxxx_sixxxx_1984@hotmail.com](mailto:Cxxx_sixxxx_1984@hotmail.com),

"customer_id":"77054848652","nationality":"","transaction_date":"2022-06-07T03:14:58Z","agent_id":"77052840723","agent_name":"Netomiai Freshdesk","group_name":"Tier-1 Customer Affairs","transaction_type":"Others","product_type":""}

Kindly help us on this!

Are you seeing the onTicketUpdate get triggered twice for each change? Or, is the HTTP request inside onTicketUpdate getting called twice for each time the onTicketUpdate event is triggered?

Hi Kaustav,

The HTTP request inside onTicketUpdate getting called twice for each time the onTicketUpdate event is triggered.

Thanks. I cannot decipher anything meaningful from the log you have shared. Are you able to replicate this issue when doing testing locally with fdk? If so, the fdk.log file might prove useful.

I could not reproduce this issue. So this may be specific to your implementation, or something specific to the account.

There can be a few reasons why this can occur:

  1. This can happen if the first HTTP request is receiving an error and the request is getting re-tried because maxAttempts is set to 2.
  2. Something else might be triggering the event handler at the same time. This can happen if the same function is exposed as an SMI and some other part of the app (another function) is calling it.
  3. Some other function is triggering the same request.

Can you check to rule out the scenarios above? Can you also share the code of the HTTP request?

Hi @kaustavdm,

The issue is only occurring few times that too in production not for all the tickets. And also the duplication can’t be captured in log details. So, we have shared the third party log details where we got the duplication details. Because they are maintaining logs for milliseconds.

Please find my points below,

  1. So if the request is receiving an error, the request will be re-tried. But here we haven’t received the error log.
  2. We have implemented the APP in On ticket update event
  3. If some other function is triggered, that should have take few secs or it should have shown the respective logs too.

@App-Platform-Squad can someone help debug this? Apparently, this is happening only in production.

@kaustavdm,

Please have a look into the sample code.

Sample code:

function createFDTicket(payload,ticketObj, attchs = []) {
    return new Promise((resolve) => {
        let URL = `${getDomain('fd')}/api/v2/tickets`;
        
        let headers = {
            "Authorization": `Basic ${getToken('fd')}`,
            'Content-Type': 'multipart/form-data'
        };

        var options = {
            method: "POST",
            url: URL,
            headers: headers
        };
  console.log("options",options,ticketObj);
        let req = request(options,async function (err, res, body) {
			console.log("body",body);
			console.log("body",JSON.parse(body));
            if (!err && (res.statusCode == 200 || res.statusCode == 201)) {
                resolve(JSON.parse(body));
            } else {
				console.log("err",err);
                //reject(body);
				let errDesc =JSON.parse(body).errors;
				let e_content= "This to bring to your notice that integration has failed, and no ticket has been logged with AOT for your reported issue. Please refer to the error massage below."
				+"<br><br>"+"<a href="+getDomain('fs')+ "/helpdesk/tickets/" + payload['data']['ticket']['id']+"target='_blank' rel='noreferrer' heap-ignore='true' data-identifyelement='356'>Ticket ID #" +payload['data']['ticket']['id'] + "</a>&nbsp;<br><br>";
				 var htmlText="<table  style='" + " border: 1px solid black; border-collapse: collapse;"+"'><th style='" + " border: 1px solid black; border-collapse: collapse;"+"'>Field</th><th style='" + " border: 1px solid black; border-collapse: collapse;"+"'>Message</th>"              
				  for(var i=0;i<errDesc.length;i++){
				  htmlText=htmlText+"<tr><td style='" + " border: 1px solid black; border-collapse: collapse;"+"'>"+errDesc[i].field+"</td>"+"<td style='" + " border: 1px solid black; border-collapse: collapse;"+"'>"+errDesc[i].message+"</td></tr>"
				  }
					 htmlText=htmlText+"</table><br>";           
								
				var namelist =e_content+htmlText;
				/*..
				//Send To All Agents e-mail ID
				let agent_emailIds = await getAgents();
				console.log("agent_emailIds",agent_emailIds);*/
				 var emailobj = {
                  to: [{email: "dmt.philippines@bw-group.com "},{email: "Shadab.Ahmed@bw-group.com"},{email: "priyadarshini@jinnss.com"}],//[{email: "priyadarshini@jinnss.com"}],//..agent_emailIds,
                  from: {
                    email: "Alerts.Freshservice@bw-group.com"
                  },
                  subject: "ALERT - FAILED INTEGRATION"+"-#"+payload['data']['ticket']['id'],
                  html: namelist,//body,
                  accountId: payload.account_id//917828//payload.account_id
                };
				console.log(emailobj);
                sendmail(payload,emailobj);
                //reject(false);
            }
        });

        let form = req.form();
        //add form field value
        for (let key in ticketObj) {
            if (ticketObj.hasOwnProperty(key)) {
                // form.append(key, ticketObj[key]);
                let p_value = ticketObj[key];
				
                if (typeof p_value == 'string') {
                    form.append(key, p_value);
                } else if (Array.isArray(p_value)) {

                    for (var i = 0; i < p_value.length; i++) {
                        form.append(`${key}[]`, p_value[i]);
                    }

                }else if(typeof p_value == 'object'){
					//console.log("OBJECT");
					   for (let cust_key in p_value) {
						//console.log(`${key}[${cust_key}]`,p_value[cust_key]);
						form.append(`${key}[${cust_key}]`,p_value[cust_key]);
					   }
				}
				else {
                    form.append(key, JSON.stringify(p_value));
                }
            }
        }
        //add attchments
        for (let i = 0; i < attchs.length; i++) {

            form.append('attachments[]', request.get(attchs[i].url), { filename: attchs[i].filename, contentType: attchs[i].type })

        }
    })
}

Thanks for sharing the code snippet, @Priyadharshini_Ramas. While we wait for someone from the engineering team to help, I have a few quick observations about the code you have shared.

  1. Looks like you are not using the Request Method feature, but using a 3rd-party HTTP library (request?). So, this is not about the request proxy getting triggered twice.
    • Aside: If you are using the request library, then consider moving to another lib because request has been deprecated.
  2. There’s some risky async code in the function. For example, you are using request.get() and trying to append its return value to form, but request.get() is probably an async function.
  3. I am still not clear about where are you seeing these screenshots that you have shared.