前回の続き。
WWW::Curlを使う
curlコマンドにJSONデータを直接指定してメールが送られることは分かったので、今度は、PerlのCurlインターフェースであるWWW::Curlを使って送ってみる。
もともと、curlに明るくなく、WWW:Curlのドキュメントはcurlを知っている前提で書かれていたため、とてもわかりにくかったが、結果分かったことを整理する。
- 今回やりたかったことは、WWW::Curl::Easyでできる。
- WWW::Curl::Easy->newでインスタンス生成。
- curlのコマンドオプションに相当するものは、すべてsetoptで値をセットできる。
CURLOPT_URL…--urlオプション
CURLOPT_POST…真の値をセットすると--request POSTと同じ。
CURLOPT_HTTPHEADER…--headerオプション。配列のリファレンスで渡す。
CURLOPT_POSTFIELDS…--dataオプション。JSONデータを指定する。 - performで実行。
use strict; use warnings; use WWW::Curl::Easy; my $curl = WWW::Curl::Easy->new; $curl->setopt(CURLOPT_URL, "https://api.sendgrid.com/v3/mail/send"); $curl->setopt(CURLOPT_POST, 1); $curl->setopt(CURLOPT_HTTPHEADER, [ "Authorization: Bearer [API KEY]", "Content-Type: application/json", ]); $curl->setopt(CURLOPT_POSTFIELDS, [JSON DATA]); my $retcode = $curl->perform; print $retcode;
$ perl wwwcurl.pl 0$
preformの返り値は0だと正常終了、それ以外はエラーコードとなる。よく見たら、ドキュメントにサンプルコードが載っていた。
http://search.cpan.org/~szbalint/WWW-Curl-4.17/lib/WWW/Curl.pm#WWW::Curl::Easy
とりあえず、これで、curlコマンドと同等の処理をPerlでできた。
sendmail_sendgrid - JSONデータの部分を動的に生成する
今までの方法だと、JSONデータ部分がまったく手動で作る必要があり(手っ取り早くPHPのjson_encodeを使ったりした)、汎用性がないので、データ部分を動的に生成して送るようにする。SendGridのオプションは猛烈にたくさんあるが、私が今までに使っていたパラメータだけを使う前提とした。つまり、送信先アドレス、件名、送信元アドレス、送信元名、本文(プレーンテキスト)のみとした。
use strict; use WWW::Curl::Easy; use MIME::Base64; use JSON; use Unicode::Japanese; sub sendgrid_send { my %opt = ( "CURLOPT_URL" => "https://api.sendgrid.com/v3/mail/send", "api_key" => "[API_KEY]", @_); my $json = { "personalizations" => [ { "to" => [ { "email" => $opt{"sendto"}, } ], "subject" => sendmail_enc_b64($opt{"subject"}), } ], "from" => { "name" => sendmail_enc_b64($opt{"sendfrom_name"}), "email" => $opt{"sendfrom"} }, "content" => [ { "type" => "text/plain", "value" => Unicode::Japanese->new($opt{"mailbody"})->getu, } ], }; if ($opt{"sendto_name"}) { $json->{"personalizations"}->[0]->{"to"}->[0]->{"name"} = sendmail_enc_b64($opt{"sendto_name"}); } if (ref $opt{"cc"} eq "ARRAY") { for my $cc(@{$opt{"cc"}}) { push(@{$json->{"personalizations"}->[0]->{"cc"}}, { "email" => $cc }); } } if (ref $opt{"bcc"} eq "ARRAY") { for my $cc(@{$opt{"bcc"}}) { push(@{$json->{"personalizations"}->[0]->{"bcc"}}, { "email" => $cc }); } } my $curl = WWW::Curl::Easy->new; $curl->setopt(CURLOPT_URL, "https://api.sendgrid.com/v3/mail/send"); $curl->setopt(CURLOPT_POST, 1); $curl->setopt(CURLOPT_HTTPHEADER, [ qq|Authorization: Bearer $opt{"api_key"}|, "Content-Type: application/json", ]); $curl->setopt(CURLOPT_POSTFIELDS, JSON->new->ascii(1)->utf8(1)->encode($json)); my $retcode = $curl->perform; die $retcode if $retcode; } sub sendmail_enc_b64 { my $subject = shift; return "=?utf-8?B?" .encode_base64($subject, "") . "?="; } 1;
# 1通ずつ送る require "lib_sendmail_sendgrid.pl"; sendgrid_send( "sendto_name" => "山田太郎", "sendto" => q|sendto@example.com|, "subject" => "メール送信テスト", "sendfrom_name" => "送信元名", "sendfrom" => q|sendfrom@example.com|, "mailbody" => "これはメール送信のテストです。これはメール送信のテストです。これはメール送信のテストです。これはメール送信のテストです。", );
これでメールを送ることができた。SendGridのAPIでは、メールヘッダにマルチバイト文字を使っても何も処理してくれない(生のまま)ので、MIMEエンコードの処理を入れた。
次回へ続く。