Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

How the email thread should happen to the customer and agent

mania
Tera Contributor

Hi,

 

I am facing some issue here.

I have a scenario here, when someone replies by email, the reply text + inline images + attachments are added to the correct case automatically. 

But here the issue is when i reply from the email the body is mapping to the worknotes.

mania_0-1755511757267.png

 

But i want the email thread should happen to the customer and agent 

Reply inbound:

(function runAction( /* GlideRecord */ email, /* GlideRecord */ event) {

    var subject = email.subject + "";
    gs.info("Email Subject: " + subject);

    // Regex to find case number pattern: CS + digits (e.g., CS12345)
    var caseNumberMatch = subject.match(/\bCS\d+\b/);
    var caseNumber = null;

    if (caseNumberMatch) {
        caseNumber = caseNumberMatch[0];
        gs.info("Extracted Case Number: " + caseNumber);
    } else {
        gs.info("No Case Number Found in Subject");
        return; // Exit early if no case number found
    }

    // Look up the related case
    var existingCase = new GlideRecord('sn_customerservice_case');
    if (existingCase.get('number', caseNumber)) {

        gs.info("The case exists: " + existingCase.number);
        gs.info("The Email sys_id is: " + sys_email.sys_id);

        // ---- Case updates ----

        // Adjust time_worked by +1 second
        var timeWorkedRaw = existingCase.getValue('time_worked'); // Example: "1970-01-01 00:02:02"
        var gdt = new GlideDateTime(timeWorkedRaw);

        var ms = gdt.getNumericValue();
        var totalSeconds = ms / 1000;
        totalSeconds += 1; // Add 1 second

        var gd = new GlideDuration(totalSeconds * 1000);
        existingCase.setValue('time_worked', gd.getDurationValue());

        // Append reply content with sender email & maintain inline images
        var senderEmail = email.origemail || ""; // gets replier's email
        gs.info("Reply sender email: " + senderEmail);

        // Append reply content (maintains inline image HTML)
        gs.info("The HTML field is " + email.body_html);
        existingCase.u_add_worknotes = "reply from: " + senderEmail + "<br><br>" + email.body_html;
        existingCase.update();

        // ---- Copy attachments from email to case ----
        copyAttachmentsFromEmailToCase(sys_email.sys_id, existingCase.sys_id);
    }

    /**
     * Copies all attachments from a sys_email record to a target case.
     * Skips duplicates based on file name + size.
     */
    function copyAttachmentsFromEmailToCase(emailSysId, caseSysId) {
        gs.info("Copying attachments from Email: " + emailSysId + " to Case: " + caseSysId);

        var gsa = new GlideSysAttachment();

        // Find attachments linked to this email
        var emailAttachmentGR = new GlideRecord('sys_attachment');
        emailAttachmentGR.addQuery('table_name', 'sys_email');
        emailAttachmentGR.addQuery('table_sys_id', emailSysId);
        emailAttachmentGR.query();

        while (emailAttachmentGR.next()) {

            var fileName = emailAttachmentGR.getValue('file_name');
            var sizeBytes = emailAttachmentGR.getValue('size_bytes');
            var sourceSysId = emailAttachmentGR.getValue('sys_id');
            var contentType = emailAttachmentGR.getValue('content_type');

            // Check for existing attachment on the case to avoid duplicates
            var caseAttachmentGR = new GlideRecord('sys_attachment');
            caseAttachmentGR.addQuery('table_name', 'sn_customerservice_case');
            caseAttachmentGR.addQuery('table_sys_id', caseSysId);
            caseAttachmentGR.addQuery('file_name', fileName);
            caseAttachmentGR.addQuery('size_bytes', sizeBytes);
            caseAttachmentGR.query();

            if (!caseAttachmentGR.hasNext()) {
                var caseGR = new GlideRecord('sn_customerservice_case');
                if (caseGR.get(caseSysId)) {
                    var stream = gsa.getContentStream(sourceSysId);
                    gsa.writeContentStream(caseGR, fileName, contentType, stream);
                    gs.info("Copied attachment: " + fileName);
                }
            } else {
                gs.info("Skipping duplicate attachment: " + fileName);
            }
        }
    }

})(email, event);

Can anyone please help on this, it will be useful.

Thanks!

 

5 REPLIES 5

GlideFather
Tera Patron

Hi @mania,

 

it seems to be this part:

  // Append reply content (maintains inline image HTML)
        gs.info("The HTML field is " + email.body_html);
        existingCase.u_add_worknotes = "reply from: " + senderEmail + "<br><br>" + email.body_html;
        existingCase.update();

 

Try to comment it out, then re-test to see any difference and then eventually remove it for good or modify it up to your full satisfactory

 

Let me know how it went please

———
/* If my response wasn’t a total disaster ↙️ drop a Kudos or Accept as Solution ↘️ Cheers! */


Hi @mania have oyu had chance to comment this part out to verify the behaviour?

———
/* If my response wasn’t a total disaster ↙️ drop a Kudos or Accept as Solution ↘️ Cheers! */


Hello @mania,

according to the shared code, it works OK, have you had chance to remove/comment the below part out of it?

  // Append reply content (maintains inline image HTML)
        gs.info("The HTML field is " + email.body_html);
        existingCase.u_add_worknotes = "reply from: " + senderEmail + "<br><br>" + email.body_html;
        existingCase.update();

 

Please let me know if need more help or you are all good and can close this thread 

———
/* If my response wasn’t a total disaster ↙️ drop a Kudos or Accept as Solution ↘️ Cheers! */


Hi @mania could you provide any feedback - solved or still something's needed?

 

Thanks

———
/* If my response wasn’t a total disaster ↙️ drop a Kudos or Accept as Solution ↘️ Cheers! */