学习目标
完成本单元后,您将能够:
- 了解如何使用Heroku使用Apex标注和工作流程。
- 了解Apex标注和工作流程的用例。
呼叫Heroku应用程序
有时,由于正在执行的流程的规模或类型,Salesforce上的事件需要由外部系统处理。例如,Salesforce中的用户上载需要调整大小以供将来使用的图像。Heroku可以从Salesforce接收事件并执行一些响应过程。(可选)可以使用REST API或Heroku Connect将流程的输出存储回Salesforce中。
根据Salesforce中的事件调用Heroku应用程序有两种主要方法:工作流出站消息或Apex HTTP标注。工作流出站消息以声明方式进行SOAP调用。Apex HTTP callout以编程方式对Heroku应用程序进行REST调用。无论哪种方式,Heroku应用程序都会收到带有事件详细信息有效负载的请求,然后执行操作。
带有工作流程的标注
使用工作流,您可以声明性地定义规则和外部系统的标注。该规则可以连接到任何Salesforce对象,如Contact或Account,并根据这些记录事件触发:
- 创建
- 创建,每次编辑
- 创建,并随时编辑以符合标准
规则必须具有筛选事件的条件。如果您不想进行任何过滤,则可以添加始终为真的条件。以下是一个示例规则:
要在规则执行时调用Heroku应用程序,请将出站消息添加到即时工作流操作列表中,并将Heroku应用程序端点指定为端点URL,如:
如果选择Send Session ID
,Heroku应用程序可以使用该令牌代表用户进行REST API调用。如果您不发送会话ID。没有办法检查请求是否有效或防止恶意调用您的Heroku应用程序的API端点。
在Heroku方面,您可以使用任何开源Web或REST技术实现事件处理程序。但由于消息是SOAP格式,因此您需要能够解析XML。例如,使用JavaScript,Node.js,Express和express-xml-bodyparser库,这里是一个处理出站消息并解析SOAP消息的端点。
app.post("/new_contact", function(req, res) {
var notification = req.body["soapenv:envelope"]["soapenv:body"][0]["notifications"][0];
var sessionId = notification["sessionid"][0];
var data = {};
if (notification["notification"] !== undefined) {
var sobject = notification["notification"][0]["sobject"][0];
Object.keys(sobject).forEach(function(key) {
if (key.indexOf("sf:") == 0) {
var newKey = key.substr(3);
data[newKey] = sobject[key][0];
}
}); // do something #awesome with the data and sessionId
}
res.status(201).end();
});
在此示例中,每次创建联系人时,Heroku应用程序都会收到联系人详细信息,并可以根据需要对数据执行任何操作。
带有Apex触发器的标注
您可以在Salesforce对象上定义Apex触发器以处理以下任何事件:
- 插入
- 更新
- 删除
- 合并
- UPSERT
- 取消删除
触发器可以使用Apex标注对Heroku应用程序上的端点进行REST JSON调用。例如,这是一个调用Heroku应用程序的Apex触发器:
trigger NewContactWebhookTrigger on Contact (after insert) {
String url = 'https://foo.herokuapp.com/new_contact';
String content = Webhook.jsonContent(Trigger.new, Trigger.old);
Webhook.callout(url, content);
}
引用的Webhook Apex类是:
public class Webhook {
public static String jsonContent(List<Object> triggerNew, List<Object> triggerOld) {
String newObjects = '[]';
if (triggerNew != null) {
newObjects = JSON.serialize(triggerNew);
}
String oldObjects = '[]';
if (triggerOld != null) {
oldObjects = JSON.serialize(triggerOld);
}
String userId = JSON.serialize(UserInfo.getUserId());
String content = '{"new": ' + newObjects + ', "old": ' + oldObjects + ', "userId": ' + userId + '}';
return content;
}
@future(callout=true) public static void callout(String url, String content) {
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint(url);
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setBody(content);
h.send(req);
}
}
jsonContent方法获取触发器数据并将其序列化为JSON。callout方法使用JSON有效负载将HTTP发布到Heroku。
与出站消息一样,您可以使用任何开源Web或REST技术构建Heroku应用程序。使用JavaScript,Node.js和Express,端点可以定义为:
app.post("/new_contact", function(req, res) {
// do something with req.body
res.status(201).end();
});
在请求处理程序中,req.body是从Apex触发器发送的反序列化JSON数据。
使用Apex触发器,您可以使用某种形式的预共享密钥来验证请求,从而避免潜在的恶意请求。您还可以让有效负载包含会话ID,以便让Heroku应用程序将REST API请求返回给Salesforce以获取或更新数据。