当前位置: 首页 > 知识库问答 >
问题:

通过触发器运行异步Apex类

荀正谊
2023-03-14

我正在SF中的自定义对象上创建Apex触发器。现在我有一个对象约会,我想在保存新记录时触发调用。由于我们的内部流程,我们不需要担心更新。仅限新记录。

也就是说,我已经创建了触发器和类的基础知识,并且它们很有效。触发器运行标记为Future的类以运行异步。然而,课堂是我迷路的地方。

我想将一些变量从正在创建的约会对象中的记录传递到代码中。我的代码向向向客户发送短信的服务发送HTTP帖子。我想使用电话号码、客户姓名和消息中包含约会日期和时间的消息。存储此数据的字段包括:

i360\uuu Prospect\u Phone\uu c

i360__Correspondence_Name__c

i360\uuu Start\uu c

i360__Start_Time__c

例如,我需要电话号码和姓名才能传输到下面的类代码中。至于消息,我希望以字符串的形式发送,其中包含变量。示例:“您好i360__Correspondence_Name__c,您与COMPANY的约会已安排在i360__Start__ci360__start_Time__c。如果您有任何问题,请回复或致电。”

这是我的触发代码:

trigger sendtext on i360__Appointment__c (after insert) {
  System.debug('Making future call to update account');
  for (i360__Appointment__c app : Trigger.New) {


    PodiumText.updateAccount(app.Id, app.Name);
  }
}

这是我的类代码:

public class PodiumText {
//Future annotation to mark the method as async.
  @Future(callout=true)
  public static void updateAccount(String id, String name) {

 Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://api.podium.com/api/v2/conversations');
        request.setMethod('POST');
        request.setHeader('Content-Type', 'application/json');
        request.setHeader('Accept', 'application/json');
        request.setHeader('Authorization', 'IDSTRING');
        request.setBody('{"customerPhoneNumber":"PHONENUMBER","message":"Testing","locationId":"49257","customerName":"CORRESPONDENCENAME"}');
        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());
        }

  }
}

任何帮助都会很好。

共有1个答案

帅银龙
2023-03-14

理想情况下,您不会每次将此@未来方法称为一个帐户。每笔交易最多50次呼叫(https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm查找“具有未来注释的最大方法数”。所以,当您从UI插入1条记录时,您现在所拥有的将非常好地工作,但如果您进行大规模数据加载,则会严重失败。

因此,您可以调用它一次,但要传递一个包含数据的列表(数组)。我们可以只传递记录ID,然后在方法本身中查询您需要的字段。或者,您可以在触发器中构建消息的文本,并将字符串列表传递给@future方法。这是个人喜好,我认为传递记录ID更干净。这样,触发器就不在乎到底发生了什么,它只会发出“哟,根据这些数据发送你需要的任何消息”。而实际的调用代码保存在一起(endpoint和消息构建),因此如果您想要更改某些内容,只需在一个文件中即可。

诸如此类(消息的顺序重要吗?如果不重要,可能会更简单一些)

trigger sendtext on i360__Appointment__c (after insert) {
  List<Id> ids = new List<Id>();
  for (i360__Appointment__c app : trigger.New) {
     ids.add(app.Id);
   }

  System.debug('Making future call to update account');
  PodiumText.updateAccounts(ids);
}

然后呢

@future(callout=true)
public static void updateAccounts(List<Id> ids){
    Map<Id, i360__Appointment__c> appointments = new Map<Id, i360__Appointment__c>([SELECT Id, Name, 
            i360__Prospect_Phone__c, i360__Correspondence_Name__c, i360__Start__c, i360__Start_Time__c
        FROM i360__Appointment__c
        WHERE Id IN :ids]);

    Http http = new Http();
    HttpRequest request = new HttpRequest();
    request.setEndpoint('https://api.podium.com/api/v2/conversations');
    request.setMethod('POST');
    request.setHeader('Content-Type', 'application/json');
    request.setHeader('Accept', 'application/json');
    request.setHeader('Authorization', 'IDSTRING');

    for(Id i : ids){
        i360__Appointment__c appointment = appointments.get(i);

        Map<String, String> message = new Map<String, String>{
            'customerPhoneNumber' => appointment.i360__Prospect_Phone__c,
            'message' => 'Testing',
            'locationId' => '49257',
            'customerName' => appointment.i360__Correspondence_Name__c
        };
        String messageJson = JSON.serialize(message);
        System.debug(messageJson);

        request.setBody(messageJson);
        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());
        }
    }
}

如果这有效(我还没有检查它是否会编译,而且我没有安装这个应用程序),那么最后一部分将是放置真实消息而不是“测试”。这部分取决于这些字段到底是什么(开始时间是文本/选择列表字段吗?时间字段?)。有有趣的String.format()方法,但我们可以保持简单(感觉我已经让你接触了很多,查询,地图,JSON序列化...)

String message = 'Hello ' + appointment.i360__Correspondence_Name__c + ', your appointment with COMPANY has been scheduled on ' + appointment.i360__Start__c + ' at ' + appointment.i360__start_Time__c + '. Please respond or call if you have any questions.';

(实际上,我给你的也不是百分之百的完美。有一个“调用总数”的限制,100。因此,如果你进行大规模数据加载,你需要重新编写此代码,以便将来可能进行两次调用,每次调用100条记录,或10*20…)

 类似资料:
  • 代码本身没有给出任何错误,但每当我运行它时,Trailhead都会给我以下消息: “挑战尚未完成……问题是:执行触发器没有按预期工作。” 以下是说明: 对于此质询,您需要创建一个触发器,在插入或更新之前检查复选框。如果复选框字段为true,则会将发货邮政编码(其API名称为ShippingPostalCode)设置为与帐单邮政编码(BillingPostalCode)相同。 Apex触发器必须调用

  • 我想写一个Apex代码并进行调试。我登录了Salesforce,在Salesforce开发人员控制台中,Apex类和Apex触发器是不可见的。我不能点击那个。 路径:Salesforce开发者控制台

  • 我已在Salesforce APEX中记录了触发器。它工作正常。 触发器代码为: 现在我正在尝试为它的测试类编写代码。它在线上给出错误,说对象无法解析为字符串。 测试等级代码为: 期待找到解决方案。任何帮助都将不胜感激。 谢谢

  • 我通过jira触发器插件将jenkins作业设置为触发器<但是jenkins作业没有被触发,尽管它从JIRA那里获得了webhook事件。 我检查了如下内容。 Jenkins得到了网络钩子事件。我在詹金斯日志上检查了这个。 我试着为詹金斯设置各种方式,但都失败了。我想知道如何设置jira触发器 > 测试环境 吉拉:6.4.11 我的测试用例是。。。 Jenkins工作设置 选中:向JIRA添加注释

  • 问题内容: 我有一张上面有插入触发器的表。如果我从存储过程中的一条插入语句中向该表中插入6000条记录,那么在插入触发器完成之前,存储过程会返回吗? 只是为了确保我在正确地思考,触发器应该只被调用一次(我知道“被调用”不是正确的词)一次,因为只有1个insert语句,对吗? 我的主要问题是:即使触发器尚未完成,存储过程也会完成吗? 问题答案: 您的插入触发器将针对整个插入语句运行一次。这就是为什么

  • 问题内容: 我在中有一个(),如果按下该按钮,我将在for循环中对其列表中的列表执行任务。这样做时,我需要更新。 问题是,当我按下JButton时,该任务是在事件调度线程(EDT)中执行的。因此,我无法更新在主线程或UI线程中触发的事件。 现在,源代码对我不可用,因为我完全更改了源代码,并尝试使用Eclipse SWT 触发Swing时,它变得混乱。 现在我得到了错误,因为Display对象在单独