CakeEmailを使ってMac OS XからGmail経由でメールをする

CakePHP2.0でGmailを利用してメールを送ろうとして
SwiftMailerってのが使えるのかぁ。それならそれ使おう」
とか思ったのですが、どうやらCakeEmailというのがあるようなのでそれを使うことにした
# たぶんCakePHP1.3まではなかったんだよね?よく調べてないけど。



ついでにMac OS Xでメールを送る時の設定をしたことなかったのでそれもついでにした。


CakeEmailを使う

CakeEmailはEmailComponentに代わって作られたライブラリのようです。
「EmailComponentはdeprecatedだからCakeEmail使ってね」って書いておる。



やることは2つ。

  • CakeEmailの設定(gmailを使うので)
  • メール送信のコードを書く

だけ。簡単ですね。


CakeEmailの設定(gmailを使うので)

まず、Emailのconfigファイルはapp/Config/email.phpなので、defaultからコピーして作る

cp app/Config/email.php.default app/Config/email.php

# ただし、この中にはgmailの設定がないので今回はあんまりコピーの必要ない



email.phpの中身はプロパティだけを持つEmailConfigというクラスになっていて、
そのプロパティそれぞれに、利用したいメールシステムの設定を書くことができる。
例えば、

    public $default = array(
        // デフォルトの設定
    );

    public $smtp = array(
        // smtpを使うときの設定
    );

みたいな感じ。



CakeEmailを使う時に

$email = new CakeEmail('default');

などとすれば、そのプロパティ名の設定が使われる。



ということで、今回はgmailの設定を付け足す。

    public $gmail = array(
        'host' => 'ssl://smtp.gmail.com',
        'port' => 465,
        'username' => '自分のgmailアカウント',
        'password' => 'パスワード'
    );

こんな感じでEmailConfigのプロパティを追加すればいい。
これで設定は終わり。


メール送信のコードを書く

もし/Emails/sendというURLを踏んだ時に送りたいのだとしたら下のような感じ。

<?php
// app/Controller/EmailsController.phpに保存
App::uses('CakeEmail', 'Network/Email');

class EmailsController extends AppController {
    public function send()
    {
        $email = new CakeEmail('gmail');
        $res = $email->config(array('log' => 'emails'))
            ->from(array('from用のアドレス' => 'アドレスの別名'))
            ->to('送りたいアドレス')
            ->subject('タイトル')
            ->send('メッセージ');
        debug($res);
        $this->redirect($this->referer(), null, true);
    }
}

要点を挙げると

  • さっきプロパティに追加したgmailの設定を使うためにnewでgmailを指定
  • configでarray('log' => 'emails')という連想配列を渡して送信ログを吐く
    • 通常app/tmp/logs/emails.logというログができる(emailsの部分を変えた場合はその名前になる)
  • CakeEmailインスタンスはメソッドチェーンになってるのでfromやtoなどをそのまま繋げられる
  • 最後にsend()でメッセージ送信

という感じ。簡単ですね。



debug部分では

Array
(
    [headers] => From: アドレスの別名 <from用のアドレス>
X-Mailer: CakePHP Email
Date: Sun, 06 Nov 201118:47:34 +0900
Message-ID: <4eb67ce538444757aa9e1eb7cbdd56cb@localhost:8081>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
    [message] => メッセージ
)

みたいな値が出力される。
つまりレスポンスは'header'と'message'というkeyをもった連想配列になっているので、
テスト書くときはこの辺を確認すれば良さげ。
テストは以下のテストファイルが参考になる

lib/Cake/Test/Case/Network/Email/CakeEmailTest.php 

さてさて、ここまで上手くいったのだけど僕のMacBookはメール送信できる設定がしてなかったため、/var/log/mail.logにはgmailに弾かれているエラーが出てしまった。

Nov  6 18:47:34 leobook postfix/qmgr[99474]: AA9212A57807: from=<daemon@leobook.local>, size=483, nrcpt=1 (queue active)
Nov  6 18:47:34 leobook postfix/error[99627]: AA9212A57807: to=<送りたいアドレス>, relay=none, delay=0.58, delays=0.5/0.07/0/0.01, dsn=4.4.1, status=deferred (delivery temporarily suspended: connect to alt4.gmail-smtp-in.l.google.com[209.85.143.27]:25: Connection refused)

ということで、Mac OS Xから送信できるようにするためにググった。


Postfixの設定

Postfixを設定すると弾かれないらしい。
MacのマシンからPostfixでGmailに送信できるようにする - F.Ko-Jiの「一秒後は未来」
これをそのままやるだけでした。便利。ありがたい。嬉しい。



Macには元からPostfixが入っているのでそれを起動させる

# 起動
[18:48]% sudo postfix start                                                         [~]
postfix/postfix-script: starting the Postfix mail system

# プロセス確認
[18:48]% ps -ef | grep postfix                                                      [~]
    0 99472     1   0   0:00.01 ??         0:00.02 /usr/libexec/postfix/master

GMailに弾かれないように/etc/postfix/main.cf に追加。ウチのISPはniftyです。

# /etc/postfix/main.cfの最後に以下を追加
relayhost = [smtp.nifty.com]

# 再読み込み
[18:49]% sudo postfix reload                                                        [~]
postfix/postfix-script: refreshing the Postfix mail system

/var/log/mail.logのエラーメッセージが変わる。ここで出てくるleobookは僕が勝手に付けてる名前。

Nov  6 18:53:48 leobook postfix/qmgr[99991]: AA9212A57807: from=<daemon@leobook.local>, size=483, nrcpt=1 (queue active)
Nov  6 18:51:47 leobook postfix/smtp[99878]: 664292A579B9: to=<送りたいアドレス>, relay=smtp.nifty.com[202.248.238.12]:25, delay=0.72, delays=0.04/0.03/0.51/0.14, dsn=5.1.8, status=bounced (host smtp.nifty.com[202.248.238.12] said: 553 5.1.8 <daemon@leobook.local>... Unreturnable address rejected (in reply to MAIL FROM command))

leobook.localってのがダメですね、ということでmyhostnameを設定してみる

# /etc/postfix/main.cfにmyhostnameの行があるのでそこに追加
myhostname = nifty.com

# リロード
[18:53]% sudo postfix reload                                                        [~]
postfix/postfix-script: refreshing the Postfix mail system

/var/log/mail.logのlobook.local部分がnifty.comに変わる。

Nov  6 18:54:13 leobook postfix/qmgr[99991]: 0F51B2A57A6E: from=<daemon@nifty.com>, size=479, nrcpt=1 (queue active)
Nov  6 18:54:13 leobook postfix/smtp[99993]: 0F51B2A57A6E: to=<送りたいアドレス>, relay=smtp.nifty.com[202.248.238.12]:25, delay=0.94, delays=0.04/0/0.52/0.38, dsn=2.0.0, status=sent (250 2.0.0 pA69sD8T013242 Message accepted for delivery)


しばらくするとメールが届く。ひゃっほー!!
ということでやりたいことが全てできました。よかったよかった。