我现在使用以下结构工作(我为格式道歉 - 它主要是伪代码):
ASyncRequest 对象:AsyncType(选择列表:'SMS to Twilio'),Params(长文本区域:逗号分隔的 ID 列表)
消息对象:To(电话)、From(电话)、Message(文本)、Sent(布尔)、smsId(字符串)、Error(文本)
消息触发器:将触发器详细信息传递给 CreateAsyncRequests() 方法。
CreateAsyncRequests:评估每个新的/更新的 Message__c;如果任何消息的 Sent == false,我们创建一个 AsyncRequest,type=SMS 到 Twilio,Params += ',' + message.Id。
// 创建一个待处理完所有消息后插入的列表 List requests = new List();
一旦我们在单个 AsyncRequest.Params 列表中达到 5 个 message.Id,将其添加到请求中。如果所有消息都已处理,并且 Params 中有 < 5 个 Id 的请求,则也将其添加到请求中。
If requests.size() > 0 {
insert requests;
AsyncProcessor.StartBatch();
}
AsyncProcessor 实现了 .Batchable 和 .AllowsCallouts,并在 ASyncRequest__c 中查询需要处理的任何请求,在这种情况下,这将是我们的 Messages 列表。
execute() 方法获取 ASyncRequests 列表,将每个 Params 值拆分为其组件消息 Id,然后在消息对象中查询这些特定消息。
StartBatch() 一次使用 1 条记录调用 execute(),因此每个 execute() 进程仍将包含少于最多 10 个标注。
每条消息都在调用 SendMessage() 的 try/catch 块中处理,设置 Message.smsId = Twilio.smsId 并设置 Message.Sent = true。
如果没有返回 smsId,则该消息未发送,我设置一个布尔值 bSidIsNull = true 表示(至少)一条消息未发送。
** 如果任何消息失败,即使是成功的消息也不会返回 smsIds **
每批消息处理完后,我检查bSidIsNull;如果为真,那么我将返回消息列表并将任何没有 smsId 的消息放入由我尝试发送它们的 Twilio 编号索引的地图中。
由于我将每个 ASyncRequest 限制为 5 条消息,因此我仍然可以使用标注来检索从该 Twilio.From 号码在当前日期发送的所有消息,使用
client.getAccount().getMessages('From' => fromNumber, 'DateSent' => currentDate)
然后我可以为所有成功的消息更新 Message.smsIds,并为任何失败的消息添加一条错误消息到 Message.Error_on_Send__c。