- 追加された行はこの色です。
- 削除された行はこの色です。
* IMAPをコマンド操作する [#hbecbce1]
#setlinebreak(on)
#contents
-- 参考
--- http://www.atmarkit.co.jp/ait/articles/0106/13/news001.html
--- http://www.atmarkit.co.jp/fnetwork/rensai/netpro09/imap4-command.html
--- http://www.atmarkit.co.jp/fnetwork/rensai/netpro09/imap4-fetch.html
** 接続 [#j06dc8a3]
SSL使用しない場合
#myterm2(){{
telnet imap.example.com 143
}}
SSL通信する場合は openssl を使用する
#myterm2(){{
openssl s_client -connect imap.gmail.com:993 -crlf -quiet
}}
** コマンド入力の基本 [#z6eb12d8]
コマンド入力時は、行の先頭に識別子を付加して行う。
#myterm2(){{
識別子 コマンド 引数/オプション等
}}
コマンドに対する結果は、コマンド実行時に入力した識別子が付加して返却される。
※ソケット通信するプログラムを組む時は、レスポンスの最終行の判定に、この識別子が利用できる。
※コマンドを手入力する時は常に "?" 等を入力しても問題ない。
例) 識別子として test01 を指定して、メールボックス一覧を表示する場合
#myterm2(){{
test01 list "" "*" # コマンド入力
* LIST (\HasNoChildren) "." "INBOX.Drafts" # ↓ 以降はレスポンス
* LIST (\HasNoChildren) "." "INBOX.Trash"
* LIST (\HasNoChildren) "." "INBOX.Sent"
* LIST (\Unmarked \HasChildren) "." "INBOX"
test01 OK LIST completed # レスポンスの最終行にも識別子が付加される
}}
** ログイン [#m751943c]
#myterm2(){{
a01 login test@example.com mail_password
a01 OK LOGIN Ok.
}}
** メールボックスの一覧表示 [#p3339d83]
#myterm2(){{
a02 list "" "*"
* LIST (\HasNoChildren) "." "INBOX.Drafts"
* LIST (\HasNoChildren) "." "INBOX.Trash"
* LIST (\HasNoChildren) "." "INBOX.Sent"
* LIST (\Unmarked \HasChildren) "." "INBOX"
a02 OK LIST completed
}}
** メールボックスの選択 [#nb1a1564]
#myterm2(){{
a03 select "INBOX"
* FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent)
* OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited
* 9 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 1483004963] Ok
* OK [MYRIGHTS "acdilrsw"] ACL
a03 OK [READ-WRITE] Ok
}}
※
** メールの検索 [#ieef46df]
#myterm2(){{
a04 search all
* SEARCH 1 2 3 4 5 6 7 8 9
a04 OK SEARCH done.
}}
** メッセージ番号を指定してメールヘッダを取得する [#ea0ac166]
#myterm2(){{
a05 FETCH 2 RFC822.HEADER
* 2 FETCH (RFC822.HEADER {1015}
Return-Path: <test@example.com>
Delivered-To: example.com-test@example.com
X-Spam-Checker-Version: SpamAssassin X.X.X (XXXX-XX-XX) on xxxx.xxxxx.com
.
.
Received: (qmail 12845 invoked by uid 89); 29 Dec 2016 18:50:58 +0900
From: XXXXX XXXXX <test@example.com>
Content-Type: text/plain;
charset=iso-2022-jp
Content-Transfer-Encoding: 7bit
Mime-Version: 1.0 (1.0)
Date: Thu, 29 Dec 2016 18:50:57 +0900
Subject: test2
Message-Id: XXXXXXXXXXXXXXXXXXXXXXX
To: test@example.com
)
a05 OK FETCH completed.
}}
** メッセージ番号を指定してメール内容を取得する [#obe1ec66]
#myterm2(){{
a06 FETCH 2 RFC822
* 2 FETCH (RFC822 {1434}
Return-Path: <test@example.com>
Delivered-To: example.com-test@example.com
X-Spam-Checker-Version: SpamAssassin X.X.X (XXXX-XX-XX) on xxxx.xxxxx.com
.
.
Received: (qmail 12845 invoked by uid 89); 29 Dec 2016 18:50:58 +0900
From: XXXXX XXXXX <test@example.com>
Content-Type: text/plain;
charset=iso-2022-jp
Content-Transfer-Encoding: 7bit
Mime-Version: 1.0 (1.0)
Date: Thu, 29 Dec 2016 18:50:57 +0900
Subject: test2
Message-Id: XXXXXXXXXXXXXXXXXXXXXXX
To: test@example.com
test2
)
a06 OK FETCH completed.
}}
** メッセージ番号を指定してメールを削除する [#ea4146d8]
メールの削除はDeletedフラグを設定後に、EXPUNGE(Deletedフラグの立っているメールを削除する) を実行する。
#myterm2(){{
a10 COPY 2 \"INBOX.Trash" # 対象のメッセージ番号のメールをゴミ箱にコピーする
a11 STORE 2 +FLAGS (\Deleted) # 対象のメッセージ番号のメールに Deleted フラグを立てる
a12 EXPUNGE # Deleted フラグの立っているメールを削除する
}}
** phpで ソケット通信する例 [#h4ff8c50]
*** 接続/ログイン [#pa030ae5]
#mycode2(){{
$fp = fsockopen("imap.example.com", "143", $errno, $errstr); //SSL通信しない場合
// $fp = fsockopen("ssl://imap.gmail.com", "993", $errno, $errstr); // SSL通信する場合
fputs($fp,"A01 login {$username} {$password}\r\n");
while (true) {
$line = fgets($fp);
if (preg_match("/(NO |failed|Failure)/i", $line)) {
// ログインエラー
fclose($fp);
}
if (preg_match("/^A01 /", $line)) { // 最終行
break;
}
}
}}
*** 件名のデコード [#j1e76d33]
Subject 等のヘッダは エンコードされた文字列から適切なデコード方法を判定できる。
ただし、長い件名等の時には、複数のデータに分割されているので、それぞれを個別にデコードした後に文字列結合する等の考慮が必要。
※ Fromヘッダ等もデコードが必要な場合がある。
PHPの例)
#mycode2(){{
public function decode_subject($line) {
$subject = $line;
if (preg_match_all("/=\?[a-zA-Z0-9\-_]+\?(B|Q)\?.+?\?=/", $subject, $ms)) {
$matches = $ms[0];
$rep = [];
foreach ($matches as $i => $str) {
$charset = preg_replace("/[^a-zA-Z0-9\-_]/", "", preg_replace("/\?.+$/", "", preg_replace("/^=\?/", "", $str)));
$subject_piece = $line;
if (preg_match("/=\?".$charset."\?(B|Q)\?/i", $str, $ms)) {
//$subject_piece = mb_decode_mimeheader($str);
$subject_piece = preg_replace("/\?=/", "", preg_replace("/=\?".$charset."\?(B|Q)\?/i", "", $str));
if ($ms[1] == "B") {
$subject_piece = mb_convert_encoding(base64_decode($subject_piece), "utf-8", $charset);
} else {
$subject_piece = mb_convert_encoding(quoted_printable_decode($subject_piece), "utf-8", $charset);
}
}
$rep[$i] = $subject_piece;
}
$subject = preg_replace("/\?=( |\t|\r\n|\r|\n)+=\?/", "?==?", $subject); // パート間のスペースを削除
foreach ($matches as $i => $str) {
$subject = str_replace($str, $rep[$i], $subject);
$subject = str_replace($str, "", $subject);
}
} else {
$subject = mb_convert_encoding($subject, "UTF-8", "auto");
}
return $subject;
}
}}
以下に例/イメージを記載する。
デコード前
#mycode(){{
=?utf-8?B?TWFj44GL44KJ6YCB5L+h44GX44Gf44OG44Kt44K544OI44Oh44O8?= =?utf-8?B?44Or?=
}}
分割( ?文字コード?(B|Q)? 〜 ?= を 1つの纏まりとして分割する )
#mycode(){{
=?utf-8?B?TWFj44GL44KJ6YCB5L+h44GX44Gf44OG44Kt44K544OI44Oh44O8?=
=?utf-8?B?44Or?=
}}
デコード後
#mycode(){{
=?utf-8?B?TWFj44GL44KJ6YCB5L+h44GX44Gf44OG44Kt44K544OI44Oh44O8?= → Macから送信したテキストメー
=?utf-8?B?44Or?= → ル
}}
結合後
#mycode(){{
Macから送信したテキストメール
}}
*** 本文のデコード [#wec292ad]
Content-Type 及び Content-Transfer-Encoding の内容を参照してデコードを行う。
※ただし、multipartなメールの場合は、それぞれのパートの Content-Type 等を参照する必要がある。
#todo
*** 添付ファイルの取得 [#d28914ab]
#todo
*** multipart の取り扱いについて [#y327eeba]
#todo
*** multipart/alternative なメールの取り扱い [#d7dfaf7f]
#todo
** UIDを指定して各種操作を行うには [#v0692d08]
上記の例で使用しているメッセージ番号は、常に1〜連番で付番される為、メールの削除等を行うと変わってしまう。(不変の番号ではない)
なので、各種の操作を行う際には、ユニークなID(UID)を指定して操作を行う方が確実である。
※UIDは過去に渡って重複しないユニークな値。
UIDを指定してコマンド実行を行うには、コマンドの前に "UID" を入力する。
例)
#myterm2(){{
# SEARCHの結果をUIDで表示する
a04 <strong>UID</strong> SEARCH ALL
* SEARCH 1 5 8 10 12
a04 OK SEARCH done.
# UID=10 を指定してメールヘッダを取得する
a05 <strong>UID</strong> FETCH 10 RFC822.HEADER
* 10 FETCH (RFC822.HEADER {1015}
Return-Path: <test@example.com>
Delivered-To: example.com-test@example.com
X-Spam-Checker-Version: SpamAssassin X.X.X (XXXX-XX-XX) on xxxx.xxxxx.com
.
.
&color(#f00){インライン要素};
}}
他にも、COPY、FETCH、STORE なども可能。