如何使用 Twilio SendGrid 和 Mezzio 使用 PHP 發送電子郵件

已發表: 2021-03-24

電子郵件與以往一樣重要,是一種溝通工具。 為了幫助您更好地利用電子郵件,我將向您展示如何使用 PHP 的 Mezzio 框架和 Twilio SendGrid 的 API 發送電子郵件。

具體來說,您將學習如何發送帶有純文本和 HTML 正文的電子郵件,其中包括 PDF 附件。 您還將學習如何使用 Twilio SendGrid 的事務模板功能來簡化開發團隊以及組織內的任何其他團隊創建電子郵件正文的過程。

聽起來不錯? 讓我們開始。

快速應用概述

作為使本教程更有意義的一種方式,假設我們將編寫的代碼是使用 Mezzio 構建的一個虛構的在線電子商務商店的一部分,名為The Little PHP Shop — 特別是在客戶購買之後的部分。 在用戶流程中,客戶會收到一封電子郵件,感謝他們的購買,並附上一份 PDF 發票以供記錄。

我們將創建一個 Handler 類來發送購買後電子郵件,該電子郵件將從客戶完成的訂單中接收購買詳細信息。 使用該購買信息,處理程序類將使用 SendGrid PHP API 中的幾個類來構建和發送購買確認電子郵件。

其中,最重要的是“SendGrid\Mail\Mail”和“\SendGrid”。 “SendGrid\Mail\Mail”是存儲我們將通過 Twilio SendGrid 發送的電子郵件消息的所有屬性的對象。 “SendGrid”對象構成傳輸層,便於通過 Twilio SendGrid 發送電子郵件。

先決條件

要完成本教程,您需要在本地開發環境中完成以下 4 件事:

  1. Twilio SendGrid 帳戶
  2. 安裝並啟用了cURL mbstringO pen SSL擴展的 PHP 7.4
  3. Composer全局安裝
  4. 捲曲

搭建 Mezzio 應用程序

我們首先需要創建基礎應用程序。 為此,我們將一如既往地使用Mezzio Skeleton為我們做這件事。 一旦我們搭建了基礎應用程序,我們將切換到新創建的項目目錄。 然後按照第一個提示在終端中運行以下命令:

安裝所需的依賴項

隨著項目的腳手架,我們需要添加 3 個額外的依賴項來完成項目。 這些是:

  • Twilio SendGrid 的PHP API 庫,用於與 Twilio SendGrid API 交互
  • 用於發送 HTTP 請求的PHP HTTP 客戶端
  • PHP Dotenv用於存儲和檢索環境變量

要安裝它們,請在終端中運行以下命令:

初始化 PHP Dotenv

安裝依賴項後,我們加載 PHP Dotenv,以便它讀取“.env”中設置的變量並將它們作為環境變量提供給 PHP。 為此,在“public/index.php”中插入以下代碼,就在“require vendor/autoload.php”之後。

添加您的 Twilio SendGrid 帳戶詳細信息

現在您需要為應用程序提供您的 SendGrid API 密鑰。 為此,在登錄Twilio SendGrid,導航到“設置 -> API 密鑰”。 ” 一旦出現:

  1. 單擊“創建 API 密鑰”以創建 API 密鑰
  2. 為新的 API 密鑰命名,接受默認的 API 密鑰權限“完全訪問然後單擊“創建和查看

創建 API 密鑰後,單擊並複制密鑰,然後單擊“完成”

之後,再向文件添加 2 個鍵:“SENDGRID_DEFAULT_SENDER_ADDRESS”和“SENDGRID_DEFAULT_SENDER_NAME”。 正如名稱所示,這些是我們將用於從我們的應用程序發送的任何電子郵件的電子郵件地址和名稱,除非被覆蓋。

注意:為此,在Sender Authentication中,確保它在“Single Sender Verification”表中顯示“Verified”。

設置應用程序郵件配置詳細信息

除了 Twilio SendGrid API 密鑰之外,我們還將存儲一些其他全局郵件配置設置。 具體來說,我們將設置一個發件人並回復電子郵件地址和名稱,我們將在每封電子郵件中使用它們。 這樣,我們不必每次都設置它們。

我們還將創建 2 個電子郵件正文模板:一個用於純文本電子郵件,一個用於 HTML 電子郵件。 為此,在“config/autoload”中創建一個名為“mail.global.php”的新文件,並在其中添加以下代碼。

創建一個類來實例化一個郵件對象

設置關鍵應用程序配置詳細信息後,現在讓我們創建一個類,該類將使用默認屬性集實例化一個基本郵件對象。 為此,在一個新目錄“src/App/src/Mailer”中,創建一個名為“SendGridMailMessageFactory.php”的新文件,並在其中添加以下代碼。

當我們調用該類時,它可以訪問應用程序的依賴注入 (DI) 容器,從中檢索我們存儲在“config/autoload/mail.global.php”中的配置詳細信息。

之後,它將實例化一個新的“SendGrid\Mail\Mail”對象,並通過將各自的配置詳細信息分別傳遞給“Mail”、“setFrom”和“setReplyTo”方法的調用來設置發件人和回复詳細信息。 之後,它將返回實例化的“Mail”對象。

但是,要使用它,您必須在 DI 容器中註冊它。 為此,在“src/App/src/ConfigProvider”中,將以下條目添加到“getDependencies”方法返回的數組中的“factories”元素中。

創建一個處理程序來發送電子郵件

接下來我們需要創建一個 Handler 類來編寫和發送電子郵件。 為此,我們將使用Mezzio 的 CLI 工具(可通過 Composer 獲得),方法是運行以下命令。

運行上面的命令為我們做了四件事:

  1. 創建一個新的處理程序類,“src/App/Handler/EmailSenderHandler.php
  2. 創建一個工廠類來實例化 Handler 類,“src/App/Handler/EmailSenderHandlerFactory.php”
  3. 創建一個我們不需要的模板文件(“src/App/templates/app/email-sender.html.<ext>”) 文件名“<ext>”由您在“create-project”階段選擇的模板引擎決定。
  4. 通過向“config/autoload/mezzio-tooling-factories.global.php”添加條目,將新的 Handler 類註冊為 DI 容器中的服務

重構處理程序以發送電子郵件

創建“EmailSenderHandler.php”後,我們現在需要對其進行重構,以便它可以發送電子郵件。 為此,我們將首先重構“EmailSenderHandler”的構造函數,將“TemplateRendererInterface”參數替換為 3 個新參數。 這些將初始化 3 個新的類成員變量:

  • “\SendGrid\Mail\Mail”對象
  • 一個“\SendGrid”對象
  • 包含所需配置詳細信息的數組

您可以在下面的示例中看到修改後的構造函數,以及相關的類成員變量。 用此代碼替換現有的類成員變量和構造函數。

注意:接下來,我們需要重構“handle”方法。 將“EmailSenderHandler”“handle”方法的現有內容替換為下面的代碼,然後讓我們逐步了解它的作用。

它首先使用“$request->getParsedBody()”來檢索請求正文中提供的任何參數,這將返回一個關聯數組,初始化“$details”。 使用可用的參數,它調用“SendGrid\Mail\Mail”對象的“addTo”方法來設置電子郵件的收件人,在前兩個參數中傳入收件人的電子郵件地址和姓名,在第三個參數中傳遞一個替換數組

替換允許您為每個收件人自定義電子郵件消息。 在純文本電子郵件中,任何直接被連字符包圍的字符串,例如“-first_name-”都是替換。 在 HTML 電子郵件中,它使用Handlebars 語法,用雙括號括住字符串,例如“{{ first_name }}”。

接下來,我們設置消息的主題並添加純文本和 HTML 消息正文。 這樣,我們的電子郵件就可以發送了。 因此,我們使用“SendGrid”對象“$this->mailer”來發送它,初始化一個新變量“$response”,其中包含嘗試發送消息的響應。 最後,我們返回一個 JsonResponse 對象,其中包含響應的狀態代碼和正文。

注意:重構 EmailSenderHandlerFactory 的 __invoke 方法

現在我們已經完成了“EmailSenderHandler”的重構,我們需要重構“EmailSenderHandlerFactory”。 這將正確地實例化“EmailSenderHandler”。 為此,請將其“__invoke`”方法的現有定義替換為以下代碼。

這會從 DI 容器中檢索“\SendGrid\Mail\Mail”對象,使用發件人預初始化並回復電子郵件詳細信息,並初始化一個名為“$message”的新對象。 然後它實例化一個名為“$mailer”的新“SendGrid”對象,用於發送郵件消息。 最後,它從應用程序的配置中檢索郵件配置。 然後,它使用這些來初始化並返回“EmailSenderHandler”對象。

更新路由表

通過所有這些更改,在我們可以測試代碼並發送電子郵件之前,還需要進行最後一項更改。 我們必須更新路由表,以便默認路由使用我們新的 Handler 類作為路由的處理程序,而不是“HomePageHandler”。 為此,請將“config/routes.php”中的默認路由定義替換為以下示例。

發送第一封電子郵件

現在是發送第一封電子郵件的時候了。 為此,首先,通過在終端中運行以下命令來啟動應用程序。

然後,使用 cURL 向“ http://localhost:8080發出 GET 請求,如下例所示,將尖括號中的值替換為電子郵件的相關詳細信息。

您應該會看到“{“status”:202,“message”:””}” 輸出到終端,並且您應該收到一封如下圖所示的電子郵件。

注意:請使用事務性電子郵件模板而不是模板字符串

雖然我們已經能夠發送包含純文本和 HTML 正文的電子郵件,但是我們如何做到這一點並不理想。 對於我們發送的每封電子郵件——我們的應用程序最終可能會發送很多——我們需要為它們添加純文本和 HTML 正文。

但是將電子郵件正文定義存儲在代碼中會將大部分精力放在開發團隊身上。 但是,至少根據我的經驗,其他團隊(通常是營銷團隊)通常會創建和維護電子郵件模板。

因此,出於這個原因,並且因為它會加速開發並在多個團隊之間分擔負載,我們將重構應用程序以使用事務性電子郵件模板 您可以通過 Twilio SendGrid UI 由可能很少或沒有技術經驗的團隊成員創建和維護這些,而不是在代碼中。

如果您沒有聽說過它們, Twilio SendGrid 詞彙表將它們定義如下:

交易電子郵件模板是預編碼的電子郵件佈局,營銷人員、設計師和開發人員可以使用它來快速輕鬆地創建交易電子郵件活動。 Twilio SendGrid 的事務性電子郵件模板允許非技術人員和技術人員對收件人收到的電子郵件進行實時更改。

對於本文,我們只需要一個相當基本的。 為此,請遵循Twilio SendGrid 文檔中的詳細信息,並創建一個僅在單個文本模塊中作為其內容的內容。 然後,對於正文,使用下面的文本。

請注意,電子郵件中有 6 個替換項:

  • “first_name”:客戶的名字
  • “last_name”:客戶的姓氏
  • “sender_name”:電子商務商店的名稱(The Little PHP Shop)
  • “sender_state”:電子商務商店的狀態
  • “sender_country”:電商所在國家
  • “support_email”:客戶可以用來獲得售後支持的支持電子郵件

鑑於此,我們需要將該信息提供給我們的應用程序。 我們已經有了客戶的名字和姓氏。 剩下的 4 個替換將是全局的,所以就像我們之前所做的那樣,我們將在“templates”元素之後將下面的配置添加到“ config/autoload/mail.global.php ”中。

創建新配置文件後,在“EmailSenderHandler”“handle”方法中,用以下代碼替換對“$this->mail->addContent()”的 2 次調用。

2 個方法調用添加發件人詳細信息並支持電子郵件地址作為全局替換。 這些替換在任何其他替換之前適用於電子郵件正文,但如果存在具有相同密鑰的電子郵件收件人的替換,則這些替換將被覆蓋。

接下來,您需要檢索事務性電子郵件模板的 ID。 您可以通過單擊模板列表中的模板名稱來找到它,如下面的屏幕截圖所示。

複製它並將其存儲在“config/autoload/mail.global.php”中的新元素中,鍵為“template_id”,然後刪除“plain”和“HTML”。 完成後,返回數組的“mail/templates”元素將如下面的代碼所示,其中“<the template's id>”替換了模板的 ID。

更新配置後,我們現在需要在“EmailSenderHandler”“handle”方法中添加對“Mail”“setTemplateId”方法的調用,將我們剛剛添加到“config/autoload/mail.global”的模板 ID 傳入。 php。” 您可以在下面的代碼中看到一個示例。

讓我們測試一下更改

和以前一樣,使用 cURL 向 http://localhost:8080 ”發出 GET 請求,以測試更改是否按預期工作。 您應該會看到“{“status”:202,“message”:””}” 輸出到終端,如前面的示例所示。 在您的電子郵件收件箱中,您應該會看到一封可愛的電子郵件,其中替換了替換內容,如下面的屏幕截圖所示。

附上 PDF 發票

現在我們正在使用動態模板,讓我們附上我們在文章頂部討論過的 PDF 發票。 為了節省您自己查找或創建發票的時間和精力,我創建了一個示例 PDF 發票,您可以在本文中使用它。 將其保存在應用程序的“數據”目錄中。

注意:要附加發票,我們需要使用“Mail”“addAttachment”方法,您可以在下一個代碼示例中看到該方法。 該方法需要 5 個參數,但我們只提供前 4 個參數。它們是:

  1. 附件”像或Base64 編碼字符串 如果此參數的值不是 base64 編碼的,則該方法將為我們執行此操作。
  2. 附件的 MIME 類型(現在稱為媒體類型)。
  3. 附件的文件名。 這是文件默認保存的名稱,除非用戶更改它。
  4. 附件的內容處置 如果您不熟悉 content-disposition,則inline content-disposition 意味著附件應在消息顯示時自動顯示,而attachment content-disposition 意味著附件不會自動顯示並且需要用戶採取某種形式的操作打開它。

在下面的代碼示例中,PHP 的file_get_contents方法將文件的內容讀入名為“$invoice”的新變量中。 然後,PDF 通過調用“addAttachment”方法附加到消息中。

在這裡,我們:

  • 傳入發票的內容,這將是 Base64 編碼的
  • 附加 PDF 文件時,將 MIME 類型設置為“application/pdf”
  • 將發票的文件名設置為客戶可能合理預期的虛構名稱
  • 將內容處置設置為“附件”

現在我們已經完成了這些更改,讓我們測試它們是否有效。 運行與前 2 次相同的 cURL 請求。 然後,在您的電子郵件收件箱中,您應該會看到一封精美的電子郵件,其中包含在查看電子郵件時可見的示例 PDF 發票。

這就是使用 Twilio SendGrid 和 Mezzio 使用 PHP 發送電子郵件的方法

雖然我們只觸及了使用 Twilio SendGrid 和 Mezzio 發送電子郵件時可能實現的功能的表面,但您現在可以發送帶有純文本和 HTML 正文以及附件的電子郵件。 您還學習瞭如何使用可以全局設置且基於每個收件人的事務模板和替換。

我強烈建議您查看PHP 庫的文檔以了解其他可用的內容,例如安排電子郵件發送、附加來自 Amazon S3 的文件、添加標題以及添加部分和類別。

Matthew Setter 是 Twilio Voices 團隊的一名 PHP 編輯器,當然也是一名 PHP 開發人員。 他也是Mezzio Essentials的作者 當他不編寫 PHP 代碼時,他正在 Twilio 編輯優秀的 PHP 文章。 可以通過以下方式聯繫到他:

  • 電子郵件: [email protected]
  • 網址: http: //matthewsetter.com
  • 推特: @settermjd
  • GitHub: https://github.com/settermjd