今日は早起きしたのでさくっと作った。
rb-skypemacがRuby1.8でしか動かなかったり、Ruby4Skypeがソースを修正しないと動かなかったり、どのskype gemもリポジトリが公開されてなくてパッチ送れなかったので1から作りなおした。
https://github.com/shokai/skype-ruby
https://rubygems.org/gems/skype
linuxだとruby-dbus、macだとrb-appscriptを使うんだけどOS毎に別のgemをdependencyに入れるのどうすればいいんだろう・・
gemspecの中でRUBY_PLATFORMを見てspec.add_dependencyしたらローカルでbundle installすると大丈夫だけど、rubygems.org経由でgem installするとlinuxなのにrb-appscriptが入ってしまってcocoa.hが無くてビルドエラーする。
インストール
for Mac
% gem install skype rb-appscript
for Linux
% gem install skype ruby-dbus
Gemfile でインストールする場合
gem 'skype'
gem 'rb-appscript' if RUBY_PLATFORM =~ /darwin/i
gem 'ruby-dbus' if RUBY_PLATFORM =~ /linux/i
使い方
これはRubyのメタプログラミングを使った超単純なラッパーなので、使う前に
Skype Developer – Skype Desktop API Reference Manualを読んで理解してください
読めばわかると思う
require 'rubygems'
require 'skype'
Skype.config :app_name => "my_skype_app"
## send message
Skype.message "USER_NAME", "hello!!"
## call
Skype.call "USER_NAME"
## get recent chat list
puts Skype.search("recentchats")
## send message to group chat
Skype.chatmessage "#name1/name2;$a1b2cdef3456", "hello chat!!"
簡単に電話かけたりチャットに投稿したりできますね。やりましたね。
しかもMacでもLinuxでも動く。
くわしい内部実装
Skype.messageやSkype.callなどの関数は実装されていません。
実装されていませんが、method_missingを使った簡単なメタプログラミングでSkype.execに変換されて実行されます。
以下と等価です
## send message
Skype.exec "MESSAGED USER_NAME hello!!"
## call
Skype.exec "CALL USER_NAME"
## get recent chat list
puts Skype.exec "SEARCH recentchats"
## send message to group chat
Skype.exec "CHATMESSAGE #name1/name2;$a1b2cdef3456 hello chat!!"
Skypeには各OS毎に通信方法こそ違うものの、同じフォーマットのQuery StringでやりとりするAPIがあります。
それが”MESSAGE ユーザー名 本文”とか、”CALL ユーザー名”です。
messageという関数を呼び出すとmethod_missingによってexec “MESSAGE ~~”になるわけですね
これだけの実装です
module Skype
def self.method_missing(name, *args)
self.exec "#{name.upcase} #{args.join(' ')}"
end
def self.exec(command)
Appscript.app("skype").send_ :script_name => self.config[:app_name], :command => command
end
end
実際には、LinuxとMacでSkype.execの中の実装がわかれています。
返り値がまだ全部Stringなので、SEARCH RECENTCHATSとかGET CHATMESSAGEとかを自分でparseしないとならないのがつらい。そのうちなんとかする。