TT-RSSとメールサーバの連携 その3(PHP製IMAP->RSS変換ツールを試す 改造版試作1号)


前回挑戦したPHP製IMAP->RSS変換ツールですが、
いくつか不満点があったので修正してみました。

ベースは、Mail2RSSというPHPで書かれたソースコード
https://github.com/vekin03/Mail2RSS

変更点は以下の通り

  • 日付フォーマットをRFC822からRFC2822(RFC_RSS)に変更
    (RSS速報でRSSを受け付け無いため修正。年表記が下2桁から4桁への変更。)
  • 表題にメール日時を追加(表題フォーマットは[メール送信者] 日付 件名)
    (表題が同名だと、RSSリーダ側でサマリされてしまう場合があるため)
    ([guidが入っていなかったためかも])
  • guidに値が入っていない場合、メール日付と件名をセットするよう変更
    (通常はmessege_idの値が入るのだけど、Zabbixから送信したメールのmessege_idに値が入っていない模様。メールサーバ側の問題かも)
  • 本文がBase64でエンコードされている場合、自動的にデコードするよう変更
    (本文がテキストでもBase64エンコードされて表示されてしまうため)
    (マルチパートメールに関しては未確認)
  • <Language>を”en-en”から”ja”に変更

 

mail2rss.php(本家はhttps://github.com/vekin03/Mail2RSS

<?php
// Mail2RSS – Display your latest mails in a RSS feed
// Version: 0.1 alpha – alpha
// Author: Kevin VUILLEUMIER (kevinvuilleumier.net)
// Add:Nasubi
// Licence: http://www.opensource.org/licenses/zlib-license.php
// User-defined constants
// ============= CHANGE BY YOUR OWN INFORMATIONS HERE ! =============
define(‘TOKEN’, ‘TOKEN’);
define(‘MAIL_PROTO’, ‘IMAP’); // You can choose : IMAP, POP3
define(‘MAIL_USERNAME’, ‘yourname@yourmaildomain’);
define(‘MAIL_PASSWORD’, ‘password’);
define(‘MAIL_SERVER’, ‘yourmailserver’);
define(‘MAIL_PORT’, 143);
define(‘MAIL_SECURITY’, ); // You can choose : SSL, TLS or leave blank
//define(‘MAIL_CHECK_CERTIFS’, true);
//==================================================================
//error_reporting(-1);
// See all errors (for debugging only)
// If the token is not sent or if it is invalid, then force quit
if (!isset($_GET[‘token’]) || $_GET[‘token’] != TOKEN) exit;ob_start();header(‘Content-Type: application/rss+xml; charset=utf-8’);

$imap_address = ‘{‘.MAIL_SERVER.’:’.MAIL_PORT;

if (MAIL_PROTO == ‘IMAP’) {
$imap_address .= ‘/imap’;
} else if (MAIL_PROTO == ‘POP3’) {
$imap_address .= ‘/pop3’;
}

if (MAIL_SECURITY == ‘SSL’) {
$imap_address .= ‘/ssl’;
} else if (MAIL_SECURITY == ‘TLS’) {
$imap_address .= ‘/tls’;
}

$imap_address .= ‘}’;

$mbox = imap_open($imap_address, MAIL_USERNAME, MAIL_PASSWORD);

if($mbox) {
$num = imap_num_msg($mbox);

if($num >0) {
echo ‘<?xml version=”1.0″ encoding=”UTF-8″?>’.”\n”;
echo “\t”.'<rss version=”2.0″ xmlns:content=”http://purl.org/rss/1.0/modules/content/”>’.”\n”;
echo ‘<channel><title>’.htmlspecialchars(MAIL_USERNAME).'</title><link>http://’.$_SERVER[“SERVER_NAME”].$_SERVER[“SCRIPT_NAME”].'</link>’;
echo ‘<description>Latest incoming mails in the mailbox</description><language>ja</language><copyright></copyright>’.”\n\n”;

for ($i = $num, $j = 0; $i >= 1 && $j < 20; $i–) {
$headerText = imap_fetchHeader($mbox, $i);
$header = imap_rfc822_parse_headers($headerText);
$from = $header->from;

$struct = imap_fetchstructure($mbox, $i);
$is_plain_text = false;
$content = ”;
$charset = ”;
$title = ”;

if (!isset($struct->parts)) {
$content = imap_fetchbody($mbox, $i, 1, FT_PEEK);
$is_plain_text = true;

foreach ($struct->parameters as $param) {
if (strtolower($param->attribute) == “charset”) {
$charset = strtolower($param->value);
}
}
} else {
$content = imap_fetchbody($mbox, $i, 2, FT_PEEK);

foreach ($struct->parts[0]->parameters as $param) {
if (strtolower($param->attribute) == “charset”) {
$charset = strtolower($param->value);
}
}
}

$from_mail = $from[0]->mailbox.’@’.$from[0]->host;
$date = date(DATE_RSS, strtotime($header->date));
$guid = $header->message_id;
$subject = $header->subject;

if ($charset == “utf-8”) {
$title = iconv_mime_decode($subject, 0, ‘UTF-8’);
$content = quoted_printable_decode($content);
} else {
$title = utf8_encode(imap_utf8($subject));
$content = utf8_encode(imap_utf8($content));
}

if ($is_plain_text) {
if (base64_decode($content, true)) {
$content = nl2br(base64_decode($content));
} else {
$content = nl2br($content);
}
}

if ($guid == “”) {
$guid = htmlspecialchars(date(“Y-m-d\TH:i:s”, strtotime($header->date))).’ ‘.htmlspecialchars($title);
}

echo ‘<item><title>[‘.htmlspecialchars($from_mail).’] ‘.htmlspecialchars(date(“Y-m-d\TH:i:s”, strtotime($header->date))).‘ ‘.htmlspecialchars($title).'</title><guid isPermaLink=”false”>’.htmlspecialchars($guid).'</guid><pubDate>’.htmlspecialchars($date).'</pubDate>’;
echo ‘<description>Mail sent by ‘.htmlspecialchars($from_mail).’ on ‘.htmlspecialchars($date).'</description><content:encoded><![CDATA[‘.$content.’]]></content:encoded>’.”\n</item>\n”;

$j++;
}

echo “</channel>\n</rss>”;
}

//close the stream
imap_close($mbox);
ob_end_flush();
}
?>

呼び出しは前回と同じでブラウザでアクセス

TT-RSSとやり取りする上では、今のところ問題なし。

Feed Validator for Atom and RSS(http://feedvalidator.org/)とか
W3C RDF Validation Service(http://www.w3.org/RDF/Validator/)で確認してみましたが、

警告は以下の2つぐらいで、今のところ大きな問題はないようです。
・Feeds should not be served with the “text/plain” media type
・Missing atom:link with rel=”self”

本当は、Zabbix 2.2のアラームを棒読みちゃんでしゃべらせたら面白いかもの通り
RSS速報と連携して棒読みちゃんを起動できたらうれしかったのだけれども、
RSS速報の起動時や、設定変更時には最新のRSS状況をしゃべるが、
その後は更新時間が来ても明示的に更新しても、新着RSS記事を見つけてくれない状況はかわらず。

たぶん、RSSの何かのパラメータが足りなくて、更新をうまく検知できていないのかもしれません。

なかなか難しいものです。

つづき
Zabbix 2.2のアラームを棒読みちゃんで読み上げてみた(正当版)。


コメントを残す

メールアドレスが公開されることはありません。