iwasherefirst2 / laravel-multimail
一个用于通过 Laravel 从多个邮箱账户轻松发送邮件的包
Requires
- laravel/framework: ^5.0|^6.0|^7.0|^8.0
Requires (Dev)
- guzzlehttp/guzzle: ^6.4
- orchestra/testbench: ^4.0
README
此包可以帮助您从 Laravel 应用程序中发送来自多个电子邮件账户的邮件。
该包支持发送排队、本地化和批量邮件。
此包适用于 SMTP
和 日志
驱动程序。
目录
要求
Laravel 5, 6, 7 或 8。Larave 9 和 10 不受支持。
安装
使用 composer 将包安装到您的 Laravel 应用程序中
composer require iwasherefirst2/laravel-multimail
发布配置文件
php artisan vendor:publish --provider="IWasHereFirst2\LaravelMultiMail\MultiMailServiceProvider" --tag=config
在 config/multimail.php
中配置您的电子邮件客户端
'emails' => [
'office@example.net' =>
[
'pass' => env('first_mail_password'),
'from_name' => "Max Musterman",
],
'contact@example.net' =>
[
'pass' => env('second_mail_password')
],
],
请确保将凭证放在 .env
文件中,这样它们就不会在您的存储库中跟踪。
对于每封邮件,您可以指定多个列
用法
可以使用 \MultiMail
而不是 \Mail
来发送邮件。方法 to
、cc
、bcc
、locale
与 mail facade 提供的完全相同(请注意,locale
仅从 Laravel 5.6 开始提供)。
MultiMail
的 from
方法需要一个在 config/multimail.php
中提供的电子邮件字符串。您可以可选地传递第二个参数作为发件人名称,而不是使用配置中提供的默认值。当使用 send
或 queue
时,邮件将从 cofing/multimail.php
中指定的邮件账户发送。
基本示例
此示例假设 office@example.net
和 contact@example.net
已在 config/multimail.php
中指定。
// Send mail from office@example.net
\MultiMail::to($user)->from('office@example.com')->send(new \App\Mail\Invitation($user));
// Send from malaccount email@gmail.com
\MultiMail::to($user)->from('email@example.net')->locale('en')->send(new \App\Mail\Invitation($user));
排队邮件
排队邮件与正常 Mail facade 的工作方式完全相同,即它们要么通过 queue
方法显式发送,要么可邮寄类实现了 ShouldQueue
协议。
// Queue Mail
\MultiMail::from('contact@foo.org')->queue(new \App\Mail\Invitation($user));
当然,需要安装一个 队列驱动程序。
在可邮寄对象中指定
您可以在您的可邮寄类中设置 to
、cc
、bcc
、locale
和 from
。在这种情况下,您可以简化上面的基本示例为
// Send mail from office@example.net
\MultiMail::send(new \App\Mail\Invitation($user));
可邮寄
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($user)
{
$this->to = $user;
$this->fromMailer = 'office@example.com'
$this->locale('en');
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->markdown('emails.invitation')
->subject('Invitation mail');
}
批量消息
对于批量消息,您首先可能需要邮件对象。您可以在发送了一定数量的邮件($frequency)之后定义一个暂停时间($timeout)。
$mailer = \MultiMail::getMailer('office@example.com' , $timeout, $frequency);
然后您可以遍历您的列表。
foreach($users as $user){
$mailer->send(new \App\Mail\Invitation($user));
};
特殊设置
多个邮件提供商
如果您希望从不同的提供商发送邮件,则可以在 provider
数组中创建另一个提供商,并在 emails
数组内部引用它
'emails' => [
'office@example.net' =>
[
'pass' => env('first_mail_password'),
'username' => env('first_mail_username'),
'from_name' => "Max Musterman",
// <------ no provider given because 'default' provider is used
],
'contact@other_domain.net' =>
[
'pass' => env('second_mail_password'),
'username' => env('second_mail_username'),
'from_name' => "Alice Armania",
'provider' => 'new_provider', // <------ specify new provider here
],
],
'provider' => [
'default' =>
[
'host' => env('MAIL_HOST'),
'port' => env('MAIL_PORT'),
'encryption' => env('MAIL_ENCRYPTION'),
'driver' => env('MAIL_DRIVER'),
],
'new_provider' =>
[
'host' => env('MAIL_HOST_PROVIDER_B'),
'port' => env('MAIL_PORT_PROVIDER_B'),
'encryption' => env('MAIL_ENCRYPTION_PROVIDER_B'),
'driver' => env('MAIL_DRIVER_B'),
// you may also add options like `stream`, `source_ip` and `local_domain`
]'
],
默认邮件账户
您可以从 config/multimail.php
中的 email
数组提供 default
凭据
'emails' => [
'office@example.net' =>
[
'pass' => env('first_mail_password'),
'username' => env('first_mail_username'),
'from_name' => "Max Musterman",
],
'contact@example.net' =>
[
'pass' => env('second_mail_password'),
'username' => env('second_mail_username'),
'from_name' => "Alice Armania",
],
'default' =>
[
'pass' => env('MAIL_PASSWORD'),
'username' => env('MAIL_USERNAME'),
]
],
当 first_mail_password
和 first_mail_username
为空时,office@example.net
将使用 default
指定的凭据。这对于本地开发非常有用,当时您希望测试时从单个邮件账户发送所有邮件。这样,您只需要在本地指定 MAIL_PASSWORD
和 MAIL_USERNAME
。
测试
不要在本地 env
中放置凭证
不要在您的本地 .env
中指定任何电子邮件账户。否则,您可能会将测试邮件发送给实际用户。
使用一个伪造的邮件账户或日志
使用 log
驱动程序或设置一个虚假的邮件SMTP账户,如 mailtrap 或类似的服务。
不需要为您的所有电子邮件账户指定相同的凭证。相反,只需提供一个默认的邮件账户(参见上面的 默认邮件账户
)。
在测试中使用日志邮件驱动程序
为了避免延迟,我建议在运行 phpunit
时始终使用 log
邮件驱动程序。您可以在 phpunit.xml
文件中设置邮件驱动程序,如下所示:<env name="MAIL_DRIVER" value="log"/>
。
使用模拟
如果您想在测试期间使用模拟功能 Mail fake,请在您的配置文件 config/multimail.php
中启用 use_default_mail_facade_in_tests
。请注意,assertQueued
从不会为真,因为 queued
邮件实际上是通过一个作业发送的。
从数据库获取邮件
如果您想从数据库加载您的邮件账户配置,请发布包迁移
php artisan vendor:publish --provider="IWasHereFirst2\LaravelMultiMail\MultiMailServiceProvider" --tag=migrations
现在您的迁移文件夹中有两个表,email_accounts 和 email_providers
而不是将电子邮件添加到配置中,它们应该添加到 email_accounts 表中。
请确保更新您的配置 config/multimail.php
<?php
return [
'mail_settings_class' => \IWasHereFirst2\LaravelMultiMail\DatabaseConfigMailSettings::class,
//...
];
现在电子邮件将是从数据库而不是配置文件中读取。如果 email_accounts 中没有提供提供者(列 provider 可为空),则将考虑 config/multimail.php
中的默认提供者。
如果您想进行自定义,请将类 \IWasHereFirst2\LaravelMultiMail\DatabaseConfigMailSettings
复制到您的应用程序的某个位置,调整命名空间,并在您的配置文件中更新引用 mail_settings_class
。
故障排除
Laravel 7 不工作
请更新到版本 1.2.2 以支持 Laravel 7
针对包开发者
如果您计划为此包做出贡献,请确保单元测试以及集成测试都成功。为了测试集成测试,请创建一个免费的 mailtrap 账户,将 tests/.env.example
复制到 tests/.env
,并在 tests/.env
中添加您的 mailtrap API 凭证。集成测试现在将向您的 mailtrap 账户发送测试电子邮件,并通过 API 验证邮件是否成功发送。
该包附带一个 Dockerfile,以便您轻松运行测试。只需按照以下步骤操作
docker-compose up --build
docker-compose exec app bash
composer install
./vendor/bin/phpunit