2amigos / mail-service
Slim 3 邮件API微服务
Requires
- php: ^7.2
- ext-json: ^1.6
- crell/api-problem: ^2.0
- enqueue/enqueue-bundle: ^0.9.7
- enqueue/fs: ^0.9.2
- gettext/gettext: ^4.6
- gofabian/negotiation-middleware: ^0.1.2
- guzzlehttp/guzzle: ^6.3
- league/flysystem: ^1.0
- league/fractal: ^0.13.0
- league/tactician: ^1.0
- lstrojny/functional-php: ^1.6
- micheh/psr7-cache: ^0.5.0
- monolog/monolog: ^1.17
- mustache/mustache: ^2.12
- slim/slim: ^3.9
- symfony/console: ^4.2
- symfony/dotenv: ^4.2
- symfony/framework-bundle: ^4.2
- symfony/options-resolver: ^4.2
- symfony/swiftmailer-bundle: ^3.2
- symfony/yaml: ^4.2
- tuupola/base62: ^1.0
- tuupola/cors-middleware: ^0.8.0
- tuupola/slim-basic-auth: ^3.2
- tuupola/slim-jwt-auth: ^3.1
- zendframework/zend-inputfilter: ^2.8
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.10@dev
- overtrue/phplint: ^1.0
- phpunit/phpunit: ^7.3
- roave/security-advisories: dev-master
- squizlabs/php_codesniffer: ^3.2
This package is auto-updated.
Last update: 2024-09-22 19:42:02 UTC
README
邮件服务是一个使用mustache模板发送邮件的邮件微服务。它被构建来允许我们的开发团队在涉及微服务基础设施的项目中避免反复配置邮件。它是由两个独立的应用程序组合而成的,一个是由Symfony的CI应用程序,另一个是使用Slim3构建的API,因为它使用了队列技术。
项目使用Monolog进行日志记录,Fractal作为序列化器,Tactitian作为命令总线,gettext进行翻译,基本访问认证和Json Web Tokens进行认证(这是可选的),以及Zend filter进行数据过滤和验证。
包含Docker compose和Postman collection文件,便于开发,尽管开发过程中不一定严格需要docker,因为可以使用PHP内置服务器。
项目试图遵循DDD原则。
安装
使用composer安装最新版本。
$ composer create-project --no-interaction --stability=dev 2amigos/mail-service app
如果您是从私有仓库使用(以下以github url为例)。
$ composer create-project --no-interaction --stability=dev 2amigos/mail-service app --repository-url=https://github.com/2amigos/mail-service
配置
该项目使用环境文件来配置秘密,因此您必须在项目的根目录下创建一个名为.env
的文件。已经提供了一个包含所有必需环境值的.env.example
文件。修改该文件并将其保存为根目录下的.env
。
默认情况下,API应用程序配置为在基本认证过程中工作。它使用用户数组来此目的,但您可以轻松更改此行为,通过创建自己的或使用库中提供的HttpBasicAuthentication中间件来配置authenticator
选项。查看PdoAuthenticator。
如果认证成功,操作将返回一个用于后续调用的Json Web Token。
认证或作用域的使用是可选的。如果您不希望使用此类设置,只需删除HttpBasicAuthentication
、JwtAuthentication
和ScopeMiddleware
中间件的中间件配置。
应用程序最重要的部分是其views
,它们需要位于views/txt
和views/html
子目录中。它们的名字已经说明了每个目录应该包含什么类型的模板。
它还通过使用 gettext
支持多语言。已提供示例翻译文件和模板,以帮助您了解其工作原理。我们还添加了一个命令,用于与优秀的本地化管理平台 POEditor 一起使用。该命令将为您导入翻译并转换文件为 .php
文件。要从 POEditor
导入所需翻译到您的项目中,请使用以下命令
$ ./bin/console import-translations:run --api-token={POEDITOR_TOKEN} --project={PROJECT_ID} --languages=es,de --delay=3
其中 {POEDITOR_TOKEN} 和 {PROJECT_ID} 分别是您的令牌和项目 ID。
翻译将自动导入到 ./i18n/
文件夹。
为了与翻译一起工作,我们还包含了一个帮助类,用于处理 Mustache
,该类将解析内容并尝试获取 {{#i18n}}{{/i18n}}
标签内的翻译文本。请参阅本项目提供的示例视图。
用法
为了示例起见,请转到应用的 public
文件夹,并像这样启动内置的 PHP 服务器
php -S localhost:8080
现在我们可以访问 http://127.0.0.1:8080
上的 api。
获取令牌
要获取令牌,请使用以下
$ curl "https://127.0.0.1:8080/token" \ --request POST \ --include \ --insecure \ --header "Content-Type: application/json" \ --data '["mail.all"]' \ --user test:test HTTP/1.1 201 Created Content-Type: application/json { "data": { "token": "XXXXXXXXXX", "expires": 1550271641 } }
发送电子邮件(到队列中)
使用 token
,您现在可以使用 application/form-data
提交请求来发送电子邮件。
curl -X POST \ http://127.0.0.1:8080/mail/send \ -H 'Authorization: Bearer YOUR_TOKEN_HERE' \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -H 'Postman-Token: 22bf2715-35e4-41ee-a04b-fd8beddcdd62' \ -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \ -F from=noreply@example.com \ -F to=user@example.com \ -F 'subject=Testing micro-services' \ -F template=hello-world \ -F 'data[name]=World' \ -F language=es \ -F 'attachments[]=@/path/to/image/to/attach/41835188_10217308479844850_6484466208170049536_o.jpg'
上述命令将在默认配置在 runtime
文件夹的队列目录中创建一个电子邮件消息。
参数
from
: 可选。消息来自谁。如果没有指定,邮件消息将使用名为MAIL_NO_REPLY_EMAIL
的环境变量进行配置(请参阅.env.example
文件)。to
: 必需。消息的收件人。subject
: 必需。这是发送者将电子邮件内容主题设置为的内容。template
: 必需。模板的名称。例如,如果我们使用registration
设置此参数,则系统将验证是否可以在views/txt
或views/html
文件夹中找到名为registration.mustache
的 mustache 模板。language
: 可选。如果名称已翻译,请将此参数设置为要翻译的消息的语言代码。例如,如果您将其设置为es
,则将尝试从i18n/es/messages.php
文件加载翻译。有关加载翻译的更多信息,请参阅src\Infrastructure\Mustache\Helpers\TranslatorHelper
。
从队列中发送电子邮件
我们使用 Symfony 的 SwiftMailer 扩展包 来简化从队列发送电子邮件的任务,因为它附带了一些有用的命令。从项目根目录在终端中键入 $ ./bin/console
,将显示以下命令
Available commands: about Displays information about the current project help Displays help for a command list Lists commands assets assets:install Installs bundles web assets under a public directory cache cache:clear Clears the cache cache:pool:clear Clears cache pools cache:pool:delete Deletes an item from a cache pool cache:pool:prune Prunes cache pools cache:warmup Warms up an empty cache config config:dump-reference Dumps the default configuration for an extension debug debug:autowiring Lists classes/interfaces you can use for autowiring debug:config Dumps the current configuration for an extension debug:container Displays current services for an application debug:event-dispatcher Displays configured listeners for an application debug:router Displays current routes for an application debug:swiftmailer Displays current mailers for an application enqueue enqueue:consume [enq:c] A client's worker that processes messages. By default it connects to default queue. It select an appropriate message processor based on a message headers enqueue:produce Sends an event to the topic enqueue:routes [debug:enqueue:routes] A command lists all registered routes. enqueue:setup-broker [enq:sb] Setup broker. Configure the broker, creates queues, topics and so on. enqueue:transport:consume A worker that consumes message from a broker. To use this broker you have to explicitly set a queue to consume from and a message processor service import-translations import-translations:run Import POEditor translations command lint lint:yaml Lints a file and outputs encountered errors router router:match Helps debug routes by simulating a path info match swiftmailer swiftmailer:email:send Send simple email message swiftmailer:spool:send Sends emails from the spool
要从队列中发送电子邮件,只需在服务器上配置一个 cron 作业,定期运行以下命令
$ ./bin/console swiftmailer:spool:send --message-limit=10
现在,我们必须说,虽然 spooling
是 SwiftMailer 的一个很好的功能,但这种技术不适合需要发送大量电子邮件的应用程序。在这种情况下,我们强烈建议使用如 php-enqueue 这样的优秀队列库,并使用最适合您知识和需求的中介。我们推荐 RabbitMQ
,因为它附带了一个管理界面,您可以在其中查看诸如发送了多少封电子邮件、有多少封失败了等等的信息,以及轻松添加/删除所需的工作者以应对可能的巨大负载。它也是 开源的
。
我们提供了一个使用 php-enqueue/enqueue-bundle 的工作示例,该示例包含一组非常实用的命令,因此您不需要重复这些工作,结合其 文件系统传输。以下章节解释了如何使用所提供的队列系统。
发送电子邮件(到文件系统队列)
首先我们需要做的是修改 commandBus
定位映射,并使用 mail.send.queue.handler
而不是 mail.send.spool.handler
$map = [ CreateTokenCommand::class => 'token.create.handler', SendMessageCommand::class => 'mail.send.queue.handler', // must be set like this ];
这就完成了。使用相同的上一个调用,这次消息将发送到运行时文件夹中配置的队列。
从文件系统队列发送电子邮件
如我们之前所说,php-enqueue/enqueue-bundle 附带了一系列非常实用的命令。有关这些命令的完整参考,请参阅其 文档。
用于消费队列中所有消息的命令是 enqueue:consume
$ ./bin/console enqueue:consume mail --no-interaction -vvv --receive-timeout=60000
结合两者的优点
该库还附带了一个自定义队列,因此您可以使用 php-enqueue 与 Swiftmailer。
为了使用它,您需要在代码上进行一些更改
修改 mail.send.spool.handler
我们需要在 ./config/api/dependencies.php
文件中使用已配置的 SendMesssageSpoolHandler
来使用我们的自定义 EnqueueSpool
组件。
$container['mail.send.spool.handler'] = function ($container) { return new SendMessageSpoolHandler( $container['enqueue.mailer'], // <--- here is the modification $container['mustache'], $container['mustache.i18n.helper'], $container['fs'] ); };
修改 services.yaml
然后在 ./config/console/services.yaml
中,我们应该重构文件,使其看起来像这样
swiftmailer.mailer.spool_mailer.spool.custom: class: App\Infrastructure\SwiftMailer\EnqueueSpool arguments: $context: @enqueue.fs.context $queue: 'enqueue.app.mail' # class: App\Infrastructure\SwitftMailer\FileSpool # commented setting! # arguments: # $path: '%kernel.project_dir%/runtime/spool/default' enqueue.mail.processor: class: App\Application\Console\Processor\SendMailProcessor public: true arguments: $mailer: '@swiftmailer.mailer.enqueue_mailer' $mustache: '@mustache.engine.mail' $translatorHelper: '@mustache.i18n.helper' tags: - { name: 'enqueue.processor', command: '__command__', processorName: 'mail' } enqueue.fs.context: class: Enqueue\Fs\FsContext arguments: $storeDir: '%kernel.project_dir%/runtime/queue' $preFetchCount: 1 $chmod: 600 $pollingInterval: 100
这就完成了,使用方法简单地遵循上述 从/到队列发送电子邮件
的指南。
贡献
要贡献,请阅读我们的 贡献指南。
鸣谢
- Tuupola slim api skeleton 感谢您提供样板代码的灵感!
- 2amigos
- 所有贡献者
许可证
BSD许可证(BSD)。有关更多信息,请参阅 许可证文件。
软件之外
www.2amigos.us