2

我正在尝试通过创建一个触发器来解决基于“邮箱已满”的退回电子邮件问题,该触发器在邮件包含“邮箱已满”时重新发送该邮件。

我面临的问题是我需要将重新发送的次数限制为 3 次。一旦收到退回的电子邮件,我现在就会不断重新发送电子邮件。

我的触发器是

trigger trgBouncedEmails on EmailMessage (after insert) {

  for(EmailMessage myEmail: trigger.New) {


    //mail box full bounced email 
    if (myEmail.HtmlBody.contains('full'))
    {

        Case[] parentCase = [Select c.Id from Case c where c.Id =: myEmail.ParentId];


         if (myEmail.Subject.contains('Financial Review'))
                parentCase[0].Resend_Email_Send__c = true;  // this will trigger a workflow to send the email again.

          Update parentCase;
              }
      }
}

如何限制重新发送,有没有办法可以在执行“更新 parentCase”之前设置等待时间

有没有更好的方法来解决这个问题,知道我有不同类型的电子邮件,每个都有不同的模板和不同的目的。

编辑 系统应该以24小时的频率自动重新发送电子邮件3次,然后在24小时后停止重新发送。我的触发器无限期地重新发送,我试图找到一种等待的方法,这样它只能在 24 小时内发送 3 次,比如每 8 小时一次。

4

3 回答 3

2

@grigriforce 击败了我-我还建议使用字段来计算重试次数,而不是简单的布尔值。这是一个“大型”触发器,其逻辑与您发布的触发器基本相同:

trigger trgBouncedEmails on EmailMessage (after insert) {
    List<Id> parentCaseIds = new List<Id>();
    for ( EmailMessage myEmail : trigger.New ) {
        // mail box full bounced email for Financial Review emails
        if ( myEmail.HtmlBody.contains('full') && myEmail.Subject.contains('Financial Review') )
            parentCaseIds.add(myEmail.ParentId);
    }
    Case[] parentCases = [select c.Id from Case c where c.Id in :parentCaseIds];
    for ( Case c : parentCases ) {
        c.Resend_Email_Count__c += 1;  // this will trigger workflow to send the email again
        c.Resend_Email_Time__c = System.now();  // keep track of when it was last retried
    }
    update parentCases;
}

更新以在 24 小时内平均分配电子邮件:

重新设计您的工作流程以确保自Resend_Email_Time__c上次设置以来已经过了 8 小时,然后安排 Apex 作业每小时运行一次以获取需要重新发送其电子邮件的符合条件的案例,并对其调用更新以确保工作流程不会不开火不要太久:

global class ResendCaseEmails implements Schedulable {
    global void execute(SchedulableContext sc) {
        Contact[] cs = [select id, Resend_Email_Count__c, Resend_Email_Time__c from Contact where Resend_Email_Count__c < 4];
        List<Contact> ups = new List<Contact>();
        for ( Contact c : cs ) {
            if ( c.Resend_Email_Time__c != null && c.Resend_Email_Time__c.addHours(8) < System.now() )
                ups.add(c);
        }
        update ups;
    }
}

**请注意,在实现 Schedulable 的类中包含此代码不是最佳实践 - 此代码理想情况下位于该类调用的另一个类中ResendCaseEmails

您可以通过从开发人员控制台调用此代码来安排此作业每小时运行一次:

ResendCaseEmails sched = new ResendCaseEmails();
String cron = '0 0 * * * ?';
System.schedule('Resend Case Email Job', cron, sched);
于 2012-07-26T15:03:05.163 回答
1

您可以简单地将案例上的重新发送布尔值更改为发送尝试的整数计数,并让您的工作流规则仅在该计数小于 3 时重新发送。

Case[] parentCase = [Select c.Id, c.Resend_Email_Count__c from Case c where c.Id =: myEmail.ParentId];
if (myEmail.Subject.contains('Financial Review'))
            parentCase[0].Resend_Email_Count__c += 1;  // this will trigger a workflow to send the email again.

      Update parentCase;

另外,我假设您简化了触发器以显示问题,但如果不是,您真的需要将其放大。

于 2012-07-26T14:51:59.530 回答
0

所以,这就是你想要发生的事情(如果我错了,请随时纠正我)。您发送一封电子邮件,如果它被退回,您希望每 8 小时重新发送一封电子邮件。重发次数最多应为 3 次。

在这种情况下,我不会只使用触发器。相反,我会设计一个解决方案,使用触发器、调度程序,也许还有一个自定义表格来跟踪退回的电子邮件。

让我们将此表/对象称为“退回电子邮件跟踪器”。它将具有以下 3 个字段:

  1. 电子邮件名称(电子邮件的一些独特描述)
  2. 电子邮件状态(已发送、退回、重新发送、失败)
  3. 重发次数
  4. 已发送电子邮件时间戳

如果并且当发送电子邮件时,您将使用状态设置为“已发送”和“已发送电子邮件”的触发器在此表中创建一个条目。如果电子邮件退回,另一个触发器会将表中的条目“更新”为将记录的状态更改为“已退回”。

调度程序将定期运行,它将从此新表中检索状态等于“退回”的所有记录,并使用“已发送电子邮件时间戳”中的值检查上次发送电子邮件的时间。它将根据发送的时间执行以下操作,并重新发送计数。

  • 如果重新发送计数小于 3,并且最后一封电子邮件的发送时间超过或等于 8 小时前,请从调度程序发送另一封电子邮件。将记录的状态更改为“已发送”。
  • 如果重发次数大于 3,并且状态为“Bounced”,则将状态更改为“Failed”。
  • 如果重新发送的次数少于 3,但最后一封电子邮件是在 8 小时前发送的,则不要执行任何操作。

我知道这是一个很大的努力,我相信它可能需要更多的思考,但这将提供一个强大的框架来跟踪和重新发送退回的电子邮件。希望这可以帮助!

阿努普

于 2012-07-27T11:29:56.033 回答