imapをつかったDoCoMoからGmailへの転送ツールの作成

概要

例えば、プロバイダメールや、スマホメールをGoogleメールに集めたい。でも、Gmailでは、POP3による外部メールの取り込み機能はあるけど、IMAPで取り込みが出来ない・・・
そんな時に以下のスクリプトをどこかに仕掛けておけばOKです!
私は使っていませんでしたが、昔imodeのメールを転送するサービス「imoten」というのがあったようですね。今回のツールはメールを転送するものではなくて(結果そうなっているように見えますが)クライアント動作として、source側からIMAPでとってきて、destination側にIMAPで差し込みをしちゃうだけのツールになります。

事前準備

imap接続に際して、以下の準備が必要です。

  • Gmailの設定で、IMAPアクセスの項目で、IMAPを有効にするを選択
  • googleアカウントの設定で、安全でないデバイスからの接続を許可
  • 各種スマホメールをWifiなどのインターネット経由で閲覧可能にする

手順概要

  1. スクリプトファイルを設置する
  2. cronの設定をする

手順

  1. スクリプトファイルを設置する
    ココでは、設置するファイル名を mailrelaytool.php と、します。
    また、phpは imap, sslをコンパイル時に利用できるようにしており、imap.soをphp.iniもしくは実行時のextensionの設定で利用できる状態である事とします。
    以下のプログラムを /home/USERNAME/bin/mailrelaytool.php に設置したとします。

    < ?php
    
    $imapSrc = array(
      'user' => 'test1'
     ,'pass' => 'test1'
     ,'host' => 'imap.spmode.ne.jp'
    );
    
    $imapDst = array(
      'user' => 'test2@gmail.com'
     ,'pass' => 'test2'
     ,'host' => 'imap.gmail.com'
    );
    
    $now  = time();
    $last = $now - 1800;
    
    $imapSrc = imap_open("{" . $imapSrc['host'] . ":993/imap/ssl/novalidate-cert}INBOX"
                   , $imapSrc['user']
                   , $imapSrc['pass']
                   ) or die (var_dump(imap_errors()));
    
    $imapDst = imap_open("{" . $imapDst['host'] . ":993/imap/ssl/novalidate-cert}INBOX"
                   , $imapDst['user']
                   , $imapDst['pass']
                   , NULL
                   , 1
                   , array('DISABLE_AUTHENTICATOR' => 'PLAIN')
                   ) or die (var_dump(imap_errors()));
    
    $imapSrcs = imap_check($imapSrc);
    $overview_list = imap_fetch_overview($imapSrc, "1:{$imapSrcs->Nmsgs}", 0);
    
    foreach ($overview_list as $overview) {
      $time = strtotime($overview->date);
      if ($time < $last) { continue; }
    
      $head = imap_fetchheader($imapSrc, $overview->msgno);
      $body = imap_body($imapSrc, $overview->msgno);
    
      imap_append($imapDst, "{" . $imapDst['host'] . ":993/imap/ssl/novalidate-cert}INBOX", $head . $body);
    }
    
    imap_close($imapSrc);
    imap_close($imapDst);
    exit();
    
    ?>

    ※ここでミソはgmailはPLAINに対応していない事です!

  2. cronの設定をする
    % export EDITOR=vi
    % crontab -e
    0,30 * * * * /usr/bin/php -d extension=imap.so -f /home/USERNAME/bin/mailrelaytool.php 2>&1
    

    ※cliのphp.iniにextension=imap.so の記述があれば、「-d extension=imap.so」の部分は不要です。

以上です!

その後、修正版。2重起動防止。いつ発動しても良いように、前回取得時間を記憶するようにした版
エラー処理とか手抜きなので、使う時には直してね!

< ?php

$imapSrc = array(
  'user' => 'test1'
 ,'pass' => 'test1'
 ,'host' => 'imap.spmode.ne.jp'
);

$imapDst = array(
  'user' => 'test2@gmail.com'
 ,'pass' => 'test2'
 ,'host' => 'imap.gmail.com'
);

$count = 0;
$wait  = 10;
$retry = 2;
$lockfile = "./relaymail.lock";
$backNumber="./relaymail.bknm";

if(file_exists($lockfile) && (time() - filemtime($lockfile)) < 300){
  exit();
}
$lock = fopen($lockfile, "w");

$src = imap_open("{" . $imapSrc['host'] . ":993/imap/ssl/novalidate-cert}INBOX"
               , $imapSrc['user']
               , $imapSrc['pass']
               );

$dst = imap_open("{" . $imapDst['host'] . ":993/imap/ssl/novalidate-cert}INBOX"
               , $imapDst['user']
               , $imapDst['pass']
               , NULL
               , 1
               , array('DISABLE_AUTHENTICATOR' => 'PLAIN')
               );
if(imap_errors()) {
  fclose($lock);
  unlink($lockfile);
  exit();
}

$srcs = imap_check($src);
$overview_list = imap_fetch_overview($src, "1:{$srcs->Nmsgs}", 0);


$last=file_get_contents($backNumber, true);
if(!$last){ $last = time() - 60; }

foreach ($overview_list as $overview) {
  $time = strtotime($overview->date);
  if ($time < $last) { continue; }

  $count++;
  $head = imap_fetchheader($src, $overview->msgno);
  $body = imap_body($src, $overview->msgno);

  imap_append($dst, "{" . $imapDst['host'] . ":993/imap/ssl/novalidate-cert}INBOX", $head . $body);
}
imap_close($src);
imap_close($dst);

file_put_contents($backNumber, time());

fclose($lock);
unlink($lockfile);
exit();

?>