ttiiwasherefirst2/laravel-multimail

一个用于通过 Laravel 从多个邮箱账号轻松发送邮件的包

v1.0.2 2023-11-16 02:36 UTC

This package is not auto-updated.

Last update: 2024-10-03 07:20:14 UTC


README

Mail image

CircleCI codecov

此包可以帮助您从 Laravel 应用程序中通过多个邮箱账号发送邮件。

该包支持发送排队、本地化和批量邮件。

此包适用于 SMTPlog 驱动。

目录

要求

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 文件中,以免在您的存储库中跟踪。

对于每封邮件,您可以指定多个列

属性功能必需
pass邮箱账户密码
username邮箱账户的用户名,如果与邮箱地址不同则必需
from_name应出现在邮箱前的名称
provider邮箱账户的提供商,如果邮件主机/加密/端口不是默认值,则需要(更多信息请见此处

用法

可以使用 \MultiMail 代替 \Mail 发送邮件。方法 toccbcclocalemail facade 提供的完全相同(注意,locale 仅从 Laravel 5.6 开始提供)。

MultiMailfrom 方法需要一个在 config/multimail.php 中提供的邮箱字符串。您可以传递一个可选的第二个参数作为发件人名称,而不是使用配置中给出的默认值。当使用 sendqueue 时,邮件将从 cofing/multimail.php 中指定的邮件账户发送。

基本示例

此示例假设已在 config/multimail.php 中指定了 office@example.netcontact@example.net

// 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));

当然,安装 队列驱动 是必要的。

在可邮寄对象中指定

您可以在可邮寄类中设置 toccbcclocalefrom。在这种情况下,您可以简化上面的基本示例为

// 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`
    ]'
],

默认邮件账号

您可以在 email 数组中提供 default 凭据,该数组来自 config/multimail.php

'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_passwordfirst_mail_username为空时,office@example.net将使用default指定的凭据。这对于您的本地开发非常有用,当您在测试时想从单个邮箱发送所有邮件。这样,您只需在本地指定MAIL_PASSWORDMAIL_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永远不会为真,因为已排队的邮件实际上是通过作业发送的。

从数据库获取邮件

如果您想从数据库加载您的邮箱账户配置,请发布包迁移

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