2016年1月11日 星期一

如何透過PHP送信

遇到一個需求,是需要透過php送驗證碼到使用者email

使用免費郵箱的SMTP

phpmail
原始出處: http://www.daixiaorui.com/read/16.html
https://github.com/kalecgos0616/tools/tree/master/phpmail
原理:用php的fputs()設定SMTP傳送email
phpmailer
https://github.com/PHPMailer/PHPMailer
composer安裝
$ composer require phpmailer/phpmailer
然後更改 ~/composer/vendor/phpmailer/phpmailer/examples/smtp.php 把smtp的設定寫進去,
優點:可以傳送附加檔案

測試結果
使用sina的SMTP對qq 郵箱連送20次,結果phpmail的網頁中段顯示空白頁,qq郵箱收到0,1,2,3,4,6,8的信,其餘連垃圾郵件都沒收到。跑完迴圈後再去發一次email到qq,就收不到了。

So You'd Like to Send Some Email (Through Code)
所以你想發送一些email(透過code)
I have what I would charitably describe as a hate-hate relationship with email. I desperately try to avoid sending email, not just for myself, but also in the code I write.
作者非常討厭用code發送email,並儘量避免。
Despite my misgivings, email is the cockroach of communication mediums: you just can't kill it. Email is the one method of online contact that almost everyone -- at least for that subset of "everyone" which includes people who can bear to touch a computer at all -- is guaranteed to have, and use. Yes, you can make a fairly compelling case that email is for old stupid people, but let's table that discussion for now.
email是溝通媒介的蟑螂:你殺不死他。email是幾乎每個人都在網上聯繫的一種方法。
So, reluctantly, we come to the issue of sending email through code. It's easy! Let's send some email through oh, I don't know, let's say ... Ruby, courtesy of some sample code I found while browsing the Ruby tag on Stack Overflow.
透過code來發送email是很簡單的。上stackoverflow查一查範例就好
Just because you send an email doesn't mean it will arrive. Not by a long shot. Bear in mind this is email we're talking about. It was never designed to survive a bitter onslaught of criminals and spam, not to mention the explosive, exponential growth it has seen over the last twenty years. Email is a well that has been truly and thoroughly poisoned -- the digital equivalent of a superfund cleanup site. The ecosystem around email is a dank miasma of half-implemented, incompletely supported anti-spam hacks and workarounds.
因為你發送一封email,不意味他會送達。根本不可能(不可能百分百送達)。請記住,我們在說的這是email。這是從不被設計為犯罪和垃圾郵件的痛苦猛攻。更不用說過去20年來的爆炸、指數增長。email已經是真正且徹底被毒害的- 超級清理網站的數量。圍繞電子郵件生態系統是半現實的,不完全支持反垃圾郵件黑客和解決方法的瘴氣。
Which means the odds of that random email your code just sent getting to its specific destination is .. spotty. At best.
這意味你用code送的email發送到目的地的機率是... 參差不齊的。
If you want email your code sends to actually arrive in someone's AOL mailbox, to the dulcet tones of "You've Got Mail!", there are a few things you must do first. And most of them are only peripherally related to writing code.
你想透過code確實的把email送達別人的郵箱。有幾件事你必須先做到的。而且大部分與code無關。
1. Make sure the computer sending the email has a Reverse PTR record
確保發信的電腦有反向PTR記錄
2. Configure DomainKeys Identified Mail in your DNS and code
設定DomainKeys Identified Mail(DKIM)在你的DNS和code
3. Set up a SPF / SenderID record in your DNS
設定 SPF / SenderID(VERIFY_KEY?)記錄在你的DNS
That sucked. How do I know all this junk is working?
你要怎麼知道這一切努力是有用的?
(略)

使用服務商送信

http://submail.cn/  (中國)
優點:
1. 連發都收得到
2. 163、sina、gmail、yahoo都收得到
缺點:
1. QQ郵箱收不到 => 客服回復:QQ邮箱域名生效会稍慢,一般新域名开始发信后3-7天后才会逐渐恢复正常,预热期内会偶尔出现丢新现象
2. 到信速度慢
配置:
登陸後台後
"郵件" => "配置发送域名" ( http://submail.cn/chs/account/settings#/mail/domainConfigs )
把你的domain加進去,然後去domain DNS代管的"解析设置"(我的domain是阿里雲代管)配置"域名验证"(VERIFY_KEY)、SPF、DKIM
然後她會測試你的domain的VERIFY_KEY、SPF、DKIM是否驗證過了
ps. 阿里雲代管每次更改DNS解析記錄都會發信通知你
"開發者"=> "邮件应用"( http://submail.cn/chs/developer/apps#/mail )
新建一個郵件應用,然後他會跟你說"應用ID"和"密鑰"

實測:
發送API
http://submail.cn/chs/documents/developer/yR0Ov
$ curl --data "appid=XXX&to=tom <tom@qq.com>&subject=testing_Subject&text=testing_text_body&from=no-reply@your.domain&signature=secret_key" -k "https://api.submail.cn/mail/send.json"
{"status":"success","return":[{"send_id":"XXXX","to":"tom@qq.com"}]}

域名剛開始發信速度會比較慢,參照
http://submail.cn/chs/blog/view/14  SUBMAIL AUTO WARM UP(Beta) 域名和 IP 自动预热机制
節錄:
通常,當一個 ESP(郵箱服務提供商)收到新的功能變數名稱或者 IP 進行郵件發信時,他們將開始對該 IP 或者功能變數名稱進行監控信譽度的計算,並且根據功能變數名稱和 IP 的信譽度來決定給與該對象流量的大小。初始階段,ESP 會限制入信的流量來達到風險管控的目的(例如當日最大入信額度 10000 封),超過這個流量的郵件可能會直接拒收,甚至有被列入黑名單的風險。
因此,一個新的功能變數名稱或 IP 在啟用或開始進行大量外發郵件之前需要對該功能變數名稱或 IP 進行前期預熱

什麼是前期預熱?
前期預熱指的是一個新 IP 或功能變數名稱在大量發送郵件之前,先通過逐漸遞增發信量來讓  ISP 標識並認可新 IP 或功能變數名稱

SUBMAIL AUTO WARM UP 並不能100%的保證你不被 ESP 拒絕,要更好的預熱你的功能變數名稱或 IP 你還需要儘量做到以下幾點:

1: 優秀的郵件內容和規範編碼
ESP 不僅對你的入信量進行評估,你的郵件內容也是決定你的郵件到達率的重要因素之一。優秀的郵件內容和規範的 HTML 編碼,將會加速 ESP 對你發件域和 IP 信任。請在發送你的郵件之前,檢查你的郵件代碼或將你的郵件 發送至http://www.mail-tester.com 查看你的郵件得分。

2: 配置獨立的觸發類(或事務類)郵件域和推廣類(EDM、訂閱類)郵件域
SUBMAIL 觸發郵件服務和推廣類郵件服務將都受到 SAWU 機制干預。所以,當你同時使用2個服務時,請將觸發郵件域推廣郵件域分開,即需要配置2個發送功能變數名稱,如你的功能變數名稱是 yourdomain.com,請為觸發郵件域配置一個二級域,如 service.yourdomain.com,再為推廣類郵件配置 newsletter.yourdomain.com 域,這樣2個服務獨立預熱、互不影響。

3:良好收件人列表
預熱的收件人要儘量避免無效地址,因為 ESP 對發送較多無效地址的發送者是很不友好的,因為他們覺得你可能在發垃圾郵件,不利於額度增長和功能變數名稱信譽度的提升的,甚至會降低。


https://sendcloud.sohu.com/ (中國)
優點:
1. 連發連發都收得到
2. QQ、163、sina、gmail、yahoo都收得到
3. 到信速度較 submail 快

註冊需經過手機驗證,註冊成功後會發API_KEY註冊信箱
配置:
後台登陸後
"邮件设置" => "增加域名"
點擊域名進去後會提示你 VERIFY_KEY、SPF、DKIM、CNAME、MX 怎麼配置

然後去你DNS代管的地方配置解析

注意:
第一張圖DKIM 複製後要把斷行改成一行,然後在第二張圖主機記錄設@
CNAME的主機記錄設*
MX的記錄值設mx.sendcloud.org.

實測:
sendcloud.php
function send_mail($count) {
    $url = 'http://sendcloud.sohu.com/webapi/mail.send.json';
    $API_USER = 'API_USER'; // 登陸後台後會告訴你
    $API_KEY = 'API_KEY'; // 去註冊email找
    //不同于登录SendCloud站点的帐号,您需要登录后台创建发信子帐号,使用子帐号和密码才可以进行邮件的发送。
    $param = array(
        'api_user' => $API_USER,
        'api_key' => $API_KEY,
        'from' => 'service@sendcloud.im',
        'fromname' => 'SendCloud测试邮件',
        'to' => 'tom@qq.com',
        'subject' => "来自SendCloud的第{$count}封邮件!",
        'html' => "你太棒了!你已成功的从SendCloud发送了{$count}封测试邮件,接下来快登录前台去完善账户信息吧!",
        'resp_email_id' => 'true');

    $data = http_build_query($param);
    $options = array(
        'http' => array(
            'method' => 'POST',
            'header' => 'Content-Type: application/x-www-form-urlencoded',
            'content' => $data,
        ));
    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
    return $result;
}

// for ($i=1; $i < 11; $i++) { 
//     echo send_mail($i);
// }

echo send_mail(1);
$  php sendcloud.php
{"message":"success","email_id_list":["14522414xxxx_47971_1165_4583.sc-10_10_127_57-inbound0$tom@qq.com"]}

https://sendgrid.com/
測試結果
郵箱收到非垃圾郵件測試次數時間
QQVV110幾秒
易網VV110幾秒
新浪VV1幾10秒
gmailVV110幾秒
yahooVX110幾秒

連發10次到QQ
=>10封都收得到,6封進收件夾,4封進垃圾郵件
註冊流程較麻煩,註冊完後台出現黃字
Your account is currently being provisioned. You will not be able to send out any email.
回報客服後,他會問你一些簡單問題(如你公司做什麼的、流量多大之類的),之後才能正式開始用(因為他們人在美國(?)只會半夜回你)

配置:
sendgrid後台登陸後
SETTINGS => Whitelabels => Domains => Add Whitelable
新增發信功能變數名稱後,照後台提示。如圖
然後去你DNS代管的地方配置解析

注意:
使用阿里雲的代管比較靠譜,原本用 WIS 匯智 ,結果竟然只能設6組代管,而且主機名稱填
s1._domainkey.your.domain 會自動幫你改成 s1.domainkey.your.domain


其他發信服務商(未測試)
https://postmarkapp.com/
http://www.socketlabs.com/
https://aws.amazon.com/tw/ses/ (亞馬遜)
http://www.emailcar.net/ (中國)
https://www.phplist.com/
http://mailchimp.com/
http://www.aweber.com/
http://www.benchmarkemail.com/tw/

工具
http://www.mail-tester.com/  email垃圾郵件測評

參考資料:
http://blog.codinghorror.com/so-youd-like-to-send-some-email-through-code/  So You'd Like to Send Some Email (Through Code)


沒有留言:

張貼留言