新しいConoHaではほとんどの操作がAPI経由で行えます。APIドキュメントを見ているといろいろと今後の展開が楽しみになってくるような作りになっています。
その中でもメールサーバAPIには「自動実行」とあるので、メールを受け取ってのあれやこれやができそうです。使ってみたところ意外とつまづきましたので、手順を公開したいと思います。

自動実行の仕様

現段階では自動実行についてのドキュメントはAPIのものしかありません。使うにあたってヘルプデスクへの問い合わせが必要でした(何度も相手していただいてありがとうございます)。

アンドキュメンテッドな部分も含め、次の仕様になっています。

  • メールアドレスにwebhookを指定できる。
  • webhookはhttp/httpsのURLとキーワードで指定する。
  • メールアドレスごとにwebhookは1つまで指定できる。
  • メールヘッダ X-Webhook-Keyword に指定したキーワードを持つメールを受け取った時にwebhookをリクエストする。
  • キーワードは完全一致である必要がある(部分一致では自動実行しない)。
  • webhookには特段のデータは送られない(メールの情報はwebhookに渡されない)。

……っとまあ現段階では正直使いにくいですね、空メール送って会員登録とかしようにもメールヘッダの縛りがあってwebhookを起動できないです。メールヘッダを加えるプログラム挟むなら直接http叩いたほうが早いですし。このあたりはバージョンアップに期待です。

webhookの仕掛け方

管理画面はないので、APIをたたきます。RESTfulなAPIなのですべてcURLコマンドで実行できます。

APIトークン発行

まず「APIのログイン」ともいえるトークン発行を行います。

curl -i -X POST \
-H "Accept: application/json" \
-d '{"auth":{"passwordCredentials":{"username":"aaaa12345678","password":"hogefuga"},"tenantId":"foobarfoobarfoobarfoobar"}}' \
https://identity.tyo1.conoha.io/v2.0/tokens

usernameは管理画面の「API」タブにあるAPIユーザ名をコピペします。自分で設定はできません。
passwordは管理画面で事前に設定します。右側の鉛筆アイコンです。
tenantIdも管理画面のAPI情報「テナントID」からコピーします。

応答は次のようになります。

HTTP/1.1 200 OK
Server: openresty/1.7.10.1
Date: Fri, 10 Jul 2015 11:20:33 GMT
Content-Type: application/json
Content-Length: 2452
Connection: keep-alive

{"access":{"token":{"issued_at":"2015-07-10T11:20:33.869642","expires":"2015-07-11T11:20:33Z","id":"fizzbuzzfizzbuzz","tenant":{"name":"aaaa12345678",(以下略)

これのうち”id”の値がトークンになります。以降のリクエストヘッダ「X-Auth-Token: fizzbuzzfizzbuzz」として指定することで、各APIを使用できます。

メールUUIDの取得

次にメールのUUIDを取得します。メールアドレスは事前に管理画面で作成しておいてください。ここでは「notify@noldor.conoha.io」とします。

$ curl -i -X GET \
> -H "Accept: application/json" \
> -H "X-Auth-Token: fizzbuzzfizzbuzz" \
> https://mail-hosting.tyo1.conoha.io/v1/emails
HTTP/1.1 200 OK
Server: openresty/1.7.10.1
Date: Fri, 10 Jul 2015 11:24:57 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 349
Connection: keep-alive
X-Openstack-Request-Id: req-d04e0ff1-d50e-4a7f-bbbf-3b9ee6f34d32

{"total_count": 1, "current_count": 1, "emails": [{"username": "notify@noldor.conoha.io", "total_usage": 0.01, "email_id": "abcd1234-ab12-ab12-ab12-abcdef123456",(以下略)

これのうち”email_id”がメールIDになり、REST APIのリソースIDになります。

webhookの指定

webhookはメールIDに対して指定します。いかにもRESTfulな感じで、https://mail-hosting.tyo1.conoha.io/v1/emails/abcd1234-ab12-ab12-ab12-abcdef123456/webhookに対してリクエストを発行することになります。

設定済みのメールアドレスにPOSTするとエラーになるので、設定変更はPUTを使いましょう。2つ以上は指定できません。

$ curl -i -X POST \
> -H "Accept: application/json" \
> -H "Content-Type: application/json" \
> -H "X-Auth-Token: fizzbuzzfizzbuzz" \
> -d '{"webhook_url":"http://example.com/test.php","webhook_keyword":"abc"}' \
> https://mail-hosting.tyo1.conoha.io/v1/emails/abcd1234-ab12-ab12-ab12-abcdef123456/webhook
HTTP/1.1 200 OK
Server: openresty/1.7.10.1
Date: Fri, 10 Jul 2015 11:39:57 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 93
Connection: keep-alive
X-Openstack-Request-Id: req-1d8c156b-1300-4fa1-bb52-807ced307c86

{"webhook": {"webhook_url": "http://example.com/test.php", "webhook_keyword": "abc"}}

POSTのとき、リクエストヘッダに「Content-Type: application/json」を指定する必要があります現段階でAPIドキュメントには書かれていないので要注意です(後日書き加えるとのことです)。書き加えられました。
このリクエストヘッダが抜けると

{"error": {"message": "InvalidRequest", "code": 400, "details": "Malformed JSON in request body."}}

のエラーになります。

メールを送る

ここまででwebhookの指定ができました。メールを送って起動してみましょう。webhookに指定したtest.phpを次のように作ります。

hello.
<!--?php </p>
<p>$mes[] = date('Y-m-d H:i:s');<br ?--> $mes[] = '[GET]';
$mes[] = print_r($_GET, true);
$mes[] = '[POST]';
$mes[] = print_r($_POST, true);
$mes[] = '[SERVER]';
$mes[] = print_r($_SERVER, true);
error_log(join("\n", $mes) . "\n\n", 3, 'test.txt');

ブラウザからアクセスしてtest.txtにログが書き込まれることを確認してください。

つぎにメールを送るコードmail.phpを作ります。

<!--?php </p>
<p>$additional_headers = 'X-Webhook-Keyword: abc';<br ?--> $to = 'notify@noldor.conoha.io';
$subject = 'testtest';
$message = 'konichiwa';

$result = mail($to, $subject, $message, $additional_headers);
var_dump($result);

ここでX-Webhook-Keywordは先に指定したwebhook_keywordと完全一致する必要があります。部分一致では起動しません。
X-Webhook-KeywordもまだAPIドキュメントには書かれていないので、要注意です。書き加えられました。

作ったらさっそく起動します。

$ php mail.php
bool(true)

ここでfalseならメールが送られていないので、実行環境を確認してみてください。sendmailなどを入れる必要があるかもしれません。メール送信先をgmailなどにしてきちんとメールが送られるかを確認する必要もありそうです。

メールとほぼ同時刻にログが書き込まれれば成功です。

2015-07-10 20:53:03
[GET]
Array
(
)

[POST]
Array
(
)

[SERVER]
Array
(
(中略)
)

……中身、空っぽなんですよねぇ:(

今後に期待

メールをトリガとするだけならgmailとIFTTTでも実現できますが、ITFFFは15分間隔での確認になる一方、APIならリアルタイム処理が可能です。
APIでメール一覧を取ってくるなどもできるので、X-Webhook-Keywordの指定が不要になればいろいろ可能になるのですが……。

しかし、今後の拡張余地を確保してあるつくりになっているのがドキュメントから読み取れます。今後の拡張に期待しています!

書いたらずいぶん長くなった上に、結論がちょいと残念な感じに。ここまで辛抱強く読んでいただいてありがとうございました。

……

登録される方は紹介用URLから登録していただけると僕がよろこびます。登録者にも1000円クーポンが発行されるのでおねがいします。