Class: Msn::NotificationServer
- Inherits:
-
EventMachine::Connection
- Object
- EventMachine::Connection
- Msn::NotificationServer
show all
- Includes:
- Protocol
- Defined in:
- lib/msn/notification_server.rb
Overview
Constant Summary
collapse
- ContactsNamespace =
{'ns' => 'http://www.msn.com/webservices/AddressBook'}
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Protocol
#answer_challenge, #clear_event, #handle_event, #handle_normal_command, #handle_payload_command, #method_missing, #on_event, #receive_binary_data, #receive_line, #send_command, #send_command_internal, #send_payload_command, #send_payload_command_and_wait
Constructor Details
Returns a new instance of NotificationServer.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# File 'lib/msn/notification_server.rb', line 10
def initialize(messenger)
@messenger = messenger
@guid = Guid.new.to_s
@switchboards = {}
@message_id = 1
@message_ids = {}
on_event 'ADL' do |, data|
data = Nokogiri::XML(data)
domain = data.xpath('//ml/d').first['n']
c = data.xpath('//ml/d/c').first
username = c['n']
display_name = c['f']
messenger.contact_request "#{username}@#{domain}", display_name
end
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
in the class Msn::Protocol
Instance Attribute Details
#guid ⇒ Object
Returns the value of attribute guid.
8
9
10
|
# File 'lib/msn/notification_server.rb', line 8
def guid
@guid
end
|
#messenger ⇒ Object
Returns the value of attribute messenger.
7
8
9
|
# File 'lib/msn/notification_server.rb', line 7
def messenger
@messenger
end
|
Instance Method Details
#cache_key_xml ⇒ Object
109
110
111
|
# File 'lib/msn/notification_server.rb', line 109
def cache_key_xml
@cache_key ? "<CacheKey>#{REXML::Text.normalize @cache_key}</CacheKey>" : ""
end
|
#create_switchboard(email, host_and_port) ⇒ Object
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
# File 'lib/msn/notification_server.rb', line 161
def create_switchboard(email, host_and_port)
host, port = host_and_port.split(':')
switchboard = EM.connect host, port, Msn::Switchboard, messenger
switchboard.on_event 'ACK' do ||
notify_ack [1].to_i, :ack
end
switchboard.on_event 'NAK' do ||
notify_ack [1].to_i, :nak
end
switchboard.on_event 'BYE' do ||
destroy_switchboard email if [1] =~ /#{email}/
end
@switchboards[email] = switchboard
end
|
#destroy_switchboard(email) ⇒ Object
176
177
178
179
|
# File 'lib/msn/notification_server.rb', line 176
def destroy_switchboard(email)
switchboard = @switchboards.delete email
switchboard.close_connection if switchboard
end
|
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
# File 'lib/msn/notification_server.rb', line 68
def get_contacts
contacts = {}
xml = Nokogiri::XML(get_soap_contacts.body)
xml.xpath('//ns:Membership', ContactsNamespace).each do |membership|
role = membership.xpath('ns:MemberRole', ContactsNamespace).text
membership.xpath('ns:Members/ns:Member', ContactsNamespace).each do |member|
cid = member.xpath('ns:CID', ContactsNamespace).text
email = member.xpath('ns:PassportName', ContactsNamespace).text
display_name = member.xpath('ns:DisplayName', ContactsNamespace)
contact = contacts[cid] ||= Msn::Contact.new(email, display_name ? display_name.text : nil)
case role
when 'Allow' then contact.allow = true
when 'Block' then contact.block = true
when 'Reverse' then contact.reverse = true
when 'Pending' then contact.pending = true
end
end
end
contacts.values
end
|
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
# File 'lib/msn/notification_server.rb', line 92
def get_soap_contacts(url = "https://local-bay.contacts.msn.com/abservice/SharingService.asmx")
msn_get_contacts_template_file = File.expand_path('../soap/msn_get_contacts_template.xml', __FILE__)
msn_get_contacts_template = ERB.new File.read(msn_get_contacts_template_file)
soap = msn_get_contacts_template.result(binding)
RestClient.post url, soap, {
'SOAPAction' => 'http://www.msn.com/webservices/AddressBook/FindMembership',
'Content-Type' => 'text/xml',
}
rescue RestClient::ExceptionWithResponse => ex
xml = Nokogiri::XML(ex.response.body)
cache_key = xml.xpath("//ns:CacheKey", ContactsNamespace).first
@cache_key = cache_key.text if cache_key
get_soap_contacts(ex.response.[:location])
end
|
#login ⇒ Object
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/msn/notification_server.rb', line 119
def login
Fiber.new do
begin
ver "MSNP18", "CVR0"
cvr "0x0409", "winnt", "5.1", "i386", "MSNMSGR", "8.5.1302", "BC01", username
response = usr "SSO", "I", username
if response[0] == "XFR" && response[2] == "NS"
host, port = response[3].split ':'
@reconnect_host, @reconnect_port = response[3].split ':'
close_connection
else
login_to_nexus(response[4], response[5])
end
rescue Msn::AuthenticationError => ex
messenger.login_failed(ex.message)
close_connection
end
end.resume
end
|
#login_to_nexus(policy, nonce) ⇒ Object
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
# File 'lib/msn/notification_server.rb', line 139
def login_to_nexus(policy, nonce)
@nexus = Msn::Nexus.new self, policy, nonce
first_msg = true
on_event('MSG') do
if first_msg
first_msg = false
messenger.ready
end
end
on_event('RNG') do ||
switchboard = create_switchboard [5], [2]
switchboard.ans username_guid, [4], [1]
end
response = usr "SSO", "S", @nexus.sso_token, @nexus.secret, guid
if response[2] != "OK"
raise Msn::AuthenticationError.new("Didn't receive OK from SSO")
end
end
|
#notify_ack(trid, status) ⇒ Object
181
182
183
184
|
# File 'lib/msn/notification_server.rb', line 181
def notify_ack(trid, status)
id = @message_ids.delete(trid)
messenger.accept_message_ack id, status if id
end
|
#password ⇒ Object
64
65
66
|
# File 'lib/msn/notification_server.rb', line 64
def password
messenger.password
end
|
#post_init ⇒ Object
113
114
115
116
117
|
# File 'lib/msn/notification_server.rb', line 113
def post_init
super
login
end
|
#send_message(email, text) ⇒ Object
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
# File 'lib/msn/notification_server.rb', line 32
def send_message(email, text)
message_id = @message_id
@message_id += 1
switchboard = @switchboards[email]
if switchboard
trid = switchboard.send_message text
@message_ids[trid] = message_id
else
Fiber.new do
response = xfr "SB"
switchboard = create_switchboard email, response[3]
switchboard.on_event 'JOI' do
switchboard.clear_event 'JOI'
trid = switchboard.send_message text
@message_ids[trid] = message_id
end
switchboard.usr username_guid, response[5]
cal_response = switchboard.cal email
if cal_response[0] == '217'
messenger.accept_message_ack message_id, :offline
end
end.resume
end
message_id
end
|
#unbind ⇒ Object
186
187
188
189
190
191
192
193
194
|
# File 'lib/msn/notification_server.rb', line 186
def unbind
if @reconnect_host
reconnect @reconnect_host, @reconnect_port.to_i
@reconnect_host = @reconnect_port = nil
login
else
messenger.disconnected
end
end
|
#username ⇒ Object
60
61
62
|
# File 'lib/msn/notification_server.rb', line 60
def username
messenger.username
end
|
#username_guid ⇒ Object
28
29
30
|
# File 'lib/msn/notification_server.rb', line 28
def username_guid
@username_guid ||= "#{messenger.username};{#{guid}}"
end
|