Conga Product Documentation

Welcome to the new doc site. Some of your old bookmarks will no longer work. Please use the search bar to find your desired topic.

Show Page Sections

download

Custom Inbound Attachment Callback Class

When you send an approval email using the Submit with Attachment feature, the attached document is sent to all approvers, who can only approve or reject the request. Approvers cannot modify the attachment. Even if the approver modifies the attachment and sends it to the next approver, the original attachment, not the modified one, is forwarded to the next approver. All approvers may also not agree on the same document by the end of the approval cycle unless approvals are submitted multiple times.

You can send modified attachments using the Inbound Attachment Callback. Inbound Attachment Callback allows you to write a callback class to handle attachments on an inbound approval email response. You can write custom logic to act based on the presence, absence, or type of attachment. This callback is called during approval reply handler processing.

To override the default Inbound Attachment Callback class

  1. Go to Setup > Develop > Custom Settings and click Manage for Approvals Custom Classes.
  2. Click Edit for Custom Classes.
    Note:

    If there is no existing entry, you must create one. Click New and in Name, enter Custom Classes.

  3. Enter your callback class's name in Inbound Attachment Callback Class.

    For example, to use the below-mentioned sample code, enter InboundAttachmentHandlerSample as the callback class name. You must provide your own custom logic inside this handler to process attachments. Use this sample code only as a reference.



    To use the default class that replaces the attachment with the ones included in the email response, you don’t have to write a custom implementation. Go to Custom Settings > Approval System Properties and enter Apttus_Approval.InboundAttachmentHandlerTest in the Inbound Attachment Callback property,.

  4. Click Save.
    Note:

    You must define your class as global for the callback mechanism to work.

    Sample Code: For reference /** * Conga Approvals * InboundAttachmentHandlerSample * * @2017-2021 Conga Inc. All rights reserved. */ public with sharing class InboundAttachmentHandlerSample implements CustomClass.IInboundAttachmentCallback { // handle attachment public static Boolean handleActionAttachment(ID ctxObjectId, String approvalAction, Messaging.InboundEmail email) { // first verify that there are attachments... if (((email.binaryAttachments == null) || email.binaryAttachments.isEmpty()) && ((email.textAttachments == null) || email.textAttachments.isEmpty())) { return true; } // associate attachment to context object Attachment ctxAttachment = null; try { // binary or text? if ((email.binaryAttachments != null) && !email.binaryAttachments.isEmpty()) { // code below overwrites existing attachment (this is the default behavior) //ctxAttachment = new Attachment(ParentId = ctxObjectId //, Name = email.binaryAttachments[0].filename //, Body = email.binaryAttachments[0].body); //insert ctxAttachment; // code below saves a new attachment with day of year appended Date dtNow = Date.today(); List<String> attachmentNameInParts = email.binaryAttachments[0].filename.split('\\.(?=[^\\.]+$)'); String attachmentName = attachmentNameInParts[0] + '-' + dtNow.dayOfYear() + '.' + attachmentNameInParts[1]; ctxAttachment = new Attachment(ParentId = ctxObjectId , Name = attachmentName , Body = email.binaryAttachments[0].body); insert ctxAttachment; } else if ((email.textAttachments != null) && !email.textAttachments.isEmpty()) { // code below overwrites existing attachment (this is the default behavior) //ctxAttachment = new Attachment(ParentId = ctxObjectId //, Name = email.textAttachments[0].filename //, Body = Blob.valueOf(email.textAttachments[0].body)); //insert ctxAttachment; // code below saves a new attachment with day of year appended Date dtNow = Date.today(); List<String> attachmentNameInParts = email.binaryAttachments[0].filename.split('\\.(?=[^\\.]+$)'); String attachmentName = attachmentNameInParts[0] + '-' + dtNow.dayOfYear() + '.' + attachmentNameInParts[1]; ctxAttachment = new Attachment(ParentId = ctxObjectId , Name = attachmentName , Body = Blob.valueOf(email.textAttachments[0].body)); insert ctxAttachment; } // optionally perform custom logic here } catch (Exception e) { System.debug('Unable to create an attachment object from provided email attachment.'); System.debug('Message... ' + e.getMessage()); System.debug('Type... ' + e.getTypeName()); System.debug('Stacktrace... ' + e.getStackTraceString()); return false; } // replace approval process attachment with this new attachment try { ApprovalsWebService.replaceApprovalEmailAttachment(ctxObjectId, ctxAttachment.Id); } catch (Exception ex) { System.debug('Unable to replace approval process attachment with ' + ctxAttachment.Name); System.debug('Message... ' + ex.getMessage()); System.debug('Type... ' + ex.getTypeName()); System.debug('Stacktrace... ' + ex.getStackTraceString()); return false; } return true; } }