Cisco 7961G電話機にツイッターを表示する

題名は7961電話機となっているがCiscoの電話機の設定は(ある程度)互換性があるので他の機種でも使える筈。

CiscoのIP電話では電話機がアイドル状態になったときに(指定時間後に)指定したコンテンツを電話機の画面に表示させることができる。
このアイドル時のコンテンツ表示は基本は固定(1コンテンツを表示したまま)だけど、HTTPレスポンスヘッダのRefreshで時間とリダイレクト先の指定を行うと(HTMLコンテンツと同じく)コンテンツの表示を自動更新できる。

電話機に表示するコンテンツを自動更新する基本

7961G電話機の基本的な設定は「Cisco7961Gの設定

電話機の設定に追加・変更するもの
<device>
  中略
  <idleURL>http://local.example.com/idleA.xml</idleURL>
  <idleTimeout>60</idleTimeout>
  中略
</device>

電話機がアイドル状態になって60秒経つとidleURLに指定したコンテンツを電話機の画面に表示する。
これに対応するようウェブサーバ側を設定する。

Nginxの設定例
server {
  listen :80;
  server_name local.example.com;
  中略
  location /idleA.xml {
    add_header 'Refresh' '10; url=http://local.example.com/idleB.xml';
  }
  location /idleB.html {
    add_header 'Refresh' '10; url=http://local.example.com/idleA.xml';
  }
  中略
}
表示するコンテンツの例 (上のidleA.xml, idleB.xml)
<?xml version="1.0" encoding="UTF-8"?>
<CiscoIPPhoneText>
  <Title>お知らせ</Title>
  <Text>コンテンツ本文</Text>
</CiscoIPPhoneText>

日本語を書く場合CiscoのドキュメントではShift_JISにしろということになっているが、上の例のようにエンコード指定するならUTF-8で問題無いみたい。

ここまで出来たら、ウェブサーバの設定変更を反映させるために設定を読み直させる。

FreeBSD上のNginxの場合
# service nginx reload
または
# /usr/local/etc/rc.d/nginx reload

電話機の設定を変更したら電話機をリセットする。
受話器を置いた状態で[directory]キーまたは[settings]キーを押してから[*][*][#][*][*]を押して再起動(リセット)を待つ。

上の設定例を試すと
idleA.xmlを表示すると10秒後にidleB.xmlにリダイレクトする。
idleB.xmlを表示すると10秒後にidleA.xmlにリダイレクトする。
要するにidleA.xmlとidleB.xmlを交互に5秒ずつ表示する。

これはidleA.xml, idleB.xmlがプレーンなXMLテキストファイル(静的コンテンツ)として作成される場合を想定したもの。
シンプルすぎるけど、コールセンターの電話機であればオペレータ向け超簡易版デジタルサイネージ(単なるお知らせ)みたいな使い方としてはアリかもしれない。

実際の運用ではテキストファイルを書いてウェブサーバに置くのではなくCGI等で動的にコンテンツを生成するであろうからHTTPレスポンスヘッダはCGI側で出力する筈。となるとウェブサーバ側でHTTPレスポンスヘッダを付ける必要はない筈。(ウェブサーバ側で付けたらダメじゃないけど)

ツイッターのタイムラインを電話機に表示する

ここからが本題

電話機の画面にツイッターのタイムラインを表示させる。電話機のアイドルタイムが60秒を超えたらタイムラインを表示。以降、60秒ごとにタイムラインの表示を更新する。取得頻度を上げて取り続けるとツイッター側から取得制限がかかるので注意する。120秒程度に伸ばす方が安全かも。
電話機の画面が狭いので表示するのは最新1,2ツイートだけで十分だと思うが一応3つ取る。
前回表示以降にタイムラインにツイートが増えていようがいまいが常に最新を取って表示するという単純なものにする。

電話機の設定に追加・変更するもの
<device>
  中略
  <idleURL>http://local.example.com/idle.php</idleURL>
  <idleTimeout>60</idleTimeout>
  中略
</device>

twitter取得にはTwitterOAuthを使う。それについてはNanoPi NEOがTwitterを声でツブヤクンデスに書いているのでこの記事では入手方法等は省略。

idle.php
<?php
require_once("./twitteroauth/autoload.php");
use Abraham\TwitterOAuth\TwitterOAuth;

date_default_timezone_set('Asia/Tokyo');

$consumerKey = 'KeyKeyKeyKeyKeyKeyKeyKey';
$consumerSecret = 'SecretSecretSecretSecretSecretSecretSecretSecret';
$accessToken = 'TokenTokenTokenTokenTokenTokenTokenTokenTokenToken';
$accessTokenSecret = 'TokenSecretTokenSecretTokenSecretTokenSecret';
//認証
$connection = new TwitterOAuth($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret);

//タイムライン取得
$timeline = $connection->get('statuses/home_timeline', ['count' => '3']);
//var_dump($timeline);

$twout = "";
foreach($timeline as $tw){
    //ツイートIDと時刻
    $twout .= $tw->user->name . " " . date('Y-m-d H:i:s', strtotime($tw->created_at)) ."\n";
    //ツイート本文中のURLは消す
    $twout .= preg_replace('/https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:@&=+$,%#]+/', '', $tw->text) . "\n\n";
}

// ↑ twitter  ↓ XML出力

header('Content-Type: text/xml');  //レスポンスヘッダ XMLコンテンツとする
header("Refresh: 60;");                     //レスポンスヘッダ 60秒で更新

$dom = new DomDocument('1.0', 'utf-8');
$dom->formatOutput = true;

$out = $dom->appendChild($dom->createElement('CiscoIPPhoneText'));
$out->setAttribute("WindowMode", "Wide");
$out->appendChild($dom->createElement('Title', 'twitter'));
$out->appendChild($dom->createElement('Text', $twout));
echo $dom->saveXML();
?>

CiscoのドキュメントにはCiscoIPPhoneTextで属性にWindowModeを指定できるようなことは書いてなかったように思うけど試してみたら機能したのでWideを指定してテキスト表示エリアを電話機の画面横いっぱいに拡げている。できればテキストエリア下のプロンプト表示用の領域もテキスト表示用に使いたいところだけどドキュメントにそれらしいのが載っていないので諦めた。

ここまで出来たら電話機をリセットする(前述)。
PHPでHTTPレスポンスヘッダを出すようにしているのでこの記事最初の設定例のようなウェブサーバに何か追加するというのは特には要らない。

電話機にツイッターのタイムラインを表示する
電話の操作をしない(アイドル)状態で60秒後に電話機にツイッターのタイムラインが表示されるようになった。これが自動更新される。もちろん更新されるまでにツイートが増えてなれば表示は変わって見えない。

これで電話機を見る回数が増えるかしら?・・・・実はこれを作ってから暫く経つんだけど増えなかった。もう少し画面の情報量が多くないとねぇ。せめて1画面に5ツイート程度表示できれば電話機でツイートを読もうかなという気にもなるところなんだけど。

関連記事:

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です