郵件中繼服務 (SMTP Relay) 使用者串接手冊

本文件協助系統使用者與軟體工程師快速對接 EZMAIL SMTP 郵件伺服器。透過本服務,您可以使用標準郵件協定安全、穩定地傳遞發票與通知郵件。

1. SMTP 連線設定

請在您的應用系統(例如網頁系統、ERP 或是發信排程程式)中,設定以下 SMTP 伺服器資訊:

伺服器主機參數
參數名稱 設定值 說明
SMTP Server Host smtp-tradevan.ezmail360.com SMTP 發信伺服器位址。
SMTP Port 587 專用發信連接埠。
連線安全性 (SSL/TLS) STARTTLS (TLS 1.2/1.3) 加密傳輸協定。
認證機制 (Auth) 需要帳號與金鑰 (API Key) 身分驗證機制。
🔐 安全加密提示: 正式環境強制啟用 STARTTLS 安全傳輸協議,以確保發信過程中的傳輸安全與資料防洩。

2. 寄件限制規則

為防範非授權寄件人冒用郵件中繼通道,伺服器配置了嚴格的寄件人過濾機制:

寄件人信箱要求
  • 寄信時,SMTP 協定寄件者(Envelope From / Return-Path)以及郵件標頭寄件者(From Header)**限定必須是以下信箱**:
    hct@ezmail360.com
  • 若使用其他寄件人地址(例如 guest@example.comsender@ezmail360.com),伺服器將會直接退信拒收。
⚠️ 錯誤示範: 若使用未允許的寄件人,SMTP 伺服器會於連線階段直接中斷並回傳 554 5.7.1 Sender address rejected: Access denied

3. 配額與黑名單攔截

伺服器內建即時安全防禦系統,會在寄信前同步進行配額與黑名單篩檢:

每日發信配額 (Daily Quota)

每個授權帳號依合約設有每日最高發信封數上限。若您的系統本日累計發信量已超出上限,伺服器會暫時拒絕後續信件,並回傳 554 5.7.1 Exceeded daily sending limit。配額會在每日 00:00 (CST, UTC+8) 自動重設。

📋 配額確認: 您的帳號配額依合約而定。如需調高上限或查詢目前剩餘配額,請聯繫 EZMAIL 技術支援。

退信壓制名單 (Suppression List) Demo 尚未實作

若某個收件人信箱曾有退信 (Bounce)投訴 (Complaint) 或被偵測為無效信箱之紀錄,該信箱會被系統主動列入壓制名單。系統將不再對其寄信,以防止損害寄件人的發信信譽分(Reputation Score)。

若您確認某信箱已恢復正常(例如對方換了新信箱,舊信箱重新啟用),可聯繫技術支援申請將該地址從壓制名單移除,提供以下資訊:

💡 Demo 提示: 壓制名單(Suppression List)過濾機制於目前的測試 (Demo) 環境中尚未實作,僅作規格說明展示。

發信速率限制 (Rate Limiting) Demo 限制

為保護系統頻寬與伺服器穩定性,本服務於測試(Demo)階段設有發信速率與連線次數限制(未來正式上線會再調整):

💡 重試機制提示: 當觸發速率限制時,伺服器回傳的是 450 暫時性錯誤碼。標準的發信用戶端(例如 ERP 或郵件伺服器)會自動將郵件保留在本地佇列(Queue)中,並在 5 ~ 15 分鐘後重新嘗試發送,不會導致郵件遺失。

4. SMTP 錯誤碼與處理建議

當您的發信程式連線發生異常或信件遭拒時,請依照下列標準 SMTP 狀態碼進行處理:

狀態碼 伺服器錯誤訊息 原因與處理建議
554 5.7.1 Sender address rejected: Access denied **寄件人地址不合法。** 請檢查程式中 From 的信箱是否為 `hct@ezmail360.com`。
554 5.7.1 Recipient address is on our suppression list **收件人處於黑名單。** 該收件人曾經退信。請勿再對其發信,建議在您的 ERP/系統中將其標記為無效地址。
554 5.7.1 Exceeded daily sending limit of X emails **今日額度已滿。** 請聯繫系統管理員調高每日額度,或等待明日零點自動重置。
451 4.3.0 Temporary delivery failure **系統暫時性錯誤。** 這通常是由於 API 超時或 Laravel 暫時維護所致。**您的程式應自動排程,在 5 ~ 15 分鐘後重新嘗試發信。**
450 4.7.1 Error: too many messages from [IP] **發信速率超限。** 單一 IP 每分鐘發信超過 20 封。**請於程式中限制發信頻率,或等待下一分鐘自動恢復。**
450 4.7.1 Error: too many connections from [IP] **連線頻率超限。** 單一 IP 每分鐘連線超過 10 次。**建議使用持續連線(Keep-Alive)或合併發信,避免頻繁建立新連線。**

5. 程式串接與測試範例

使用 Swaks 進行終端機快速發信測試

Swaks 是常用的 SMTP 命令列測試工具,可快速驗證連線與認證是否正常。

# 範例一:發送單一收件人(含 SASL 認證)
                        swaks --to recipient@example.com \
                          --from hct@ezmail360.com \
                          --server smtp-tradevan.ezmail360.com \
                          --port 587 \
                          --auth LOGIN \
                          --auth-user YOUR_SMTP_KEY \
                          --auth-password YOUR_SECRET_KEY \
                          --tls \
                          --header "Subject: 測試主旨" \
                          --body "這是信件內容"

                        # 範例二:發送給多個收件人(多個收件人以逗號分隔)
                        swaks --to recipient1@example.com,recipient2@example.com \
                          --from hct@ezmail360.com \
                          --server smtp-tradevan.ezmail360.com \
                          --port 587 \
                          --auth LOGIN \
                          --auth-user YOUR_SMTP_KEY \
                          --auth-password YOUR_SECRET_KEY \
                          --tls \
                          --header "Subject: 測試多收件人" \
                          --body "這是給多人的信件內容"

                        # 範例三:發送單一收件人(含附件與 SASL 認證)
                        swaks --to recipient@example.com \
                          --from hct@ezmail360.com \
                          --server smtp-tradevan.ezmail360.com \
                          --port 587 \
                          --auth LOGIN \
                          --auth-user YOUR_SMTP_KEY \
                          --auth-password YOUR_SECRET_KEY \
                          --tls \
                          --header "Subject: 測試含附件主旨" \
                          --body "這是信件本文內容" \
                          --attach /path/to/invoice.pdf

發信成功後,終端機應出現 250 OK 字樣,代表伺服器已接受信件。

Python 串接範例(含附件)

import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication

msg = MIMEMultipart()
msg['Subject'] = '郵件中繼測試(含發票附件)'
msg['From'] = 'hct@ezmail360.com'
msg['To'] = 'recipient@example.com'

# 附加本文
msg.attach(MIMEText('這是信件的本文內容。', 'plain', 'utf-8'))

# 附加檔案
file_path = '/path/to/invoice.pdf' # 請替換為您系統上的檔案路徑
if os.path.exists(file_path):
    with open(file_path, 'rb') as f:
        attachment = MIMEApplication(f.read(), _subtype='pdf')
        attachment.add_header('Content-Disposition', 'attachment', filename='invoice.pdf')
        msg.attach(attachment)

try:
    # 建立連線,設定 5 秒超時
    with smtplib.SMTP('smtp-tradevan.ezmail360.com', 587, timeout=5) as server:
                    server.starttls() # 正式環境強制 TLS 加密
            server.login('YOUR_SMTP_KEY', 'YOUR_SECRET_KEY') # 正式環境需要登入
                server.sendmail(msg['From'], [msg['To']], msg.as_string())
        print("發信成功!")
except smtplib.SMTPResponseException as e:
    print(f"發信失敗,SMTP 錯誤碼: {e.smtp_code},訊息: {e.smtp_error.decode('utf-8')}")
except Exception as e:
    print(f"連線失敗: {e}")

Node.js (Nodemailer) 串接範例(含附件)

const nodemailer = require('nodemailer');

// 設定 SMTP 連線資訊
const transporter = nodemailer.createTransport({
    host: 'smtp-tradevan.ezmail360.com',
    port: 587,
    secure: false, // 587 連接埠請設為 false,使用 STARTTLS
            auth: {
            user: 'YOUR_SMTP_KEY',
            pass: 'YOUR_SECRET_KEY'
        }
    });

const mailOptions = {
    from: 'hct@ezmail360.com',
    to: 'recipient@example.com',
    subject: 'Node.js 串接測試(含發票附件)',
    text: '這是來自 Node.js 程式發送的發票通知信。',
    attachments: [
        {
            filename: 'invoice.pdf',
            path: '/path/to/invoice.pdf' // 請替換為您系統上的檔案路徑
        }
    ]
};

transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
        console.error('發信出錯:', error.message);
        if (error.responseCode === 554) {
            console.log('請檢查寄件人是否合法、或收件人是否被黑名單阻擋。');
        }
        return;
    }
    console.log('信件發送成功: ' + info.response);
});

Laravel (PHP) 串接範例

若您的系統使用 Laravel 框架,只需在 .env 設定以下環境變數,即可透過 Laravel 內建 Mail 功能直接串接:

Laravel .env 設定

MAIL_MAILER=smtp
MAIL_HOST=smtp-tradevan.ezmail360.com
MAIL_PORT=587
    MAIL_USERNAME=YOUR_SMTP_KEY
    MAIL_PASSWORD=YOUR_SECRET_KEY
    MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hct@ezmail360.com
MAIL_FROM_NAME="Tradevan 電子發票"

Laravel Mail 範例

在您的 Mailable 類別(例如 App\Mail\InvoicePaid)中,您可以直接使用 attachments() 方法來附加檔案:

use Illuminate\Mail\Mailables\Attachment;

/**
 * Get the attachments for the message.
 *
 * @return array<int, \Illuminate\Mail\Mailables\Attachment>
 */
public function attachments(): array
{
    return [
        Attachment::fromPath('/path/to/invoice.pdf')
            ->as('invoice.pdf')
            ->withMime('application/pdf'),
    ];
}

PHP (原生 PHPMailer) 串接範例(含附件)

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;

$mail = new PHPMailer(true);

$mail->isSMTP();
$mail->Host       = 'smtp-tradevan.ezmail360.com';
$mail->Port       = 587;
    $mail->SMTPAuth   = true;
    $mail->Username   = 'YOUR_SMTP_KEY';
    $mail->Password   = 'YOUR_SECRET_KEY';
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;

$mail->setFrom('hct@ezmail360.com', 'EZMAIL 電子發票');
$mail->addAddress('recipient@example.com');

// 夾寄檔案
$mail->addAttachment('/path/to/invoice.pdf', 'invoice.pdf');

$mail->CharSet = 'UTF-8';
$mail->Subject = '電子發票通知(含附件)';
$mail->Body    = '您好,請查收附件中的電子發票。';

$mail->send();

6. API Key 與金鑰設定

在正式環境 (Production) 中,為確保郵件傳輸的安全性與可追溯性,發信系統必須通過 SASL 認證。您需要配置 API Key 與 Secret Key 來進行驗證。

如何取得您的憑證

API Key 由 EZMAIL 技術團隊在開通服務時核發。若您尚未收到,或需要重新申請,請透過以下方式聯繫:

  • 📧 Email:service@ezmail360.com
  • 請於信件中說明您的系統名稱與使用情境,我們將在 1 個工作天內完成開通。
憑證說明

請將您的認證金鑰寫入系統環境變數或設定檔,切勿將金鑰直接硬編碼在程式碼中,以免洩漏。

  • Username (帳號): 系統核發的 API_KEY(例如:client_123)。
  • Password (密碼): 對應的 SECRET_KEY(請妥善保管,不可與他人共享)。
通用 SMTP 設定範例 (環境變數)

適用於大部分支援 SMTP 傳輸的系統與程式庫,請依據您的開發框架或系統設定調整:

# 通用環境變數設定範例
SMTP_HOST=smtp-tradevan.ezmail360.com
SMTP_PORT=587
SMTP_USERNAME=YOUR_SMTP_KEY
SMTP_PASSWORD=YOUR_SECRET_KEY
SMTP_ENCRYPTION=tls
SMTP_FROM_ADDRESS=hct@ezmail360.com