【问题标题】:How to set up drip email system for PHP app如何为 PHP 应用程序设置滴灌电子邮件系统
【发布时间】:2014-02-01 08:19:27
【问题描述】:

我的 Web 应用程序使用的是 CakePHP 2.4,我计划构建一个 "drip" email 功能,以便随着时间的推移发送后续电子邮件。这是现代网站中非常常见的功能,但我对我能找到的资源如此之少感到惊讶。

我的问题:是否有任何既定的模式可以做到这一点?我有一些想法,但我不想重新发明轮子。

(我快速搜索了一下,结果一无所获。)

注意:我知道 MailChimp 之类的服务会执行此操作,但我的“滴灌”需要动态完成,因为它们与可能已经发生或未发生的用户操作相关联。例如:如果用户尚未完成他们的个人资料,我想每 3 天发送一封电子邮件。一旦他们这样做,他们应该停止滴水。

【问题讨论】:

  • 设置 cron 作业以检查操作日期与现在,当满足您的条件时间限制时,cron 发送电子邮件。不需要外部服务,如果您愿意,可以使用标准 mail() 来完成。只是记录每次用户执行操作的时间/日期的情况,以便您进行比较
  • @Dave 你能把这个作为答案发布吗?
  • 你去吧,我试图解释逻辑而不是 100% 完整的代码,这样你就可以自己计算出实际的代码。

标签: php email cakephp


【解决方案1】:

按要求进行。

基本上它更多的是逻辑/工作流程问题。

在您的情况下,您希望在 3 天后以及之后每 3 天警告用户他们的个人资料不完整。

因此,首先您需要某种方法来检测他们的个人资料不完整,在这种情况下,我将使用标志字段 IsComplete 0/1。默认为 0(不完整)。我们还想知道用户注册的日期,因此我们将使用一个简单的 mysql 时间戳字段填充 yyyy-mm-dd H:i:s 格式的 mysql 日期,我们还想知道用户的日期是最后一封电子邮件通知。为此,我们这次将使用另一个 mysql 字段,格式相同的日期时间字段 yyyy-mm-dd H:i:s。

所以我们的用户 db 现在看起来像这样(注意 mysql 语法不正确)

IsComplete TINYINT 1 DEFAULT 0,
SignupDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
LastWarnDate DATETIME DEFAULT NULL

最后警告日期的 NULL 很重要!

在您的前端用户个人资料编辑/更新页面上,您只需将以下内容添加到保存位中

if (PSEUDO_CODE_ALL_FIELDS_ARE_COMPELTED==TRUE) {
    "UPDATE tblusers SET IsComplete=1";
}

现在我们已经解决了这个问题,让我们看看基本逻辑。

滴灌邮件程序只需每天检查一次您的数据库以了解待处理的操作,然后根据需要发送通知电子邮件。我们可以通过在 linux crond 上运行的基本无头 cron 任务来实现这一点。您可以在 google 上找到通过 cron 运行 php 脚本的示例,几乎第一个响应正是您想要的。我不会深入讨论,而是更深入地了解实际的 cron 脚本。

所以现在我们知道用户何时注册您的网站,我们知道他们的个人资料是否完整,以及我们上次警告他们的时间。 我们的 cronjob 既好又简单,它所要做的就是检查个人资料是否完整,如果没有,然后检查日期并发送电子邮件。

$query = "SELECT EmailAddress,SignupDate,LastWarnDate FROM tblusers WHERE IsComplete=0"; //we don't need to bring back the completed users so for speed we look at uncomplete only

if (strlen($query->LastWarnDate) < 5) {  // this is a little nasty but will work NULL is in the db field which returns 4 characters on strlen so a quick check that its < 5 means that we don't have a proper date in the field.  There's better ways of doing this i'm being brief

// ok no last warn date so check sign up date vs now
    if (DATE_DIFF($query->SignupDate,now()) >=3) {
        //3 days or longer since signups so do first warn
        "update tblusers SET LastWarnDate=NOW()";
        mail();  //standard php mail function for sending email you can use swiftmail or another component if you like
    } // its been less than 3 days so do nothing no need for an else
} else {

//we have a last warn date so check warn date vs now
    if (DATE_DIFF($query->LastWarnDate,now()) >=3) {
        //3 days or longer since last warn date so update last warn date to now and email
        "update tblusers SET LastWarnDate=NOW()";
        mail();  //standard php mail function for sending email you can use swiftmail or another component if you like
    } //its been less than 3 days so do nothing no need for an else
}

这就是非常基本的逻辑流程和示例无效的 php,但您应该能够非常容易地将最终解决方案基于代码。

将 cron 作业安排在每晚午夜运行,您就完成了。

【讨论】:

  • 谢谢@Dave。这正是我希望进行的那种讨论......在您的示例中,您建议使用用户表中的额外列来跟踪“滴水”。如果我想发送几种不同的滴水,你还会推荐这个吗?例如,假设用户还没有验证他们的电子邮件,他们会得到另一个滴水。重用 lastWarnDate 字段并按相同的时间表发送它们可能没什么大不了的,但是在添加了更多不同的滴灌标准之后,我担心表格会变得笨拙。你怎么看?
  • 在我的示例中,您必须为第二次检查创建第二个警告列,您也可以重用最后一个警告日期,但您必须应用其他列来跟踪最后一个警告操作,即:如果您每 2 天对未完成的电子邮件地址发出警告,那么它将永远不会触发配置文件完成警告,因为它永远不会在更新前 3 天达到。当然,使用滴灌式电子邮件发送到未经验证的电子邮件无论如何都是一个坏主意,因为如果它输入错误只会在您的邮件队列中发送垃圾邮件。
  • 如果您要对很多不同的功能/操作发出警告,那么您最好创建一个滴漏跟踪表,在列中放置一个用于发送警告类型/模板的列,最后一个警告日期,然后扩展您的 cron 脚本,而不是循环遍历用户表,您循环遍历作业表,搜索每个不同的类型/模板,然后进行日期比较循环。然后编写一个清理 cron 以清空 30 天以上的所有内容并每月完成一次,如果用户在 30 天后还没有完成,那么你的表会变得太大,你也可以删除该用户。
  • 这正是我所追求的方向。谢谢!我会在一分钟内发布一个答案,概述我的想法。
  • 请记住,您不希望向您的用户发送数千封滴灌邮件,它们应该最多用于 1 或 2 个事件,否则您将大量增加您的服务器垃圾邮件排名并作为您的用户群增长你每天将发送成百上千的邮件。
【解决方案2】:

正如@Dave 在他的回答中所讨论的那样,我正在考虑在专用表中跟踪滴水,以便为自己购买更多的灵活性...

创建一个包含以下字段的drips 表:

  • id (INT)
  • 类型(INT 或 ENUM)这映射到特定类型的滴水及其相应的条件等
  • user_id (INT) 外键链接到将收到电子邮件的用户
  • user_email* (VARCHAR) (可选)用户的电子邮件地址
  • count (INT) 跟踪它被发送多少次以用于限制滴水次数
  • last_sent (datetime) 跟踪上次发送它以用于维护间隔的日期

当发生可能与滴灌有关的操作时,我会检查此表并相应地添加/删除计划的滴灌。例如,当用户完成他们的个人资料时,我会检查此表并删除相应的点滴。 (

每天晚上,都会运行一个 cron 作业,该作业会循环运行并发送与每个 type 对应的电子邮件,并且这些电子邮件与代码中设置的时间间隔相匹配。该作业会增加 count 字段,并且可能还会删除已达到最大值的记录(可能在作业结束时进行查询)。

【讨论】:

  • 跟踪代码中的滴漏非常容易。理想情况下,只需创建一个控制器函数或类,然后将所有的滴水代码放在那里,然后像 $dripclass->drip(1); 这样调用它。等或 $dripclass->profileDrip();但是,您希望以统一代码的方式来处理它,并且您不必每次都在所有代码中四处寻找滴水。此外,无需从表格中删除,只需将滴灌标记为已完成并在 6 个月左右后将其清除,这样您就可以对用户完成任务之前滴灌的次数进行部分报告统计。
猜你喜欢
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多