Skip to content

Instantly share code, notes, and snippets.

@thinkAmi
Created June 5, 2014 20:46
Show Gist options
  • Save thinkAmi/b9360d1d01f17fc4db27 to your computer and use it in GitHub Desktop.
Save thinkAmi/b9360d1d01f17fc4db27 to your computer and use it in GitHub Desktop.
Windows + Skype + Ruby(win32ole) で、Skypeを操作するサンプル
# Tested Environment
# - Windows7 x64
# - Skype 6.16.0.105
#
# Thanks
# Sunitha/SkypeShell https://github.com/Sunitha/SkypeShell
require "win32ole"
# 拡張して、to_aを実装しとく
class WIN32OLE
def sort
ole_methods.join("\t").split("\t").sort
end
def to_a
Array.new.tap do |array|
self.each {|o| array.push o}
end
end
end
class Skype
def initialize
@skype = WIN32OLE.new 'Skype4COM.Skype'
@skype.Attach
end
def current_user_status
puts "status : #{@skype.CurrentUserStatus}"
end
def command
# 動作しそうなんだけれど、確認できてない
# ヘルプよりVBでの実装
# oSkype.SendCommand(oSkype.Command(4, "GET USER echo123 FULLNAME", "USER echo123 FULLNAME", True))
# 似た感じで実装
# @skype.SendCommand(@skype.Command(4, "GET USER echo123 FULLNAME", "USER echo123 FULLNAME", true))
end
def show_all_chats
show_chats(all_chats)
end
def show_recent_chats
show_chats(recent_chats)
end
def show_message(chat_name, all='')
condition = all.empty? ? ->(x){ x.unread? } : ->(x){ x.text_message? }
chat = find_chat(chat_name)
unless chat.nil?
chat.show_messages(condition)
else
p "Cannot read : #{chat_name}"
end
end
def seen(chat_name)
chat = find_chat(chat_name)
unless chat.nil?
chat.seen
else
p "Cannot see: #{chat_name}"
end
end
def send(chat_name, message)
chat = find_chat(chat_name)
unless chat.nil?
chat.send(message)
else
p "Cannot send #{chat_name} - #{message}"
end
end
def method_missing(meth, *args)
@message.__send__(meth, *args)
end
private
def all_chats
@skype.Chats.to_a.map{|c| Chat.new(c)}
end
def recent_chats
@skype.RecentChats.to_a.map{|c| Chat.new(c)}
end
def find_chat(chat_name)
# 最近のチャットリストを取れない場合は、全チャットリストから検索する
chats = recent_chats
chats = all_chats if chats.size == 0
i = chats.index { |c| c.name == chat_name }
chats[i]
end
def show_chats(chats)
chats.each_with_index {|chat, i| puts "#{i} : #{chat.name}" }
end
end
class Chat
def initialize(chat)
@chat = chat
end
def name
@chat.FriendlyName
rescue
""
end
def messages
@chat.Messages.to_a.map{|m| Message.new(m)}
end
def show_messages(condition)
messages.reverse.each do |message|
if condition.call(message)
p "#{@chat.Name} #{message.Type} #{message.Role} #{message.Status} #{message.Body} #{message.TimeStamp}"
end
end
end
def send(msg)
@chat.SendMessage(msg)
p "sent #{msg}"
end
def seen
msgs = messages.reverse.select(&:unread?)
msgs.each(&:seen)
end
end
class Message
# 手元で確認できたstatus
STATUS = {
unreceived: 1,
unread: 2,
already_read: 3
}
# 手元で確認できたtype
TYPE = {
unknown: -1,
what: 1,
text: 4,
attachment: 6
}
def initialize(message)
@message = message
end
def unread?
@message.Status == STATUS[:unread] && text_message?
end
def text_message?
@message.Type == TYPE[:text]
end
def seen
# 既読にするには、プロパティにセットすれば良い
# ヘルプのMissedMessages.vbsを参照
@message.Seen = true
p "Seen: #{ @message.Body }"
end
def method_missing(meth, *args)
@message.__send__(meth, *args)
end
end
CHAT_NAME = 'example'
skype = Skype.new
# 送れそうなんだけど、結果が返ってこない
# puts skype.command
# ステータスの取得
puts skype.current_user_status
# 最近のチャットのリストを表示する
skype.show_recent_chats
# 全チャットのリストを表示する
skype.show_all_chats
# 指定したチャットにおいて、未読のメッセージを表示する
skype.show_message(CHAT_NAME)
# 指定したチャットにおいて、未読のメッセージを既読にする
skype.seen(CHAT_NAME)
# 指定したチャットにおいて、メッセージを送る
skype.send(CHAT_NAME, 'hello world')
# 指定したチャットのすべてのメッセージを表示する
skype.show_message(CHAT_NAME, :all)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment