tin-cat/emailqueue

一个快速、简单但非常高效的PHP/MySQL电子邮件队列系统。

v3.411 2020-07-18 09:15 UTC

This package is auto-updated.

Last update: 2024-09-05 10:45:12 UTC


README

一个快速、简单但非常高效的PHP/MySQL电子邮件队列系统

由 Tin.cat (https://tin.cat) 提供

几乎每个创建过向用户发送电子邮件(如新闻通讯、通知等)的Web应用程序的开发者,最初都尝试使用PHP电子邮件函数或PHPMailer(如精美打造的PHPMailer)等高级电子邮件库来简单发送电子邮件。然而,他们很快意识到,在代码中触发SMTP连接并不是让Web应用程序通过电子邮件与用户通信的最有效方式,主要是因为这会让你的代码负责任何SMTP连接错误,并特别增加所有SMTP延迟到用户体验中。

这就是像Emailqueue这样的解决方案派上用场的地方:Emailqueue不是一个SMTP中继,也不是像PHPMailer(尽管它实际上使用PHPMailer进行最终投递)这样的电子邮件发送库。把它想象成一个中间的、非常快的邮政局,所有需要发送的电子邮件都临时存储、排序和组织,这是它的工作方式

  • 当你的应用程序需要向用户发送电子邮件(或向10,000个用户发送10,000封电子邮件)时,它不是使用PHP邮件函数或PHPMailer,而是简单地将电子邮件添加到Emailqueue。您可以通过调用Emailqueue API、直接注入到Emailqueue的数据库或使用提供的PHP类将电子邮件添加到Emailqueue。

  • 插入操作尽可能快,你的应用程序可以自由地做其他事情。Emailqueue会处理这些。

  • 每分钟,emailqueue都会检查队列,并以其自己的速度发送队列中的电子邮件。您可以配置每封电子邮件之间的延迟和每分钟发送的最大电子邮件数量,以调整交付速度并使外部SMTP更加友好。

  • Emailqueue甚至会对无法发送的电子邮件做一些基本的重试工作,并存储检测到的故障历史记录。

  • 已发送的电子邮件存储在emailqueue的数据库中,以便您可以检查谁收到了什么。自动执行清除过程以删除太旧的已发送电子邮件,以避免emailqueue数据库变得太大。

最佳功能

  • 通过API注入电子邮件:超级简单,超级灵活,从任何地方注入。您也可以直接将电子邮件插入到数据库中或通过提供的PHP类插入。
  • 超快速注入任何数量的电子邮件,并立即让您的应用程序去做其他事情。让Emailqueue在后台处理工作。
  • 优先处理电子邮件:在注入电子邮件时指定一个优先级,它将先于任何具有较低优先级的其他排队电子邮件发送。例如:您可以注入具有优先级10的100k封新闻通讯电子邮件(它们需要一段时间才能发送),同时还可以注入具有优先级1的重要电子邮件(如密码提醒消息),以便在发送大量新闻通讯之前立即发送。
  • 安排电子邮件:现在注入一封电子邮件并指定未来日期/时间以进行计划投递。
  • 代码库相当古老,其根源可以追溯到2000年代初。它已经测试过了!Emailqueue是一个可靠的老者。

Docker版本

有一个官方的 Docker Compose 项目用于 Emailqueue,只需一眨眼即可运行 Emailqueue 服务器。查看它:(https://github.com/tin-cat/emailqueue-docker)。

变更日志

  • 版本 3.4.12

    • 升级 PHPMailer 版本依赖以避免漏洞。
    • is_sentis_cancelledis_blocked 数据库字段默认不设为 0。感谢 @marco-pm 指出这个问题。问题 #29
    • 将 php 和 mysqli 添加到 composer 依赖项中。感谢 @marco-pm 提出这个改进。问题 #28
    • 切换到语义版本控制。(从 v3.412 到 v3.4.12)。
  • 版本 3.411

    • 使用 emailqueue_inject 注入时,电子邮件地址会被修剪以去除前后空格和其他不想要的字符,如 NUL、制表符和回车符。其他小错误已解决。
  • 版本 3.41

    • 添加了通过 "sender" 数组键在 emailqueue_inject 和电子邮件 API 中指定发送者电子邮件地址的选项,允许指定特定的 Return-path 值,因此退回和 SMTP 交付通知消息会发送到发送者而不是发件人。这可能不适用于所有 SMTP 服务器,因为它们可能根据自己政策设置 Return-path。感谢 @Andrewsuares 提出这个改进。这需要更新数据库,您可以通过运行提供的 install/migrate_from_v3.3_or_v3.4_to_v3.41.sql 来执行。
    • 解决了导致电子邮件发送到黑名单地址的bug。感谢 @Andrewsuares 指出这一点!
    • 解决了在检查地址不正确后仍发送电子邮件的bug。
  • 版本 3.4

    • 创建了官方的 Emailqueue Docker Compose 项目(https://github.com/tin-cat/emailqueue-docker),允许您轻松部署一个工作的 Emailqueue 设置。
    • 添加了一个简单的 HTTP API 来排队电子邮件,在将 Emailqueue 运行在隔离服务器上或作为 docker 服务时非常有用。
    • 现在支持暂停和恢复。
    • 更好的脚本。
    • 小型错误已驯服。
  • 版本 3.3

    • 支持表情符号。
    • 现在使用标准 PHP 异常抛出错误,易于捕获。
  • 版本 3.2

    • 切换到 MIT 许可证,现在 Emailqueue 可以用于商业和非 GNU-GPL 项目。
    • emailqueue_inject::inject 方法现在调用方式不同,请参阅“如何使用”部分或 example_local.php 以获取更多信息。
    • "is_send_now" emailqueue_inject::inject 参数发送电子邮件而不等待下一个队列处理事件,非常适合您不能等待一分钟发送电子邮件的情况。
    • 现在使用 composer 进行库依赖。
    • 使用标准 <?php 而不是简写的 <? 版本以提高兼容性。
    • 不再需要配置 LIB_DIR 或 APP_DIR。
    • "is_inmediate" 参数拼写错误已修正876543,现在它被称为 "is_immediate"
  • 版本 3.1

    • 终于支持附件了!请参阅“提示”部分了解这个有趣的想法。
    • 超级强大的功能,可以将消息中的所有图像自动嵌入为附件,因此它们在收到后应该会在用户的屏幕上非常快地显示(客户端无需下载其他图像)。此外,一些电子邮件客户端可能会直接显示图像而无需用户下载。
    • 更好的文档。
    • 一些代码清理。代码仍然非常简单。
    • 对前端进行了一些视觉改进,包括一个全新的 PNG 未来的标志和一个美丽的微型favicon。
    • PHPMailer 库现在是 GIT 子模块。
    • 添加了动物虐待宣言。

待办事项

  • 重新编写文件记录系统。
  • 重新编写以满足现代标准。
  • 提供安全硬链接查看单个电子邮件的方法,以便在电子邮件中包含一个类似“看不到这条消息?点击此处查看”的链接供用户查看。
  • 更强大的后端实时查看队列,以及一些精美的统计图表。

如何安装

  • 将emailqueue存储库克隆到您想要的位置。

    • 出于安全考虑,不要在公共目录中安装Emailqueue。相反,在您的Web服务器配置中创建一个新的路由,指向Emailqueue安装的“前端”目录。
    • 如果您将使用API,在您的Web服务器上创建另一个路由,指向Emailqueue安装的“api”目录。作为额外的安全措施,请确保此路由只能由您将调用API的主机访问,并且您通过HTTPS提供服务。

    $ git clone https://github.com/tin-cat/emailqueue.git

  • Emailqueue依赖于出色的PHPMailer,它通过composer(https://composer.php.ac.cn/)包含。通过运行以下命令安装PHPMailer:

    $ composer update

  • 在您的服务器上创建一个名为您的数据库。例如:emailqueue

  • 在数据库上运行提供的SQL代码install/emailqueue.sql,以创建初始数据库结构。

  • 将config/application.config.inc.php.example和config/db.config.inc.php.example文件复制到不带.php扩展名的版本,如下所示

cp application.config.inc.php.example application.config.inc.php cp db.config.inc.php.example db.config.inc.php

  • 根据您的需要自定义新创建的.config.inc.php文件的正文。这两个文件都进行了良好的文档说明。

  • 确保shell脚本scripts/delivery和scripts/purge是可执行的。

  • 修改scripts/delivery和scripts/purge文件以匹配Emailqueue的安装目录

  • 给脚本赋予执行权限

$ cd scripts
$ chmod +x delivery flush pause purge run unpause
  • 在Linux上设置两个cronjob,定期执行交付和清除脚本,例如

    $ crontab -e

    添加以下行:* * * * * /var/www/htdocs/emailqueue/scripts/delivery 0 6 * * * /var/www/htdocs/emailqueue/scripts/purge

    • 交付脚本将队列中的挂起电子邮件交付。建议每分钟运行一次。

    • 清除脚本从队列中删除旧的和已发送的电子邮件,以避免队列变得过大。每天运行一次就足够了。

  • 现在您应该已经准备好了,您现在可以

    • 通过在浏览器中访问/emailqueue/frontend来查看队列的状态。
    • 使用提供的emailqueue_inject PHP类(位于scripts/emailqueue_inject.class.php中)发送电子邮件。在example_local.php中查看如何使用此类的示例。
    • 您还可以通过手动在数据库中插入消息来将消息注入队列(在“emails”表中插入,阅读字段注释以获取详细说明)。

从版本3.3或3.4迁移到版本3.41

  • 在emailqueue目录中运行$ git pull以获取最新版本。
  • 使用您的数据库管理器,选择您的emailqueue数据库,并运行SQL文件install/migrate_from_v3.3_or_v3.4_to_v3.41.sql

从版本3.2迁移到版本3.3

  • 在emailqueue目录中运行$ git pull以获取最新版本。
  • 使用您的数据库管理器,选择您的emailqueue数据库,并运行SQL文件install/migrate_from_v3.2_to_v3.2.sql

从版本3.1迁移到版本3.2

  • 按照常规安装过程安装此新的3.2版本。
  • 设置与现有Emailqueue数据库相同的数据库连接参数。请注意,db.config.inc.php和application.config.inc.php中的一些小事情已更改,因此您不能使用旧的。
  • 使用您的数据库管理器,选择您的emailqueue数据库,并运行SQL文件install/migrate_from_v3.1_to_v3.2.sql
  • 在安装目录上运行$ composer update以获取最新的phpmailer库。

从低于v3.1的版本迁移

如果您使用的emailqueue版本低于v3.1(发布于2015年12月26日),并且想升级到v3.1或更高版本,请使用您的数据库管理器选择emailqueue数据库,并运行install/migrate_from_versions_older_than_v3.1.sql SQL文件。

如果Emailqueue与您的代码在同一个服务器上,如何使用

文件example_local.php是一个详尽的示例,展示了如何使用提供的emailqueue_inject PHP类通过emailqueue发送电子邮件。当Emailqueue与您的代码安装在同一服务器上,且Emailqueue配置文件和emailqueue_inject.class.php类文件可被您的代码访问时,使用此方法注入电子邮件。

以下是操作步骤

  • 包含以下文件(根据需要指定路径)

    • config/application.config.inc.php
    • config/db.config.inc.php
    • scripts/emailqueue_inject.class.php
  • 实例化一个emailqueue_inject对象,传递数据库连接配置,可以从db.config.inc.php中的相同配置中获取,只需指定以下定义

    $emailqueue_inject = new emailqueue_inject(DB_HOST, DB_UID, DB_PWD, DB_DATABASE);

  • 通过调用emailqueue_inject对象的inject方法发送电子邮件,传递一个包含键的哈希数组,这些键在本文件的“Emailqueue注入键”部分定义。

通过API调用使用

当您在独立服务器或像官方Emailqueue docker compose项目(https://github.com/tin-cat/emailqueue-docker)这样的dockerized环境中运行Emailqueue时,使用此方法:通过标准的HTTP请求调用Emailqueue API将电子邮件添加到Emailqueue中。

API端点URL可能如下所示:https:/// API端点示例:https://192.168.1.100/emailqueue

通过使用名为q的参数调用您的端点,该参数包含以下键的JSON

  • key:在application.config.inc.php中定义的API_KEY
  • message:定义您想注入的电子邮件消息的数组,其中的键在本文件的“Emailqueue注入键”部分定义。
    • 遗憾的是,您还不能通过API调用附加图像,因此当调用API时,“attachments”和“is_embed_images”键将没有任何影响。

注入单个电子邮件的q POST参数的一个示例值

{
	"key":"your_api_key",
	"message": {
		"from":"me@domain.com",
		"to":"him@domain.com",
		"subject":"Just testing",
		"content":"This is just an email to test Emailqueue"
	}
}

要在单个API调用中注入多个消息,请使用“messages”键而不是“message”键

  • messages:定义电子邮件消息的数组,其中每个定义电子邮件消息的数组都有本文件“Emailqueue注入键”部分中定义的键。

注入多个电子邮件的q POST参数的一个示例值

{
	"key":"your_api_key",
	"messages": {
		{
			"from":"me@domain.com",
			"to":"him@domain.com",
			"subject":"Just testing",
			"content":"This is just an email to test Emailqueue"
		},
		{
			"from":"me@domain.com",
			"to":"him@domain.com",
			"subject":"Testing again",
			"content":"This is another test"
		}
	}
}

API将响应包含以下键的JSON对象

  • result:如果电子邮件或电子邮件已成功注入,则为true,否则为false。
  • errorDescription:错误的描述,如果有。

查看提供的example_api.php,了解如何在PHP中调用API的示例。

Emailqueue注入键

无论何时您使用emailqueue_inject类注入电子邮件、调用API或手动将电子邮件插入Emailqueue的数据库,您都可以使用这些键及其描述

  • foreign_id_a:可选,您内部记录的id数字。例如,发送此电子邮件的用户的内部id。
  • foreign_id_b:可选,您内部记录的辅助id数字。
  • priority:此电子邮件相对于其他电子邮件的优先级:优先级越低,发送得越快。例如,具有优先级10的电子邮件将在优先级11的1000封电子邮件之前发送。默认为10。
  • is_immediate:将其设置为true,以将此电子邮件排队以便尽快投递。(不覆盖优先级设置)默认为true。
  • is_send_now:将其设置为true,使此电子邮件立即发送,而无需等待下一次投递调用。这实际上消除了emailqueue的排队功能,并可能在SMTP连接完成期间稍微延迟脚本的执行。在您不希望用户等待一分钟甚至更长时间才能收到消息的情况下使用。默认为false。
  • date_queued:如果指定,则只有在达到给定的时间戳后,此消息才会发送。将其设置为false,以便尽快发送消息。(不覆盖优先级设置)
  • is_html:给定的“content”参数是否包含HTML。默认为true。
  • from:发件人电子邮件地址
  • from_name:发件人姓名
  • to:收件人电子邮件地址
  • replyto:默认情况下,回复此消息的电子邮件地址
  • replyto_name:默认情况下,回复此消息的姓名
  • subject:电子邮件主题
  • content:电子邮件内容。可以包含HTML(如果包含,请将is_html参数设置为true)。
  • content_nonhtml:不支持HTML电子邮件的客户端的纯文本内容(现在相当少见)。如果设置为false,将自动生成给定内容的纯文本版本。
  • list_unsubscribe_url:可选。指定用户可以取消订阅您的邮件列表的URL。某些电子邮件客户端将此URL显示为用户的选项,并且它很可能被许多垃圾邮件过滤器视为良好信号,因此强烈建议使用。
  • attachments:可选。一个哈希数组,指定您想要附加到电子邮件的文件。有关如何构建此数组的具体描述,请参阅example_local.php。
  • is_embed_images:当设置为true时,Emailqueue将在提供的HTML代码的“content”参数中找到所有<img ... />标签,并将它们转换为附加到电子邮件本身的嵌入图像,而不是通过URL引用。这可能会导致电子邮件客户端立即显示电子邮件,而无需用户手动接受加载图像。将此选项设置为true将大大增加SMTP服务器的带宽使用,因为每条消息都将包含所有嵌入消息的副本。每条包含300Kbs图像的10k电子邮件意味着大约3Gb的数据需要传输!
  • custom_headers:可选。一个额外的头信息哈希数组,其中每个键是头信息名称,每个值是其值。

提示

  • 这里有一个小窍门:将一个.vcf卡片附加到您的电子邮件中,以便用户只需点击几下即可将您添加到他们的联系人列表:如果您的“from”电子邮件地址在用户的联系人列表中,许多电子邮件客户端将信任您,这会极大地提高您的电子邮件进入收件箱的可能性。
  • 在将数据发送到emailqueue之前,强烈建议检查所有来自用户输入的参数,以防止SQL注入、XSS和其他奇怪的事情!
  • 调整SMTP以获得良好的收件箱放置相当困难。请务必测试尽可能多的电子邮件提供商,正确实施SPF和DKIM(甚至更好的DMARC),并使用swaks(http://www.jetmore.org/john/code/swaks)等工具进行测试。
  • 如果想要最大化邮箱中放置HTML代码的效果,那么创建用于发送电子邮件的HTML代码会变得很棘手。大多数电子邮件客户端都不喜欢现代的HTML、CSS或高级技术,如果你想使你的电子邮件在尽可能多的客户端中保持一致显示,并且不被分类为垃圾邮件,你应该坚持使用老旧的表格、过时的HTML和非常简单的CSS。获取信息,并花费时间对不同电子邮件客户端和服务提供商进行广泛的测试。最好的开始方式?查看像Twitter和Facebook这样的大公司发送的电子邮件的源代码。欢迎回到1998年。

现代开发者的注意事项

Emailqueue是在2000年代初构建的,当时使用了许多(许多!)业余开发者的技术,那是Cold Fusion和PHP 3版本的时代,如果你习惯了现代编程技术,这里的一些代码可能会让你感到紧张,特别是关于全局变量的技巧、缺乏任何有意义的面向对象编程以及系统区分前端和后端的方式复杂。Emailqueue应该从头开始完全重建,以跟上现代技术和安全标准。

不要使用Emailqueue发送未经请求的电子邮件,或关于动物虐待的电子邮件。

许可证

Emailqueue在MIT许可证下发布(见LICENSE文件)。Emailqueue使用了PHPMailer库(https://github.com/Synchro/PHPMailer),该库在GNU GPL v2.1下授权(https://gnu.ac.cn/licenses/old-licenses/lgpl-2.1.html)。根据GNU GPL v2.1条款第5条:[...] "一个不包含库任何部分派生版本的程序,但通过编译或链接与库一起设计来工作的,被称为“使用库的工作”。这样的工作,在孤立状态下,不是库的派生作品,因此不在此许可证的范围内。" [...], Emailqueue不需要在GNU GPL许可证下发布。