緊急地震速報がきたら音声で震度を読み上げるAppleScript

地震こわいですね。

そんなとき安心できるのは、緊急地震速報(EEW)。地震が来る前もしくは揺れてるときに、この地震はたぶん震度3だとかがわかるので、それほど怖がらなくて済む。EEWは大きな地震だけじゃなく、小さな地震でもそういう意味で効果があると思ってる。

そんなEEWをプッシュ的に受け取れる環境が、自分のところには3つある。

これらにはそれぞれ自分としては不満があって、

  • ケータイは、そもそも大きな地震のときしか教えてくれないので、「この地震は小さいから安心」という用途には使えない
  • ケータイとGoogleChromeは、1つの地震で初期の速報しかこない。EEWは短い間に何度も更新されて、最初に震度5弱で出た速報も数秒後には震度2くらいになったりするが、それがわからない。
  • どれにでも言えるのは、どんな地震の時も同じ音が鳴るので、画面を見ないと震度がわからない。

という感じ。別にそれでかまわない人は全然いいと思うけど。自分は、

  • 音だけで震度がわかって
  • 速報が更新されてもどんどん追ってくれる

というものが欲しい。

Twitter for Mac用のAppleScriptとして作ってみた

というわけで作ってみた。

Twitter for Macというのがあって、Mac App Storeで無料で配布されているMac用の公式Twitterクライアント。これはTwitterのストリーミングAPIに対応していて、リアルタイムでタイムラインが流れる。さらに、AppleScriptにも対応していて、スクリプトからタイムラインの情報を取得できたりする。

それから、@yurekuruというTwitterアカウントがある。これはiPhoneのゆれくるコールのアプリと同じところでやっていて、EEWをTwitterにポストしている。速報が更新されると、それらも全部ポストされる。

そこで、こんなことを考えた。

  1. @yurekuruを自分のアカウントでフォローして
  2. Twitter for Macで表示させて
  3. AppleScriptでTLを監視して
  4. EEWが来たらsayコマンドでしゃべる!

という感じ。そんなことができるAppleScriptを書いてみた。

コードは以下。

tell application "Twitter"
	set lastid to status id of status 1 of home timeline of current account
	repeat
		set firstid to status id of status 1 of home timeline of current account
		repeat with s in (statuses of home timeline of current account)
			set currentid to status id of s
			if lastid is greater than or equal to currentid then
				set lastid to firstid
				exit repeat
			end if
			if username of author of s is "yurekuru" then
				set txt to text of status 1 of home timeline of account 1 as string
				set msg to ""
				if (offset of "最大震度:不明" in txt) is greater than 0 then set msg to "shynd foomay"
				if (offset of "最大震度:1" in txt) is greater than 0 then set msg to "shynd ichi"
				if (offset of "最大震度:2" in txt) is greater than 0 then set msg to "shynd ni"
				if (offset of "最大震度:3" in txt) is greater than 0 then set msg to "shynd sahn"
				if (offset of "最大震度:4" in txt) is greater than 0 then set msg to "shynd yown"
				if (offset of "最大震度:5弱" in txt) is greater than 0 then set msg to "shynd go jaku"
				if (offset of "最大震度:5強" in txt) is greater than 0 then set msg to "shynd go kio"
				if (offset of "最大震度:6弱" in txt) is greater than 0 then set msg to "shynd ro ku jaku"
				if (offset of "最大震度:6強" in txt) is greater than 0 then set msg to "shynd ro ku kio"
				if (offset of "最大震度:7" in txt) is greater than 0 then set msg to "shynd nana"
				do shell script "say " & msg
			end if
		end repeat
		delay 1
	end repeat
end tell

使い方

  1. Twitterで@yurekuruをフォローして、
  2. Twitter for Macを起動しておく。
  3. AppleScriptエディタを起動して
  4. 上記のコードをコピペする。
  5. watch_yurekuru_for tfm.app」などの名前で、アプリケーション形式で保存。
  6. 保存したファイルをダブルクリック。

これで監視が始まる。あとは@yurekuruがEEWをポストすると、それを見つけて音声で震度を読み上げる。速報が更新されればそれも読み上げる。

sayコマンドにムリヤリ日本語をしゃべらせてるので発音がアレだけど許して。

終了するには、Dockのアイコンを右クリックして、optionキーを押すと「強制終了」が出るのでそれをクリック。通常の終了はできないですごめんなさい。

どんな感じかテストしたければ

上記のコードの "yurekuru" って判定している部分を、自分のアカウント名に書き換えて、自分のアカウントから「最大震度:4」とかの文字をポストすればテストできる。このときコロンも数値も全角で書くのがポイント。

反応する震度を変える方法

上記のコードの「最大震度」って文字を判定してる部分を、適当にコメントアウトすればOK。AppleScriptのコメントはハイフン2つ。

ひどいコードだと思う

正直AppleScriptは超初心者なので、かなり非常識なコードを書いてる気がする。

例えば、無限ループで処理をさせているのはいいんだろうか。よくわかんないけど、終了するには強制終了するしかなくなっちゃった。

あと、ループは時間的に未来から過去に向けて(TLの上から下に向けて)処理してるので、監視中にEEWが複数更新された場合に、新しいものを先に読み上げてしまう。激しく微妙。逆からループしたいんだけど、どうしたものかわからなかった。

誰かもっといいコードに直してくれないかなー。

2011-7-30 追記

LionがKyokoで日本語の読み上げに対応したので、直してみた。

上記リンク先に書いたやり方で、Kyokoをインストールして有効にしておくこと。

tell application "Twitter"
	set lastid to status id of status 1 of home timeline of current account
	repeat
		set firstid to status id of status 1 of home timeline of current account
		repeat with s in (statuses of home timeline of current account)
			set currentid to status id of s
			if lastid is greater than or equal to currentid then
				set lastid to firstid
				exit repeat
			end if
			if username of author of s is "yurekuru" then
				set txt to text of status 1 of home timeline of account 1 as string
				set msg to ""
				if (offset of "最大震度:不明" in txt) is greater than 0 then set msg to "震度は不明"
				if (offset of "最大震度:1" in txt) is greater than 0 then set msg to "震度1"
				if (offset of "最大震度:2" in txt) is greater than 0 then set msg to "震度2"
				if (offset of "最大震度:3" in txt) is greater than 0 then set msg to "震度3"
				if (offset of "最大震度:4" in txt) is greater than 0 then set msg to "震度4"
				if (offset of "最大震度:5弱" in txt) is greater than 0 then set msg to "震度、5弱"
				if (offset of "最大震度:5強" in txt) is greater than 0 then set msg to "震度、5強"
				if (offset of "最大震度:6弱" in txt) is greater than 0 then set msg to "震度、6弱"
				if (offset of "最大震度:6強" in txt) is greater than 0 then set msg to "震度、6強"
				if (offset of "最大震度:7" in txt) is greater than 0 then set msg to "震度7"
				do shell script "say " & msg
			end if
		end repeat
		delay 1
	end repeat
end tell

読み上げの文字を日本語にした。弱とか強がついてると発音が微妙だったから、句読点を打ってみた。それだけ。