1

I am using an Apex Action from SF Unofficial to Pos to Slack from a Flow. One of the parameters in Apex Action is the "block" which builds the body json string for the Slack Post. In the block I am using various merge fields.
The challenge is that the merge fields can contain quotes which then invalidates the json.
I could run each of the fields through a formula to remove the quotes and use these in the block, however this is tedious.

I would like to modify the Apex Class to identify the Text values and remove just the quotes from the merge fields.
So in the example below I would just remove the " around the word quotes

{
    "blocks": [
        {
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": "*Subject:* How can I remove the "quotes" from this Subject"
            }
        }
    ]
}

Below is the full Apex Class

global without sharing class PostToSlackPlus {

        
        @InvocableMethod(label='Post to Slack Plus' description='Post Message to Slack Plus' callout=true)
        global static List<Response> execute(List<Request> requests) {
            
            String endpoint = 'https://slack.com/api/' + 'chat.postMessage';
            List<Response> curResponses = new List<Response>();

            Map<String,Object> responseMap = new Map<String,Object>();
            for (Request curRequest: requests ){
                Response curResponse = new Response();
                String token = curRequest.token;
                String body = formBody(curRequest); 
                System.debug('body is: ' + body);

                if(!Test.isRunningTest()) {
                    responseMap = SlackUtils.Send(endpoint, token, body);
                    System.debug('response from chat.postMessage is: ' + responseMap);
                } else {
                    
                    String testResponse = sampleResponse;
                    responseMap = (Map<String, Object>) JSON.deserializeUntyped(testResponse);
                    System.debug('response from chat.postMessage is: ' + responseMap);
                }
               
                curResponse.timeStamp = (String)responseMap.get('ts');
                curResponse.ok = (Boolean)responseMap.get('ok');
                curResponse.errorMessage = (String)responseMap.get('error');
                curResponses.add(curResponse);
            }
            return curResponses;
      
        }

        private static String formBody(Request curRequest) {
            String body = '{';
            body = body + '"channel":"' + curRequest.channelId + '",';
            if(curRequest.blocks != null && curRequest.blocks != '') {
                curRequest.blocks = curRequest.blocks.replace('\r\n', '\n ');
                curRequest.blocks = curRequest.blocks.replace('\r', '\n ');
                body = body + '"blocks":' + curRequest.blocks+ ',';
            }
            if(curRequest.thread_ts != null && curRequest.thread_ts != '') {
                body = body + '"thread_ts":"' + curRequest.thread_ts + '",';
            }
            if(curRequest.username != null && curRequest.username != '') {
                body = body + '"username":"' + curRequest.username + '",';
            }
            if(curRequest.unfurl_links != null && curRequest.unfurl_links != '') {
                body = body + '"unfurl_links":"' + curRequest.unfurl_links + '",';
            }
            if(curRequest.attachments != null && curRequest.attachments != '') {
                body = body + '"attachments":"' + curRequest.attachments + '",';
            }
            if(curRequest.text != null && curRequest.text != '') {
                body = body + '"text":"' + curRequest.text + '"';
            }
            
            body = body + '}';
            return body; 

        }

        final static String sampleResponse = '{'
           + ' "ok": true,'
            +'"channel": "C1H9RESGL",'
            +' "ts": "1503435956.000247",'
            +' "message": {'
                +'  "text": "Here\'s a message for you",'
                +' "username": "ecto1",'
                +' "bot_id": "B19LU7CSY",'
                +' "attachments": ['
                    +'  {'
                        +'  "text": "This is an attachment",'
                        +' "id": 1,'
                        +' "fallback": "This is an attachment\'s fallback"'
                     +' }'
                +' ],'
                +' "type": "message",'
                +' "subtype": "bot_message",'
                +' "ts": "1503435956.000247"'
            +' }'
        + '}';

        global class Request {
            @InvocableVariable
            global String text; //main message unless you're using blocks

            @InvocableVariable
            global String blocks;
            
            @InvocableVariable(required=true)
            global String channelId;  

            @InvocableVariable
            global String token;

            @invocableVariable
            global String thread_ts;

            @invocableVariable
            global String username;

            @invocableVariable
            global String unfurl_links;

            @invocableVariable
            global String attachments;

        }
        global class Response {
            @invocableVariable
            global String errorMessage;

            @invocableVariable
            global String timeStamp;

            @invocableVariable
            global Boolean ok;
        }

      }
2
  • why would you not want to escape the double quotes (e.g. \" )to preserve original data?
    – cropredy
    Commented Feb 24, 2022 at 6:25
  • For the Slack posts I really do not need to preserve these. However if it is just as easy to replace rather than substitute that will work. Commented Feb 24, 2022 at 6:45

1 Answer 1

3

Don't build the JSON string yourself but rather use one of the JSON Class serialize methods. They automatically take care of the escaping of the embedded quotes.

You also end up with more readable code:

Map<String, Object> body = new Map<String, Object>{
    'channel' => curRequest.channelId,
    'blocks' => ...
};

String jsonString = JSON.serializePretty(body);

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .