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

概要

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

事前準備

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

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

手順概要

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

手順

スクリプトファイルを設置する
ココでは、設置するファイル名を 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に対応していない事です!

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();

?>

投稿日

カテゴリー:

,

投稿者:

タグ: