【Salesforce与第三方集成】在Salesforce中,用Apex来实现往Slack发送消息(用Incoming Webhooks方法)
2023年08月31日
文章浏览:332
需求: 在Salesforce中和Slack进行通信,当Salesforce中的数据有创建?更新的时候,发送消息到Slack中通知Slack的用户

大家知道,作为Salesforce的产品集群中的Slack,越来越被大家所接受。

所以用了Salesforce,又使用了Slack,那么两者之间的实时通信就变得非常需要。

有小伙伴在微信群里面问这个问题,所以我就来写一篇文章来大概讲解一下具体的实现方式。


1。创建SlackAPP

首先我们在Slack平台上打开APP创建的页面。

打开下面的这个链接。

 https://api.slack.com/apps

并点击【Create an APP】按钮。



并输入APP名称,还有选择WorkSpace,最后点击【Create APP】按钮。


2。在Slack中,建立Webhook(网络钩子)

webhook,在集成多个系统的时候,是经常会被用到的。我们来看一下Wiki的定义。

webhook 是一种基于HTTP 的回调函数,可在2 个应用编程接口(API)之间实现轻量级的事件驱动通信。 


接下来,我们点击有效化Incoming Webhook。



在【Incoming Webhook】页面的最下面,有一个Add New Webhook to Workspace按钮,


在下面的画面选择要通知的频道。然后再点击 【许可】


下面是【Add New Webhook to Workspace】完成的效果。




在【Sample curl request to post to a channel】内我们可以看到如果我们要发消息到Slack,

就可以上面的示例代码,使用POST方法把消息放在JSON数据中发送给Slack的消息频道。


POST https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Content-type: application/json
{
    "text": "Hello, world."
}
  


在写Apex代码之前,我们先用Curl代码来尝试一下,是不是能够成功把消息传给Slack的频道。

如下图所示,能够成功把消息传给Slack的频道。所以用Incoming Webhooks是可行的



下面是通过Incoming Webhooks发送消息的API的详细使用方法
 https://api.slack.com/messaging/webhooks


3。创建发送Http请求的Apex代码sendMessage方法

先创建一个共通方法sendMessage

/**
 * @description       : 共通方法
 * @author            : SalesforceGogogo.com
 * @last modified on  : 2023/08/31
 * @last modified by  : SalesforceGogogo.com
**/

public with sharing class CommonUtil {

    /**
    * 发送消息到第三方平台的方法sendMessage
    * @param msg 要发送到Slack的消息内容
    * @param url Slack的Webhook URL
    */
    @future (callout=true)
    private static void sendMessage(String msgBody, String endpointUrl) {
        Http http = new Http();
        HttpRequest HttpRequestItem = new HttpRequest();
        HttpRequestItem.setEndpoint(endpointUrl);
        HttpRequestItem.setMethod('POST');
        HttpRequestItem.setHeader('Content-Type', 'application/json');
        System.debug('rendpointUrles----------->'+endpointUrl);
        HttpRequestItem.setBody(msgBody);
        //System.debug('msgBody----------->'+JSON.serialize(msgBody));

        HttpResponse res = http.send(HttpRequestItem);
        System.debug('res----------->'+res);
    }
}


4。创建存放endpointUrl的Custom Labels

打在Custom Labels页面,创建一个SlackEndpointUrl. 

用来存放在Slack的Webhook URL





5。在CommonUtil文件中,添加另外一个发送消息的方法


    public static void sendMessageToSlack(String slackMsg) {
        // 当参数为空字符时,不作处理
        if (String.isEmpty(slackMsg)) {
            System.debug('slackMsg is Empty');
            return;
        }

        String strEndpointUrl = System.label.SlackEndpointUrl;
        String jsonString = CommonUtil.create_JSON(slackMsg).getAsString();

        CommonUtil.sendMessage(jsonString,strEndpointUrl);
    }


还需要把Body里面的内容改变成具体的JSON格式。

    public static JSONGenerator create_JSON(String msg){   
        JSONGenerator json = JSON.createGenerator(True);
        json.writeStartObject();
        json.writeStringField('text', msg);
        //json.writeStringField('channel', channel);
        json.writeEndObject();
        
        return json;
    }

这个JSON格式的话,有具体的格式的,不是简单转换成JSON就行了的。

是需要设置成下面格式的JSON字符串,Text是必须项,其余的是可选项。(注意了哦,不然会返回400 BadRequest)

FieldTypeRequired?Description
textStringYesThe usage of this field changes depending on whether you're using blocks or not. If you are, this is used as a fallback string to display in notifications. If you aren't, this is the main body text of the message. It can be formatted as plain text, or with mrkdwn. This field is not enforced as required when using blocks, however it is highly recommended that you include it as the aforementioned fallback.
blocksArrayNoAn array of layout blocks in the same format as described in the building blocks guide.
attachmentsArrayNoAn array of legacy secondary attachments. We recommend you use blocks instead.
thread_tsStringNoThe ID of another un-threaded message to reply to.
mrkdwnBooleanNoDetermines whether the text field is rendered according to mrkdwn formatting or not. Defaults to true.

具体可以看下面的这个官方链接。

 https://api.slack.com/reference/messaging/payload 



为了方便大家,下面是所有需要的Apex代码。


/**
 * @description       : 与Slack通信的所有共通方法
 * @author            : SalesforceGogogo.com
 * @last modified on  : 2023/08/31
 * @last modified by  : SalesforceGogogo.com
**/

public with sharing class CommonUtil {

    /**
    * 发送消息到第三方平台的方法sendMessage
    * @param msg 要发送到Slack的消息内容
    * @param url Slack的Webhook URL
    */
    @future (callout=true)
    private static void sendMessage(String msgBody, String endpointUrl) {
        Http http = new Http();
        HttpRequest HttpRequestItem = new HttpRequest();
        HttpRequestItem.setEndpoint(endpointUrl);
        HttpRequestItem.setMethod('POST');
        HttpRequestItem.setHeader('Content-Type', 'application/json');
        System.debug('rendpointUrles----------->'+endpointUrl);
        HttpRequestItem.setBody(msgBody);
        //System.debug('msgBody----------->'+JSON.serialize(msgBody));

        HttpResponse res = http.send(HttpRequestItem);
        System.debug('res----------->'+res);
    }

    public static void sendMessageToSlack(String slackMsg) {
        // 当参数为空字符时,不作处理
        if (String.isEmpty(slackMsg)) {
            System.debug('slackMsg is Empty');
            return;
        }

        String strEndpointUrl = System.label.SlackEndpointUrl;
        String jsonString = CommonUtil.create_JSON(slackMsg).getAsString();

        CommonUtil.sendMessage(jsonString,strEndpointUrl);
    }

    public static JSONGenerator create_JSON(String msg){   
        JSONGenerator json = JSON.createGenerator(True);
        json.writeStartObject();
        json.writeStringField('text', msg);
        //json.writeStringField('channel', channel);
        json.writeEndObject();
        
        return json;
    } 
    
}




6。因为有Webhook的URL,所以我们需要在Salesforce上,添加Remote Site





7。要偷懒了,不用Flow了,直接在开发者控制台里面调方法执行代码。


大家看到了,通过Apex代码,我们可以直接发消息给Slack的频道。

关注 收藏