RTMのリマインド機能みたいにSkypeメッセージ送りたい

オレオレリマインダー的なものが必要だったので、PHPからSkypeチャットしてみたメモです。

LinuxはD-Bus経由で通信

調べたところ、Linux上でSkypeAPIを利用するには、アプリケーション間でやりとりを行ってくれるD-Busっていうのを使うらしい。
自分の場合は、すでにD-Busのパッケージが入ってたので特にすることはないが、なければ yum や apt-get で簡単に入るようだ。
あともちろん、Linux版のSkypeも必要。

runlevelは5

Skypeはテキストログインでは使えないっぽい。
なので、Linuxはグラフィカルログインである必要がある。
この時点で、ちょっとやる気が落ちてきた。
ちなみに、テキストログインで運用中の場合は、コマンドラインで

telinit 5

と叩くとグラフィカルログインに動的に変更できる。(もちろんグラフィカルログインに必要なパッケージが揃っていれば)

PHP DBus を入れる

スクリプトからD-Busを利用するためには、そのための拡張やライブラリが必要です。Perlの場合は 'Net::DBus' ってのが既にあったので簡単に実装できました。
なので、すっきりしないですが、PHPからPerlスクリプトを叩くって方向でやってたんですが、最近グリー株式会社さんって所が 'PHP DBus'っていうPHP拡張モジュールを作ってくださったので、それをありがたく使わせてもらうことにしました。

さらに、Skype用のラッパークラスまで提供されています。まさに、渡りに船状態
インストール方法など、詳しい情報もこちらに載ってるので、それらを参考に導入しました。

とりあえず、Linuxのターミナル上から実行テスト

まず、Linux上でSkypeを立ち上げて、ターミナルから下記のPHPを叩く。

[skype_sample.php]
<?php
require_once 'Skype.php';
$skype = new Skype("skype_test_app", 5, true); //1.このスクリプトのアプリケーション名, 2.SkypeAPIのPROTOCOLバージョン, 3.デバッグモードスイッチ
if($skype->connect()){
  $chat_id = $skype->invoke("CHAT CREATE hoge"); //SkypeAPIを参照。SkypeID(この場合は'hoge')に対してSkypeチャットを作成する。
  $chat_id = preg_replace('/ .+$/', '', $chat_id[1]); //上の戻り値からChatIDのみを抽出(汚くてゴメン)。
  $skype->invokeChatmessage($chat_id, "メッセージだよ。"); //ChatIDを指定してメッセージを送信。
}

初回は、Skypeがこのスクリプトとの通信許可を求めてくるので許可する。
どうだろう?うまくいけば指定先にメッセージが送信されているはず。

現状、Skype.phpが開発中のもののようで、コンストラクタの引数の後ろ2つはスルーされる。
自分の場合は気になったので、手動で修正したが、そのうち修正されるはずなので問題ないと思う。

外部、及びcronから実行テスト

まず、普通に外部からSSHかなんかで接続して、PHPスクリプトをコンソールから叩くと

Fatal error: Uncaught exception 'Exception' with message 'dbus_bus_get() failed'

な感じでエラーになる。cronの場合も同じだろうと思う。
今現在も、これに対する正しい対処の方法が分からないんだけど、まぁ、環境変数が違うんだろーなと思って、Linux上のターミナルとSSH接続の外部コンソールの環境変数の違いを洗い出したところ、どうやら

DBUS_SESSION_BUS_ADDRESS

という環境変数をセットする必要があるようだ。
セットする値の方は

unix:abstract=/tmp/dbus-XXXXXXXXXX

な感じで、コロコロ変わってしまいそうな値です。
まぁ、再起動とかしなきゃ大丈夫だと思うので、今回はハードコーディングで環境変数セットしてやります。

[skype_sample.php]
<?php

putenv("DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-XXXXXXXXXX");

require_once 'Skype.php';
$skype = new Skype("skype_test_app", 5, true); //1.このスクリプトのアプリケーション名, 2.SkypeAPIのPROTOCOLバージョン, 3.デバッグモードスイッチ
if($skype->connect()){
  $chat_id = $skype->invoke("CHAT CREATE hoge"); //SkypeAPIを参照。SkypeID(この場合は'hoge')に対してSkypeチャットを作成する。
  $chat_id = preg_replace('/ .+$/', '', $chat_id[1]); //上の戻り値からChatIDのみを抽出(汚くてゴメン)。
  $skype->invokeChatmessage($chat_id, "メッセージだよ。"); //ChatIDを指定してメッセージを送信。
}

これで動くと思います。
必要なのは、Skypeが起動しているところのsessionアドレスなので dbus-launch とかで新規に作っても駄目っぽいです。

まとめ

Linux版のSkypeは現在バージョン2なので、PROTOCOL 5 までしか対応してないけど、そこそこ遊べそう。
ただ、Skypeクライアントを使わず、WebAPIのようなものがあればこんな面倒なことはしなくていいなぁ。どこかやらないかなぁ。
あと、現状では汎用的なものになってないので、今後も調査してみる。

--
もっとシンプルな方法があるはず。