function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Taro UraokaTaro Uraoka 

How to escape merge fields of Named Credentials?

I'm using Named Credentials with "Allow Merge Fields in HTTP Body" in Apex code.
How to include exact char sequence "{!$Credential.OAuthToken}" (avoid replaceing into OAuth token) into my request body?
 
Shashikant SharmaShashikant Sharma
Hi Taro,

Could you please share your code. That will help me in understanding the issue and sharing a resolution for it.

Thanks
Shashikant
Taro UraokaTaro Uraoka
Thank you for the reply, Shashikant.

For example, this batch posts Yesterday's Leads to another Salesforce organization using SOAP API and Named Credentials.
public class PostLeadBatch implements Schedulable, Database.Batchable<SObject> {
    
    public void execute(SchedulableContext context) {
        Database.executeBatch(new PostLeadBatch(), 50); 
    }
    
    public Database.QueryLocator start(Database.BatchableContext context) {
        return Database.getQueryLocator([
            select Id, FirstName, LastName, Company
            from Lead
            where CreatedDate < today and CreatedDate >= yesterday
        ]);
    }
    
    public void execute(Database.BatchableContext context, Lead[] scope) {
        String[] sobjects = new String[] {};
        for (Lead e : scope) {
            sobjects.add('<m:sObjects>' +
                         '<sobj:type xsi:type="xsd:string">Lead</sobj:type>' +
                         '<sobj:FirstName xsi:type="xsd:string">' + e.FirstName.escapeXml() + '</sobj:FirstName>' +
                         '<sobj:LastName xsi:type="xsd:string">' + e.LastName.escapeXml() + '</sobj:LastName>' +
                         '<sobj:Company xsi:type="xsd:string">' + e.Company.escapeXml() + '</sobj:Company>' +
                         '</m:sObjects>');
        }
        String xml = '<?xml version="1.0" encoding="UTF-8"?>' +
            '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" ' +
            'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' +
            'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
            '<env:Header>' +
            '<SessionHeader xmlns="urn:partner.soap.sforce.com">' +
            '<sessionId>' +
            '{!$Credential.OAuthToken}' +
            '</sessionId>' +
            '</SessionHeader>' +
            '</env:Header>' +
            '<env:Body>' +
            '<m:create xmlns:m="urn:partner.soap.sforce.com" xmlns:sobj="urn:sobject.partner.soap.sforce.com">' +
            String.join(sobjects, '') +
            '</m:create>' +
            '</env:Body>' +
            '</env:Envelope>';
            
        HttpRequest req = new HttpRequest();
        req.setEndpoint('callout:AnotherDeveloperEdition');
        req.setMethod('POST');
        req.setHeader('Content-Type', 'text/xml; charset=UTF-8');
        req.setHeader('SOAPAction', '""');
        req.setBody(xml);
        HttpResponse res = new Http().send(req);
        System.debug(res.getBody());
    }
    
    public void finish(Database.BatchableContext context) {
        // do nothing
    }
    
}
SOAP API require sessionId in HTTP body. So I need "Allow Merge Fields in HTTP Body" in Named Credentials.

But If any Yesterday's Leads have Company field value: "{!$Credential.OAuthToken}", 
the Company field value of the Lead record created in another organization is the OAuth token.

I want to create Lead record with Company field value: "{!$Credential.OAuthToken}".

Thanks
Taro UraokaTaro Uraoka
In this case, it can be resolved by replacing '$' in every string field to '&#x24;' like:
e.Company.escapeXml().replaceAll('\\$', '&#x24;')
because HTTP body of SOAP API is XML.

But endpoint is not only Salesforce platform.
Sometimes I need post plain text. So I want to know how to escape merge fields syntax like "{!$Credential.OAuthToken}".

Thanks