【问题标题】:Send Scheduled Email using Azure Scheduler / Postal / MVC使用 Azure 调度程序/邮政/MVC 发送预定电子邮件
【发布时间】:2016-01-19 18:43:31
【问题描述】:

我的项目托管在 Azure 上,我想每天早上向忘记在我的应用程序中完成某些任务的用户发送一封电子邮件。

我已经建立了我的电子邮件(使用邮政发送)。如果我自己运行该功能,电子邮件会按预期发送。

我已将 Azure 调度程序配置为运行 HTTPS 操作、get 方法 [https://www.example.com/Email/EmailReminder]。计划的作业报告为成功,但没有电子邮件发送出去。

我以前不必这样做,所以我怀疑我的函数 > 调度程序作业之间缺少链接。我已经搜索了有关如何设置它的代码示例,但我还没有找到解决方案。调度程序期望我不给它什么?

public void EmailReminder()
{
     var remCheckOuts = // query code here                                
     into grouped
     select new Reminder
     {
          /// populate viewmodel 
     });    

    // send emails
    foreach (var i in remCheckOuts)
    {
                string Full = i.Full;
                string FirstName = i.FirstName;
                var CheckOutCt = i.CheckOutCt;                   

                dynamic email = new Email("emReminder");
                email.FromAdd = "test@test.com";
                email.To = "test2@test2.com";
                email.NPFirstName = NPFirstName;
                email.CheckOutCt = CheckOutCt;
                email.Send();
      } 
}

【问题讨论】:

  • 您是否在 web.config as described here 中正确配置了出站 SMTP 端口?提示 - Azure 没有为你提供纯 SMTP 服务器 - 你需要像 SendGrid 这样的第三方,或者如果你想自己动手,你可以启动一个虚拟机。
  • 是的 - 如果只是访问运行上述功能,电子邮件将正确发送。但是,我设置用于访问此页面的调度程序运行成功,但没有发送任何内容。我知道我的代码中缺少调度程序正在寻找的东西。如果它是从上面创建一个 cron 作业,我不知道该怎么做....
  • 您如何确定电子邮件没有发送出去?您说该作业显示它在作业历史记录中运行,并且当您手动点击链接时,电子邮件就会消失。也许存在身份验证问题?如果是这样,也许these docs 会有所帮助。
  • 我已将自己设置为测试的接收者,并且 Azure 站点显示作业运行成功。我会调查这个身份验证问题,也许这就是问题所在。为了测试,我关闭了任何身份验证要求,但也许我遗漏了一些东西!
  • 我遇到了身份验证问题。我的原始脚本现在正在发送。谢谢。

标签: c# asp.net-mvc azure postal


【解决方案1】:

我认为你最好的选择是网络作业。我假设你已经有一个 Web App,所以如果你添加一个使用 Webjob SDK 的 Webjob,你可以创建一个带有签名的函数:

public class Functions
{
    public static void ProcessTimer([TimerTrigger("0 0 9 1/1 * ? *", RunOnStartup = true)]
    TimerInfo info)
    {
        var remCheckOuts = // query code here                                
     into grouped
     select new Reminder
     {
          /// populate viewmodel 
     });    

    // send emails
    foreach (var i in remCheckOuts)
    {
                string Full = i.Full;
                string FirstName = i.FirstName;
                var CheckOutCt = i.CheckOutCt;                   

                dynamic email = new Email("emReminder");
                email.FromAdd = "test@test.com";
                email.To = "test2@test2.com";
                email.NPFirstName = NPFirstName;
                email.CheckOutCt = CheckOutCt;
                email.Send();
      } 
    }
}

它使用TimerTrigger 在给定时间触发(由CRON expression 定义),它比HTTP POST 方法(您需要考虑HTTP 超时)简单得多。

如果您在使用 CRON 表达式时遇到问题,请查看CronMaker

对于电子邮件发送和跟踪 WebJobs SDK 示例,您可以使用 SendGrid extension 与队列进行解耦配对,这样您就可以拥有多个 TimerTrigger 功能(例如,Morning mails、Evening X 用途的邮件、Y 用途的夜间电子邮件、月度报告)和一个发送所有邮件的功能:

public class MailNotification{
    public string From {get;set;}
    public string To {get;set;}
    public string Subject {get;set;}
    public string Body {get;set;}
}

public class Functions
{
    public static void MorningMail([TimerTrigger("0 0 9 1/1 * ? *", RunOnStartup = true)]
    TimerInfo info, [Queue]("mail") ICollector<MailNotification> mails)
    {
        var remCheckOuts = // query code here                                
     into grouped
     select new Reminder
     {
          /// populate viewmodel 
     });    

    // send emails
    foreach (var i in remCheckOuts)
    {
            mails.Add(new MailNotification(){
                To = "test2@test2.com",
                From = "test@test.com",
                Subject = "Whatever Subject you want",
                Body = "construct the body here"
            }); 

      } 
    }

    public static void EveningMail([TimerTrigger("0 0 18 1/1 * ? *", RunOnStartup = true)]
    TimerInfo info, [Queue]("mail") ICollector<MailNotification> mails)
    {
        var remCheckOuts = // query code here                                
     into grouped
     select new Reminder
     {
          /// populate viewmodel 
     });    

    // send emails
    foreach (var i in remCheckOuts)
    {
            mails.Add(new MailNotification(){
                To = "test2@test2.com",
                From = "test@test.com",
                Subject = "Whatever Subject you want",
                Body = "construct the body here"
            }); 

      } 
    }

    public static void SendMails([QueueTrigger(@"mails")] MailNotification order,
        [SendGrid(
            To = "{To}",
            From = "{From}",
            Subject = "{Subject}",
            Text = "{Body}")]
        SendGridMessage message)
    {
        ;
    }
}

【讨论】:

  • 这种方法的缺点是 Web 作业必须“始终在线”,而 Scheduler 只能在预定时间运行作业。在选择之前应该进行成本效益分析。另见:azure.microsoft.com/en-us/documentation/articles/…
  • 确实如此,如果 Web 应用程序已经处于 Always On 状态,则无需额外费用。虽然调度器存在 HTTP 超时处理的技术问题,但它会尝试重新运行作业,除非您更改重试策略,这不是简单的壮举,只能通过 Management API 来实现。
  • 有趣。有更多详细信息的链接吗?此外,我认为 OP 的问题与其说是关于调度程序,不如说是关于正在使用的电子邮件库。
  • 我感觉我会在我的应用程序中添加一些这样的电子邮件提醒。我想要一些可以可靠运行的东西。我是否正确理解我需要将我的电子邮件功能转换为 CRON 工作?如何将上面的函数转换为可上传到调度程序的 CRON 作业或文件?这对我来说是新的。
  • 正如马特建议的那样,Azure 不发送邮件。您需要一个外部 SMTP 服务(Sendgrid、MailGun、AmazonSES)。您有 2 个可能的选项来安排工作: 1-继续使用 Azure 调度程序并使用外部 SMTP 发送邮件,但您必须记住,调度程序将等待 30 秒,如果您花费超过 30 秒来完成所有操作您的发送,调度程序将失败并尝试再次运行该操作,这可能不好。 2-使用 Webjobs,它可能看起来更令人生畏,但这是它们所针对的场景类型。
【解决方案2】:

关于我为什么 Azure 调度程序没有发送我的电子邮件的问题,这是在 Azure 门户中解决的身份验证问题。

Matias 的回答也是正确的,以及我未来的发展方向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    相关资源
    最近更新 更多