Salesforce Integretion

本文详细介绍了Salesforce与其他系统的集成方式,包括Connected App、REST API、SOAP API、Bulk API和Streaming API的使用。讲解了REST API中的HTTP方法、状态码以及如何进行Callout操作。同时提到了Salesforce的平台事件(Platform Event)和变更数据捕获(Change Data Capture)功能,用于实时数据交互和同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Salesforce to other system || other system to salesforce

Connected App是一个允许外部的应用通过API 以及 标准协议来实现和Salesforce交互的架构.

Remote Site salesforce通过REST方式访问外界站点需要添加站点的url

Streaming API/Pub/Sub API     Bulk ApI     Rest    Soap 

Rest : REST方式获取外部Service数据以及其他Service访问Salesforce数据操作

Salesforce call other system

将Web Service的授权端点地址添加到Remote Site中

Some Common HTTP Methods

Get and Post

Get 方式传递值直接拼在url 中, post 传递一个json 格式数据

String params = '?subject=test&status=active';           
String url == WEB_URL+'/xxx/Sync/SyncTest?'+params;
Http h = new Http();
            HttpRequest req = new HttpRequest();
            req.setEndpoint(url);
            req.setMethod('GET');
            HttpResponse res = h.send(req);
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
request.setMethod('POST');
request.setHeader('Content-Type', 'application/json;charset=UTF-8');
// Set the body as a JSON object
request.setBody('{"name":"mighty moose"}');
HttpResponse response = http.send(request);
// Parse the JSON response
if(response.getStatusCode() != 201) {
    System.debug('The status code returned was not expected: ' + response.getStatusCode() + ' ' + response.getStatus());
} else {
    System.debug(response.getBody());
}

other system call salesforce 

创建Connected App,根据生成的Consumer Key以及Consumer Secret 配置外部系统

     @RestResource:曝光此类作为REST资源;

     @HttpGet:曝光方法作为REST资源,当有Http get请求发送时,此注解对应的方法会被执行;

  @HttpPost:Http post 请求发送时,此注解对应的方法会被执行;

  @HttpDelete:当有Http delete请求发送时,此注解对应的方法会被执行;

  @HttpPut:当有Http put请求发送时,此注解对应的方法会被执行;

  @HttpPatch:当有Http patch请求发送时,此注解对应的方法会被执行。

@HttpGet和@HttpDelete不能有形参,可以通过URL?param或者URL/param方式传过来参数
类和方法需要global,方法需要静态
类需要通过RestResource(UrlMapping='/page/*')注解声明
@RestResource(UrlMapping='/AccountLogic/*')
 8 global class AccountRESTController {
10     @HttpGet
11     global static List<Account> getAccountsByIdOrList() {
12         RestRequest request = RestContext.request;
16         String accountId= request.params.get('accountId');
17         String fetchSql;
18         if(accountId!= null) {
19             fetchSql = 'SELECT CreatedById, CreatedDate, IsDeleted, Name,' +
22             ' xxxx FROM Account' +
23             ' where Id = :accountId';
24         } else {
25            
29         }
30         List<Account> accountList = Database.query(fetchSql);
31         return accountList ;
32     }
33     
34     
35     @HttpPost
36     global static Id insertAccount(String accountName,String xxxxx) {
37         return xxx;
49     }
50     
51     @HttpDelete
52     global static void deleteGoods() {
53        
60     }
61     
62     @HttpPut
63     global static ID upsertAccounts(String id,String accountName) {
64         
77     }
78 
79     @HttpPatch
80     global static ID updateAccounts() {
81        
93     } 
94     
95     
96     
97 }

自己写的方法可以在workbench中查看测试

/services/apexrest/AccountLogic/getAccountsByIdOrList?accountid=xxxxx

REST API支持JSON和XML两种传输方式,默认为JSON,可通过【HTTP ACCEPT】header来设定

Callout方法在执行后续代码的时候,会等待外部服务器的响应结果,所以Callout方法同样可以在@future(callout=true) 中进行调用,这样Callout方法可以在单独的进程中调用,不会阻塞其他进程,尤其在触发器中调用Callout方法时,必须将其包含在含有@future(callout=true) 的方法中进行

Make Long-Running Callouts with Continuations

<apex:page controller="ContinuationController" showChat="false" showHeader="false">
   <apex:form >
      <!-- Invokes the action method when the user clicks this button. -->
      <apex:commandButton action="{!startRequest}" 
              value="Start Request" reRender="result"/> 
   </apex:form>

   <!-- This output text component displays the callout response body. -->
   <apex:outputText id="result" value="{!result}" />
</apex:page>
public with sharing class ContinuationController {
    // Unique label corresponding to the continuation
    public String requestLabel;
    // Result of callout
    public String result {get;set;}
    // Callout endpoint as a named credential URL 
    // or, as shown here, as the long-running service URL
    private static final String LONG_RUNNING_SERVICE_URL = 
        '<Insert your service URL>';
   
   // Action method
    public Object startRequest() {
      // Create continuation with a timeout
      Continuation con = new Continuation(40);
      // Set callback method
      con.continuationMethod='processResponse';
      
      // Create callout request
      HttpRequest req = new HttpRequest();
      req.setMethod('GET');
      req.setEndpoint(LONG_RUNNING_SERVICE_URL);
      
      // Add callout request to continuation
      this.requestLabel = con.addHttpRequest(req);
      
      // Return the continuation
      return con;  
    }
    
    // Callback method 
    public Object processResponse() {   
      // Get the response by using the unique label
      HttpResponse response = Continuation.getResponse(this.requestLabel);
      // Set the result variable that is displayed on the Visualforce page
      this.result = response.getBody();
      
      // Return null to re-render the original Visualforce page
      return null;
    }
}

code

 1.以“2”开头,表示成功:

                (1)200:表示“成功”。通常用于GET、HEAD和一些PATCH中。

                (2)201:表示“已创建”。通常用于POST和一些PATCH中。

                (3)204:表示“没有内容”。通常用于DELETE和一些PATCH中。

        2.以“3”开头,表示重定向:

                (1)300:当外部ID存在于多条数据中时返回该状态码。即Response Body中包含多条符合的数据。

                (2)304:用户在发送请求的header中指定日期时间,如果从这个日期时间开始请求的文件内容未变化,则返回该状态码。(用于指定日期时间的header是【If-Modified-Since】)

        3.以“4”开头,表示客户端错误:

                (1)400:请求无法被解析,通常是因为JSON或XML body中有错误。

                (2)401:Session ID或OAuth令牌无效或过期,在response body中会有相关信息和错误状态码 

                (3)403:请求被拒绝。查看发送请求的用户是否有权限。若错误信息是“REQUEST_LIMIT_EXCEEDED”,则是超出了组织API请求上限。

                (4)404:找不到请求中的信息。检查URI是否正确。

                (5)405:请求行中的方法不被允许访问URI

                (6)409:请求无法完成,因为当前请求的相关设定中存在冲突。检查请求的API版本是否合适。

                (7)410:通知用户该资源已经不可再用,主要是帮助网站管理员维护网站。

                (8)412:表示“未满足前提条件”,如用户发送的请求的header中的指定条件无法对应。        

                (9)414:URI长度过长(超出16384 byte)

                (10)415:服务器无法处理请求附带的媒体格式。检查header中的Content Type是否正确。

                (11)431:URI和header加在一起的长度超过16384 byte,可能是由于token过长。

        4.以“5”开头,表示服务器错误:

                (1)500:Lightning Platform发生错误,请求无法处理。请联系Salesforce服务台。

                (2)503:服务器无法处理请求。一般是因为系统维护或超载。

SOAP :

根据系统生成的WSDL 文件 ,外部系统通过这个文件进行接口的调用

系统根据外部系统的WSDL文件生成对应的apex class ,调用外部系统

Bulk ApI : 大量的数据处理,batch 处理, 通过excel 等

--BOUNDARY
Content-Type: application/json
Content-Disposition: form-data; name="job"

{
  "object":"Contact",
  "contentType":"CSV",
  "operation": "insert",
  "lineEnding" : "LF"
}

--BOUNDARY
Content-Type: text/csv
Content-Disposition: form-data; name="content"; filename="content"

FirstName,LastName,MailingCity
Astro,Nomical,San Francisco
Hootie,McOwl,San Francisco
Appy,Camper,San Francisco
Earnie,Badger,San Francisco
--BOUNDARY--

Streaming API/Pub/Sub API :

如果想使用Streaming API,需要enable api的权限以及streaming api的权限

想要接受通知(notifications),当前登录的user必须针对StreamingChannel表拥有read权限

想要创建和管理通知,当前登录的user必须对StreamingChannel拥有Create权限

Push Topic

ApiVersion:用于指定查询的SQL的版本,37以后系统可以存储24小时以内的事件,必填字段;
Description:PushTopic的描述信息,限定在400个字符以内;
ID:指定一条记录的全局唯一的标识;
isActive:是否可用,关系到PushTopic的限制计数(系统对PushTopic有limitation size);
IsDeleted:指定此PushTopic是否移动到回收站;
Name:PushTopic的名字,定义了渠道的名字,并且此名称必须是唯一的,后期订阅者订阅时,使用的就是这个名字;
NotifyForFields:指定哪些字段被评估生成通知;
NotifyForOperations:指定数据哪种事件操作会生成通知,在api version 29以后,此字段为只读字段;
NotifyForOperationCreate:Create操作是否会生成通知,api29以后可用;
NotifyForOperationDelete:Delete操作是否会生成通知,api29以后可用;
NotifyForOperationUndelete:UnDelete操作是否会生成通知,api29以后可用;
NotifyForOperationUpdate:Update操作是否会生成通知,api29以后可用;
Query:SOQL语句决定了哪些数据符合触发的事件后会发送到渠道。

PushTopic pushTopic = new PushTopic();
pushTopic.Name = 'InvoiceStatementUpdates';
pushTopic.Query = 'SELECT Id, Name, Status__c, Description__c FROM Invoice_Statement__c';
pushTopic.ApiVersion = 61.0;
pushTopic.NotifyForOperationCreate = true;
pushTopic.NotifyForOperationUpdate = true;
pushTopic.NotifyForOperationUndelete = true;
pushTopic.NotifyForOperationDelete = true;
pushTopic.NotifyForFields = 'Referenced';
insert pushTopic;

创建之后可以在workbench查看 Jump To选择Streaming Push Topics

Push Topics 选择刚刚创建的InvoiceStatementUpdates,点击Subscribe,则目前已经模拟订阅了此PushTopic

在系统中修改publish topic 关联的并且符合soql 的数据,则会在Streaming Push Topic 显示具体的修改信息推送消息了

Streaming Channels: 

Description : Streaming Channel的描述
ID : Streaming Channel的ID
IsDeleted : 指定Streaming Channel是否被移动到回收站
IsDynamic : 如果为true则在订阅时动态创建channel
LastReferencedDate : 存储当前用户最近一次查看的这条记录的时间戳
Name:绑定的PushTopic,以/u/开始,命名为/u/pushtopic Name
OwnerId : Streaming Channel的owner

外部系统请求订阅,订阅后符合PushTopic 中soql 的数据触发后会发送

内部系统自己也可以调用Streaming Channels

Platform Event:

可以监听系统数据并且满足某种条件下,和自己或者其他外部系统进行交流通讯

创建Platform Event以后,可以选择Publish Behavior,salesforce提供了两个值可供选择: Publish After Commit / Publish Immediately

Publish Immediately如果设置了此种模式, setSavePoint以及rollback不支持,即发送了就发送了,没有某种case回滚模式;反之Publish After Commit可以有回滚操作

Publish Immediately当对一个platform event列表进行publish时,即使有一些失败,成功的那些也会继续进行发布,即保存时allOrNone属性会被自动忽略;

trigger AccountTrigger on Account(after update) {
    List<Account__e> needPublishAccountList = new List<Account__e>();
    for(Account accountItem : (List<Account>)Trigger.new) {
        //some logic 
        if() {
            //new created plat event
            Account__e accountPublishItem = new Account__e(); 
            //put account value to event record field
            accountPublishItem.Account_Id__c = accountItem.Id;
            needPublishAccountList.add(accountPublishItem);
        }
    }
        // publish the event
        List<Database.SaveResult> results = EventBus.publish(needPublishAccountList);
       

}

添加监听, 可以在对应的event 创建trigger 或者其他方式,trigger只能after insert

Change Data Capture:

 setup->  change data capture 然后选择需要追踪的表

trigger OpportunityChangeTrigger on OpportunityChangeEvent (after insert) {
  for (OpportunityChangeEvent event : Trigger.New) {
    // Get some event header fields
    EventBus.ChangeEventHeader header = event.ChangeEventHeader;
    if (header.changetype == 'UPDATE') {
        for (String field : header.changedFields) {
             System.debug('Changed field value: ' + field + '. New Value: '
                    + event.get(field));
        }
    }
    
}

debug log中查看到CDC相关的订阅信息,需要将 Traced Entity Type设置成 Automated Process

自己记录使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值