FbRuby 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +876 -0
- data/lib/FbRuby/chats.rb +369 -0
- data/lib/FbRuby/comments.rb +178 -0
- data/lib/FbRuby/createaccount.rb +142 -0
- data/lib/FbRuby/exceptions.rb +25 -0
- data/lib/FbRuby/facebook.rb +453 -0
- data/lib/FbRuby/groups.rb +260 -0
- data/lib/FbRuby/login.rb +297 -0
- data/lib/FbRuby/messenger.rb +272 -0
- data/lib/FbRuby/posts.rb +267 -0
- data/lib/FbRuby/settings.rb +282 -0
- data/lib/FbRuby/tempmail.rb +56 -0
- data/lib/FbRuby/user.rb +550 -0
- data/lib/FbRuby/utils.rb +412 -0
- data/lib/FbRuby.rb +21 -0
- metadata +114 -0
data/lib/FbRuby/chats.rb
ADDED
@@ -0,0 +1,369 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
require_relative 'exceptions.rb'
|
5
|
+
|
6
|
+
module FbRuby
|
7
|
+
# Class Chats di gunakan untuk mengirim pesan, dan menerima pesan
|
8
|
+
class Chats
|
9
|
+
|
10
|
+
# Daftar Nama Stiker Yang Tersedia
|
11
|
+
# Key : Nama Stiker
|
12
|
+
# value: Id Stiker
|
13
|
+
@@stiker_pack = {
|
14
|
+
'smile'=> 529233727538989,
|
15
|
+
'crying'=> 529233744205654,
|
16
|
+
'angry'=> 529233764205652,
|
17
|
+
'heart_eyes'=> 529233777538984,
|
18
|
+
'happy_heart'=>529233794205649,
|
19
|
+
'laugh'=>529233810872314,
|
20
|
+
'fearful'=>529233834205645,
|
21
|
+
'sleeping'=>529233847538977,
|
22
|
+
'grimacing'=>529233954205633,
|
23
|
+
'creazy_face'=>529233967538965,
|
24
|
+
'smiling_face_with_sunglasses'=>529233864205642,
|
25
|
+
'face_with_spiral_eyes'=>529233884205640,
|
26
|
+
'face_blowing_a_kiss'=>529233917538970,
|
27
|
+
'face_vomiting'=>529233937538968,
|
28
|
+
'face_screaming'=>529233980872297,
|
29
|
+
}
|
30
|
+
|
31
|
+
class << self
|
32
|
+
def stiker_pack
|
33
|
+
return @@stiker_pack
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :chats_url, :chat_info
|
38
|
+
|
39
|
+
# inisialisasi Object Chats
|
40
|
+
#
|
41
|
+
# @param chats_url[String] Url Dari Chat
|
42
|
+
# @param request_session[Session] Object Session
|
43
|
+
def initialize(chats_url:, request_session:)
|
44
|
+
@sessions = request_session
|
45
|
+
@url = URI("https://mbasic.facebook.com")
|
46
|
+
@chats_url = URI(chats_url)
|
47
|
+
|
48
|
+
@chats_url.host = @url.host if @chats_url.host != @url.host
|
49
|
+
|
50
|
+
@req = @sessions.get_without_sessions(@chats_url)
|
51
|
+
@res = @req.parse_html
|
52
|
+
@chat_info = {"name"=>nil,"id"=>nil,"chat_id"=>nil,"chats_url"=>@chats_url.to_s,"chat_type"=>"unknow","blocked"=>"unknow"}
|
53
|
+
@data_other = {}
|
54
|
+
@skip_data = ['searech', 'search_source','query', 'like', 'send_photo','unread', 'delete', 'delete_selected', 'archive', 'ignore_messages', 'block_messages', 'message_frx','unarchive','unblock_messages','add_people','leave_conversation',nil]
|
55
|
+
@message_form = @res.at_xpath("//form[starts-with(@action, \"/messages/send\")]")
|
56
|
+
@message_data = {}
|
57
|
+
|
58
|
+
unless @res.at_xpath("//a[starts-with(@href,'/messages/compose')]").nil?
|
59
|
+
@chat_info['name'] = @res.at_xpath("//input[@type = 'hidden'and starts-with(@name,'text_ids')]")['value']
|
60
|
+
else
|
61
|
+
@chat_info['name'] = @res.at_css('title').text
|
62
|
+
end
|
63
|
+
|
64
|
+
unless @message_form.nil?
|
65
|
+
@message_form.xpath("//input[@type=\"hidden\"]").each{|i| @message_data.update({i['name']=>i['value']})}
|
66
|
+
message_submit = @message_form.at_xpath("//*[@type=\"submit\" and @name=\"send\"]")
|
67
|
+
@message_data[message_submit['value']] = "submit" unless message_submit.nil?
|
68
|
+
@message_data.each do |k,v|
|
69
|
+
if k.match(/^ids\[\d+\]/)
|
70
|
+
@chat_info['id'] = v
|
71
|
+
break
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
@messages_redirect_form = @res.at_css("form[action^='/messages/action_redirect']")
|
77
|
+
@messages_redirect_data = {}
|
78
|
+
unless @messages_redirect_form.nil?
|
79
|
+
@messages_redirect_form.css("input").each{|i| @messages_redirect_data.update({i['name']=>i['value']})}
|
80
|
+
tid = CGI.unescape(@messages_redirect_form['action']).match(/tid=cid\.(.?)\.((\d+:\d+)|\d+)/)
|
81
|
+
@chat_info['chat_id'] = tid[2] unless tid.nil?
|
82
|
+
@chat_info['chat_type'] = (@messages_redirect_data.include? ('leave_conversation') or @messages_redirect_form['action'].include? ('cid.g.')) ? "group" : "user"
|
83
|
+
@chat_info['blocked'] = @messages_redirect_data.include? ('unblock_messages')
|
84
|
+
end
|
85
|
+
|
86
|
+
@res.css('input[type="submit"]').each{|i| @data_other.update({i['name']=>i['value']}) if @skip_data.include? (i['name'])}
|
87
|
+
@message_data.delete_if {|k,v| k.nil? or v.nil? or @skip_data.include? (k)}
|
88
|
+
@link_stiker = @res.at_xpath("//a[starts-with(@href,\"/messages/sticker_picker/\")]")
|
89
|
+
end
|
90
|
+
|
91
|
+
# Mengembalikan string representasi dari objek Chats.
|
92
|
+
#
|
93
|
+
# @return [String] Representasi string dari objek Chats.
|
94
|
+
def to_s
|
95
|
+
return "Facebook Chats : name=#{@chat_info['name'].inspect} id=#{@chat_info['id'].inspect} chat_id=#{@chat_info['chat_id'].inspect} chat_type=#{@chat_info['chat_type'].inspect}"
|
96
|
+
end
|
97
|
+
|
98
|
+
# Mengembalikan string representasi dari objek Chats.
|
99
|
+
#
|
100
|
+
# @return [String] Representasi string dari objek Chats.
|
101
|
+
def inspect
|
102
|
+
return self.to_s
|
103
|
+
end
|
104
|
+
|
105
|
+
# Perbarui halaman
|
106
|
+
def refresh
|
107
|
+
initialize(chats_url: @chats_url, request_session: @sessions)
|
108
|
+
end
|
109
|
+
|
110
|
+
def [](item)
|
111
|
+
return @chat_info[item]
|
112
|
+
end
|
113
|
+
|
114
|
+
def method_missing(method_name, *args)
|
115
|
+
key = method_name.to_s
|
116
|
+
if @chat_info.key?(key)
|
117
|
+
return @chat_info[key]
|
118
|
+
else
|
119
|
+
super
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def respond_to_missing?(method_name, include_private = false)
|
124
|
+
@chat_info.key?(method_name.to_s) || super
|
125
|
+
end
|
126
|
+
|
127
|
+
# Mendapatkan chat dari url
|
128
|
+
#
|
129
|
+
# @param chats_url[String] Chat url
|
130
|
+
# @return [Hash] method ini akan mengembalikan Hash yang memuat informasi chat
|
131
|
+
def get_messages(chats_url)
|
132
|
+
data = {"chat"=>[], "previous_chats"=>nil}
|
133
|
+
|
134
|
+
@req = @sessions.get(chats_url)
|
135
|
+
@res = @req.parse_html
|
136
|
+
prev_msg = @res.at_css('div#see_older')
|
137
|
+
msg = @res.at_css('div#messageGroup')
|
138
|
+
|
139
|
+
return data if msg.nil?
|
140
|
+
|
141
|
+
unless prev_msg.nil?
|
142
|
+
data['previous_chats'] = URI.join(@url,prev_msg.at_css('a')['href']).to_s
|
143
|
+
prev_msg.remove
|
144
|
+
end
|
145
|
+
|
146
|
+
for moya in msg.css('div div a')
|
147
|
+
echaa = moya.parent
|
148
|
+
next if echaa.nil?
|
149
|
+
profile = echaa.at_css('a')
|
150
|
+
next unless profile['href'].match(/^\/([a-zA-Z0-9_.-]+|profile\.php)\?/)
|
151
|
+
|
152
|
+
username = profile['href'].match(/^\/([a-zA-Z0-9_.-]+)\?/)
|
153
|
+
chat_data = {"name"=>profile.text,"username"=>(username[1] if !username.nil? and !profile['href'].include?('profile.php')),"message"=>[],"file"=>[],"stiker"=>[],"time"=>nil}
|
154
|
+
|
155
|
+
for pesan in echaa.css('span')
|
156
|
+
next if (!pesan['class'].nil? or !pesan['aria-hidden'].nil? or !pesan['style'].nil? or pesan.text.empty?)
|
157
|
+
chat_data['message'] << pesan.text.strip
|
158
|
+
end
|
159
|
+
|
160
|
+
for file in echaa.css('a[href^="/messages/attachment_preview/"], a[href^="/video_redirect"]')
|
161
|
+
files = {"link"=>nil,"id"=>nil,"file_size"=>nil,"preview"=>nil,"content_type"=>nil,"content_length"=>nil}
|
162
|
+
get_id = lambda {|url| x = url.match(/(\d+_\d+_\d+)/); return ((!x.nil?) ? x[0] : nil)}
|
163
|
+
|
164
|
+
files['link'] = (file['href'].include?('/messages/attachment_preview')) ? file.at_css('img')['src'] : CGI.unescape(file['href']).match(/src=(.*)/)[1]
|
165
|
+
files['id'] = get_id.call(files['link'])
|
166
|
+
file_head = @sessions.head(files['link']).headers
|
167
|
+
files['file_size'] = (file_head.member?(:content_length)) ? FbRuby::Utils::convert_file_size(file_head[:content_length].to_i) : nil
|
168
|
+
files['preview'] = URI.join(@url, file['href']).to_s
|
169
|
+
files['content_type'] = file_head[:content_type]
|
170
|
+
files['content_length'] = file_head[:content_length].to_i
|
171
|
+
chat_data['file'] << files
|
172
|
+
end
|
173
|
+
|
174
|
+
for stiker in echaa.css('img')
|
175
|
+
next if (stiker['alt'].nil? or stiker['class'].nil?)
|
176
|
+
chat_data['stiker'] << {"stiker_name"=>stiker['alt'], "stiker_url"=>stiker['src']}
|
177
|
+
end
|
178
|
+
|
179
|
+
waktu = echaa.parent.at_css('abbr')
|
180
|
+
chat_data['time'] = waktu.text unless waktu.nil?
|
181
|
+
|
182
|
+
data['chat'] << chat_data
|
183
|
+
end
|
184
|
+
return data
|
185
|
+
end
|
186
|
+
|
187
|
+
# Mendapatkan pesan di chat (Tanpa Url)
|
188
|
+
#
|
189
|
+
# @param limit [Integer] Jumblah maksimal pesan yang ingin di dapatkan
|
190
|
+
# return[Array<Hash>] Method ini akan mengembalikan Array yang di dalam nya ada Hash yanb memuat daftar percakapan
|
191
|
+
def get_message(limit)
|
192
|
+
pesan = []
|
193
|
+
url = self['chats_url']
|
194
|
+
|
195
|
+
while pesan.length < limit
|
196
|
+
dump = get_messages(url)
|
197
|
+
pesan.concat(dump['chat'])
|
198
|
+
break if dump['previous_chats'].nil?
|
199
|
+
url = dump['previous_chats']
|
200
|
+
end
|
201
|
+
|
202
|
+
return pesan[0...limit]
|
203
|
+
end
|
204
|
+
|
205
|
+
# Kirim Pesan Teks
|
206
|
+
#
|
207
|
+
# @param message[String] Pesan yang akan di kirim
|
208
|
+
# @return [Boolean] Method ini akan mengembalikan true jika berhasil mengirim pesan
|
209
|
+
def send_text(message)
|
210
|
+
raise FbRuby::Exceptions::FacebookError.new("Tidak dapat mengirim pesan ke #{self.name} di karenakan anda telah memblokir akun tersebut!!!") if self.blocked == true
|
211
|
+
raise FbRuby::Exceptions::FacebookError.new("Tidak dapat mengirim pesan ke #{self.name} :(") if @message_form.nil?
|
212
|
+
raise FbRuby::Exceptions::FacebookError.new("Panjang pesan minimal 1 karakter, dan harus di awali dengan non-white space character!") if message.strip.empty?
|
213
|
+
|
214
|
+
data = @message_data.clone
|
215
|
+
data.update({'body'=>message})
|
216
|
+
kirim = @sessions.post(URI.join(@url,@message_form['action']), data = data)
|
217
|
+
return kirim.ok?
|
218
|
+
end
|
219
|
+
|
220
|
+
# Kirim Pesan & Foto
|
221
|
+
#
|
222
|
+
# @param file[Array<String>, String] Lokasi Dari File Foto
|
223
|
+
# @param message[String] Pesan yang akan di sertakan saat mengirim foto
|
224
|
+
# @return [Boolean] Method ini akan mengembalikan true jika berhasil mengirim pesan
|
225
|
+
# @example Kirim 1 foto
|
226
|
+
# chat.send_images("fotoku.jpg","Pesan")
|
227
|
+
# @example Kirim lebih dari 1 foto
|
228
|
+
# chat.send_images(["foto1.jpg","foto2.jpg"], "Pesan")
|
229
|
+
def send_images(file, message = nil)
|
230
|
+
raise FbRuby::Exceptions::FacebookError.new("Tidak dapat mengirim pesan ke #{self.name} di karenakan anda telah memblokir akun tersebut!!!") if self.blocked == true
|
231
|
+
raise FbRuby::Exceptions::FacebookError.new("Tidak dapat mengirim pesan ke #{self.name} :(") if @message_form.nil?
|
232
|
+
|
233
|
+
forms = @res.at_css('form[action^="https://"][action*="z-upload.facebook.com"], form[action^="https://"][action*="upload.facebook.com"]')
|
234
|
+
|
235
|
+
if forms.nil?
|
236
|
+
data = @message_data.clone
|
237
|
+
data.delete(data.keys[data.values.index("submit")]) if data.values.include? ("submit")
|
238
|
+
data.update({'send_photo'=> @data_other['send_photo']})
|
239
|
+
moya = @sessions.post(URI.join(@url, @message_form['action']), data = data)
|
240
|
+
forms = moya.parse_html.at_css('form[action^="https://"][action*="z-upload.facebook.com"], form[action^="https://"][action*="upload.facebook.com"]')
|
241
|
+
end
|
242
|
+
|
243
|
+
forms_data = {'body'=>message.to_s}
|
244
|
+
forms.css('input[type="hidden"]').each{|i| forms_data.update({i['name']=>i['value']})}
|
245
|
+
|
246
|
+
begin
|
247
|
+
return FbRuby::Utils::upload_photo(@sessions, forms['action'], files = file, data = forms_data).last.ok?
|
248
|
+
rescue FbRuby::Exceptions::PageNotFound
|
249
|
+
return true
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
# Kirim Stiker Dengan ID
|
254
|
+
#
|
255
|
+
# @param sticker_id[String] Id dari Sticker
|
256
|
+
# @return [Boolean] Method ini akan mengembalikan true jika berhasil mengirim stiker
|
257
|
+
def send_stickers(sticker_id)
|
258
|
+
raise FbRuby::Exceptions::FacebookError.new("Tidak dapat mengirim stiker ke \"#{self['name']}\" :(") if @link_stiker.nil?
|
259
|
+
stiker_form = @sessions.get_without_sessions(URI.join(@url,@link_stiker['href'])).parse_html.at_css("form[action^=\"/messages/send\"]")
|
260
|
+
data = {'sticker_id'=>sticker_id.to_s}
|
261
|
+
stiker_form.css('input[type="hidden"]').each{|i| data.update({i['name']=>i['value']})}
|
262
|
+
kirim = @sessions.post(URI.join(@url,stiker_form['action']), data = data)
|
263
|
+
|
264
|
+
return kirim.ok?
|
265
|
+
end
|
266
|
+
|
267
|
+
# Kirim Stiker Dengan Nama
|
268
|
+
#
|
269
|
+
# @param stiker_name[String] Nama Dari Stiker
|
270
|
+
# @return [Boolean] Method ini akan mengembalikan true jika berhasil mengirim stiker
|
271
|
+
def send_sticker(stiker_name)
|
272
|
+
stiker_name.downcase!
|
273
|
+
if stiker_name == 'like'
|
274
|
+
data = @message_data.clone
|
275
|
+
data.update({'like'=>@res.at_xpath("//input[@name=\"like\"]")['value']})
|
276
|
+
kirim = @sessions.post(URI.join(@url,@message_form['action']), data = data)
|
277
|
+
|
278
|
+
return kirim.ok?
|
279
|
+
else
|
280
|
+
raise FbRuby::Exceptions::FacebookError.new("Stiker dengan nama #{stiker_name} tidak di temukan") unless @@stiker_pack.member?(stiker_name)
|
281
|
+
send_stickers(@@stiker_pack[stiker_name])
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
# Alias Untuk Mengirim Stiker Suka
|
286
|
+
#
|
287
|
+
# @return [Boolean] Method ini akan mengembalikan true jika berhasil mengirim stiker
|
288
|
+
def send_like_stiker
|
289
|
+
send_sticker('like')
|
290
|
+
end
|
291
|
+
|
292
|
+
# Tandai Chat Sebagai Belum Di Baca
|
293
|
+
#
|
294
|
+
# @return [Boolean]
|
295
|
+
def mark_as_unread
|
296
|
+
chat_action('unread')
|
297
|
+
end
|
298
|
+
|
299
|
+
# Arsip Chat
|
300
|
+
#
|
301
|
+
# @return [Boolean]
|
302
|
+
def archive_chat
|
303
|
+
chat_action('archive')
|
304
|
+
end
|
305
|
+
|
306
|
+
# Batalkan Pengarsipan Chat
|
307
|
+
#
|
308
|
+
# @return [Boolean]
|
309
|
+
def unarchive_chat
|
310
|
+
chat_action('unarchive')
|
311
|
+
end
|
312
|
+
|
313
|
+
# Hapus Semua Pesan
|
314
|
+
#
|
315
|
+
# @return [Boolean]
|
316
|
+
def delete_chat
|
317
|
+
chat_action_with_confirm('delete', '/messages/action/?mm_action=delete')
|
318
|
+
end
|
319
|
+
|
320
|
+
# Abaikan chat / Bisukan Pesan Ini
|
321
|
+
#
|
322
|
+
# @return [Boolean]
|
323
|
+
def ignore_chat
|
324
|
+
chat_action_with_confirm('ignore_messages', '/nfx/ignore_messages/confirm/')
|
325
|
+
end
|
326
|
+
|
327
|
+
# Blokir Chat
|
328
|
+
#
|
329
|
+
# @return [Boolean]
|
330
|
+
def block_chat
|
331
|
+
chat_action_with_confirm('block_messages', '/nfx/block_messages/confirm/')
|
332
|
+
end
|
333
|
+
|
334
|
+
# Buka Blokir Chat
|
335
|
+
#
|
336
|
+
# @return [Boolean]
|
337
|
+
def unblock_chat
|
338
|
+
chat_action_with_confirm('unblock_messages', '/nfx/unblock_messages/confirm/')
|
339
|
+
end
|
340
|
+
|
341
|
+
private
|
342
|
+
def chat_action(action)
|
343
|
+
if !@messages_redirect_data.nil? && @messages_redirect_data.member?(action)
|
344
|
+
data = {}
|
345
|
+
@messages_redirect_form.css("input[type = 'hidden']").each{|i| data[i['name']] = i['value']}
|
346
|
+
data[action] = @messages_redirect_data[action]
|
347
|
+
submit = @sessions.post(URI.join(@url,@messages_redirect_form['action']), data = data)
|
348
|
+
|
349
|
+
if block_given?
|
350
|
+
yield(submit)
|
351
|
+
else
|
352
|
+
return submit.ok?
|
353
|
+
end
|
354
|
+
else
|
355
|
+
return false
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def chat_action_with_confirm(action, url_confirm)
|
360
|
+
chat_action(action) do |res|
|
361
|
+
url = URI.join(@url, res.parse_html.at_css("a[href^='#{url_confirm}']")['href'])
|
362
|
+
confirm = @sessions.get_without_sessions(url)
|
363
|
+
|
364
|
+
return confirm.ok?
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
end
|
369
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require_relative 'utils.rb'
|
3
|
+
require_relative 'posts.rb'
|
4
|
+
require_relative 'exceptions.rb'
|
5
|
+
|
6
|
+
module FbRuby
|
7
|
+
# clsss Comments di gunakan untuk membaca dan membalas komentar
|
8
|
+
class Comments
|
9
|
+
|
10
|
+
attr_reader :author, :username, :comment_text, :user_tag, :media, :time
|
11
|
+
|
12
|
+
# Inisialisasi Object Comments
|
13
|
+
#
|
14
|
+
# @param nokogiriObj[Object] Object dari tag Nokogiri
|
15
|
+
# @param request_session [Session] Object Session
|
16
|
+
def initialize(nokogiriObj:, request_session:)
|
17
|
+
@html = nokogiriObj
|
18
|
+
@url = URI("https://mbasic.facebook.com/")
|
19
|
+
@sessions = request_session
|
20
|
+
@author = @html.at_css("h3 a[href*='profile.php?id='], h3 a")
|
21
|
+
@username = nil
|
22
|
+
@comment_text = @html.at_css("h3")
|
23
|
+
@user_tag = []
|
24
|
+
@media = {}
|
25
|
+
@time = @html.at_css("abbr")
|
26
|
+
@time = @time.text unless @time.nil?
|
27
|
+
|
28
|
+
unless @author.nil?
|
29
|
+
usr = @author['href'].match(/^\/(([a-zA-Z0-9_.-]+)\?eav|profile\.php\?id=(\d+))/)
|
30
|
+
@username = (@author['href'].include?('profile.php') ? usr[3] : usr[2]) unless usr.nil?
|
31
|
+
@author = @author.text
|
32
|
+
end
|
33
|
+
|
34
|
+
unless @comment_text.nil?
|
35
|
+
@comment_text = @comment_text.next_element
|
36
|
+
for com in @comment_text.css('a')
|
37
|
+
next unless com['class'].nil?
|
38
|
+
u = com['href'].match(/^\/(([a-zA-Z0-9_.-]+)\?eav|profile\.php\?id=(\d+))/)
|
39
|
+
u = com['href'].include?('profile.php') ? u[3] : u[2]
|
40
|
+
@user_tag << {"name"=>com.text,"username"=>u}
|
41
|
+
end
|
42
|
+
@comment_text.css("br").each{|i| i.replace("\n")}
|
43
|
+
@comment_text = @comment_text.text
|
44
|
+
end
|
45
|
+
|
46
|
+
@video = @html.at_css("a[href^='/video_redirect']")
|
47
|
+
@image = @html.at_css("a[href^='/photo.php']")
|
48
|
+
|
49
|
+
unless @video.nil?
|
50
|
+
vidData = {"link"=>nil,"id"=>nil,"preview"=>nil,"content-type"=>"video"}
|
51
|
+
vidUrl = URI.decode_www_form_component(@video['href']).match(/src=(.*)/)
|
52
|
+
preview = @video.at_css('img')
|
53
|
+
|
54
|
+
unless vidUrl.nil?
|
55
|
+
vidData['link'] = vidUrl[1]
|
56
|
+
vidData['id'] = vidUrl[1].match(/&id=(\d+)/)[1]
|
57
|
+
end
|
58
|
+
|
59
|
+
vidData['preview'] = preview['src'] unless preview.nil?
|
60
|
+
@media.update(vidData)
|
61
|
+
end
|
62
|
+
|
63
|
+
unless @image.nil?
|
64
|
+
imgData = {"link"=>nil,"id"=>nil,"preview"=>nil,"content-type"=>"image"}
|
65
|
+
imgUrl = URI.join(@url, @image['href'])
|
66
|
+
thubmnail = @image.at_css('img')
|
67
|
+
fullPhoto = @sessions.get(imgUrl).parse_html.at_css("img[src^='https://scontent'], img[src^='https://z-m-scontent']")
|
68
|
+
imgData["link"] = fullPhoto['src'] unless fullPhoto.nil?
|
69
|
+
imgData["id"] = fullPhoto['src'].match(/(\d+_\d+_\d+)/)[1] unless fullPhoto.nil?
|
70
|
+
imgData["preview"] = thubmnail['src'] unless thubmnail.nil?
|
71
|
+
@media.update(imgData)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Mengembalikan string representasi dari objek Comments.
|
76
|
+
#
|
77
|
+
# @return [String] Representasi string dari objek Comments.
|
78
|
+
def to_s
|
79
|
+
return "Facebook Comments : author=#{@author} username=#{@username} comment_text=#{@comment_text} user_tag=#{@user_tag} time=#{@time}"
|
80
|
+
end
|
81
|
+
|
82
|
+
# Mengembalikan string representasi dari objek Comments.
|
83
|
+
#
|
84
|
+
# @return [String] Representasi string dari objek Comments.
|
85
|
+
def inspect
|
86
|
+
return to_s
|
87
|
+
end
|
88
|
+
|
89
|
+
# Membalas Komentar
|
90
|
+
#
|
91
|
+
# @param message [String] Balasan dari komentar
|
92
|
+
# @return[Boolean] Mengembalikan true jika berhasil membalas komentar
|
93
|
+
def reply(message)
|
94
|
+
replyUrl = @html.at_css("a[href^='/comment/replies']")
|
95
|
+
raise FbRuby::Exceptions::FacebookError.new("Tidak dapat membalas komentar ini:(") if replyUrl.nil?
|
96
|
+
html = @sessions.get(URI.join(@url, replyUrl['href'])).parse_html
|
97
|
+
form = html.at_css("form[action^='/a/comment.php']")
|
98
|
+
formData = {"comment_text"=>message}
|
99
|
+
form.css("input[type='hidden'][name][value]").each{|i| formData[i['name']] = i['value']}
|
100
|
+
balas = @sessions.post(URI.join(@url, form['action']), data = formData)
|
101
|
+
|
102
|
+
return balas.ok?
|
103
|
+
end
|
104
|
+
|
105
|
+
# Berikan Reaksi Ke Komentar
|
106
|
+
#
|
107
|
+
# @param react_type[String] Jenis Reaksi
|
108
|
+
# List reaksi yang bisa di gunakan
|
109
|
+
# - like
|
110
|
+
# - love
|
111
|
+
# - care
|
112
|
+
# - haha
|
113
|
+
# - wow
|
114
|
+
# - sad
|
115
|
+
# - angry
|
116
|
+
# @return [Boolean]
|
117
|
+
def send_react(react_type)
|
118
|
+
react_type.downcase!
|
119
|
+
react_list = FbRuby::Posts.REACT_LIST
|
120
|
+
react_url = @html.at_css("a[href^='/reactions/picker']")
|
121
|
+
raise FbRuby::Exceptions::FacebookError.new("Invalid React Type!!!") if !react_list.include?(react_type)
|
122
|
+
raise FbRuby::Exceptions::FacebookError.new("Tidak dapat memberikan react ke komentar ini:(") if react_url.nil?
|
123
|
+
html = @sessions.get(URI.join(@url, react_url['href'])).parse_html
|
124
|
+
react = html.xpath("//a[starts-with(@href,'/ufi/reaction')]")
|
125
|
+
|
126
|
+
begin
|
127
|
+
send = @sessions.get_without_sessions(URI.join(@url,react[react_list.index(react_type)]['href']))
|
128
|
+
return send.ok?
|
129
|
+
rescue RestClient::NotFound
|
130
|
+
return true
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Dapatkan balasan dari komentar
|
135
|
+
#
|
136
|
+
# @param limit [Integer] Limit maksimal balasan yang akan di ambil
|
137
|
+
# @return [Array<Comments>, C]
|
138
|
+
def get_reply(limit = 10)
|
139
|
+
balasanList = []
|
140
|
+
balasan = @html.at_xpath("//a[starts-with(@href,'/comment/replies') and contains(@href,'count')]")
|
141
|
+
|
142
|
+
unless balasan.nil?
|
143
|
+
html = @sessions.get(URI.join(@url,balasan['href'])).parse_html
|
144
|
+
for i in html.css("h3:not([class])")[1...]
|
145
|
+
div_comment = i.ancestors('div[class][id]').find { |div| div['id'] =~ /^\d+$/ }
|
146
|
+
div_comment = i.ancestors.css('div:not([class]):not([id]:not([role]))')[2] if div_comment.nil?
|
147
|
+
next if div_comment.nil?
|
148
|
+
balasanList << FbRuby::Comments.new(nokogiriObj: div_comment, request_session: @sessions)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
return balasanList
|
153
|
+
end
|
154
|
+
|
155
|
+
# Mendapatkan jumblah react yang di berikan terhadap komentar ini
|
156
|
+
#
|
157
|
+
# @return[Hash] mengembalikan Hash yang memuat informasi jenis react dan jumblah react
|
158
|
+
def get_react
|
159
|
+
reactData = {}
|
160
|
+
FbRuby::Posts.REACT_LIST.each{|i| reactData[i] = 0}
|
161
|
+
ufi = @html.at_css("a[href^='/ufi/reaction/profile']")
|
162
|
+
|
163
|
+
unless ufi.nil?
|
164
|
+
html = @sessions.get(URI.join(@url, ufi['href'])).parse_html
|
165
|
+
reactUrl = html.xpath("//a[starts-with(@href,'/ufi/reaction/profile') and contains(@href,'total_count') and contains(@href,'reaction_type')]")
|
166
|
+
reactUrl.each do |f|
|
167
|
+
total = (f['href'].match(/total_count=(\d+)/)[1]).to_i
|
168
|
+
type = f['href'].match(/reaction_type=(\d+)/)[1]
|
169
|
+
next unless FbRuby::Posts.REACT_TYPE.include?(type)
|
170
|
+
reactData[FbRuby::Posts.REACT_TYPE[type]] = total
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
return reactData
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'date'
|
3
|
+
require_relative 'utils.rb'
|
4
|
+
require_relative 'login.rb'
|
5
|
+
require_relative 'exceptions.rb'
|
6
|
+
|
7
|
+
module FbRuby
|
8
|
+
# class CreateAccount di gunakan untuk membuat akun facebook baru
|
9
|
+
class CreateAccount < FbRuby::Login::Cookie_Login
|
10
|
+
|
11
|
+
# Inisialisasi Object CreateAccount
|
12
|
+
#
|
13
|
+
# @param firstname[String] Nama Depan
|
14
|
+
# @param lastname[String] Nama Belakang
|
15
|
+
# @param email[String] Email atau nomor handphone yang di gunakan untuk mendaftar akun facebook
|
16
|
+
# @param gender[String] Jenis Kelamin
|
17
|
+
# @param date_of_birth[String<DateTime>, DateTime] Tanggal lahir, untuk format tanggal lahir nya adalah dd/mm/yyyy
|
18
|
+
# @param password[String] Kata Sandi Akun Facebook
|
19
|
+
# @param headers[Hash] Headers yang akan di gunakan untuk melakukan request saat pembuatan akun
|
20
|
+
# @param save_login[Boolean] Simpan informasi login
|
21
|
+
# @param free_facebook[Boolean] Gunakan Facebook Versi Gratis
|
22
|
+
def initialize(firstname:, lastname:, email:, gender:, date_of_birth:, password:, headers: {}, save_login: true, free_facebook: false)
|
23
|
+
@firstname = firstname
|
24
|
+
@lastname = lastname
|
25
|
+
@email = email
|
26
|
+
@gender = gender.downcase
|
27
|
+
@date_of_birth = (date_of_birth.kind_of?(DateTime) ? date_of_birth : DateTime.strptime(date_of_birth,"%d/%m/%Y"))
|
28
|
+
@password = password
|
29
|
+
@headers = headers
|
30
|
+
@save_login = save_login
|
31
|
+
@free_facebook = free_facebook
|
32
|
+
@url = URI("https://mbasic.facebook.com/")
|
33
|
+
@sessions = FbRuby::Utils::Session.new(@headers)
|
34
|
+
|
35
|
+
gender_value = {'female'=>'1','male'=>'2','custom'=>'-1'}
|
36
|
+
html = @sessions.get(@url).parse_html
|
37
|
+
err_req = html.at_css("div[class][id = 'root'][role = 'main']")
|
38
|
+
signup_form = html.at_css("form[action^='/login/device-based/regular']")
|
39
|
+
|
40
|
+
if !err_req.nil? and signup_form.nil?
|
41
|
+
err_div = err_req.at_css("div[class]")
|
42
|
+
raise FbRuby::Exceptions::FacebookError.new(err_div.text)
|
43
|
+
end
|
44
|
+
|
45
|
+
signup_data = {"sign_up"=>"Submit"}
|
46
|
+
signup_form.css("input[type = 'hidden']").each{|i| signup_data[i['name']] = i['value']}
|
47
|
+
signup_value = signup_form.at_css("input[name = 'sign_up'][type = 'submit']")
|
48
|
+
raise FbRuby::Exceptions::FacebookError.new('Untuk Saat ini fitur \"CreateAccount\" tidak mendukung pada facebook mobile, untuk mengatasi masalah ini coba ganti User-Agent yang sedang anda gunakan :)') if signup_value.nil?
|
49
|
+
reg_html = @sessions.post(URI.join(@url, signup_form['action']), signup_data).parse_html
|
50
|
+
reg_form = reg_html.at_css("form[action*='reg/submit']")
|
51
|
+
reg_data = {}
|
52
|
+
reg_form.css("input[type = 'hidden']").each{|i| reg_data[i['name']] = i['value']}
|
53
|
+
|
54
|
+
if reg_html.at_css("input[name = 'lastname']").nil?
|
55
|
+
reg_data["firstname"] = "#{@firstname} #{@lastname}"
|
56
|
+
else
|
57
|
+
reg_data["firstname"] = @firstname
|
58
|
+
reg_data["lastname"] = @lastname
|
59
|
+
end
|
60
|
+
|
61
|
+
reg_data["reg_email__"] = @email
|
62
|
+
reg_data["sex"] = (gender_value.member?(@gender) ? gender_value[@gender] : '1')
|
63
|
+
reg_data["birthday_day"] = @date_of_birth.day
|
64
|
+
reg_data["birthday_month"] = @date_of_birth.month
|
65
|
+
reg_data["birthday_year"] = @date_of_birth.year
|
66
|
+
reg_data["reg_passwd__"] = @password
|
67
|
+
reg_data["submit"] = "submit"
|
68
|
+
reg_submit = @sessions.post(URI.join(@url, reg_form['action']), data = reg_data)
|
69
|
+
reg_res = reg_submit.parse_html
|
70
|
+
reg_error = reg_res.at_css("div[id = 'registration-error']")
|
71
|
+
|
72
|
+
File.write("out.html",reg_res.to_s)
|
73
|
+
puts reg_submit.request.url
|
74
|
+
raise FbRuby::Exceptions::FacebookError.new(reg_error.text) unless reg_error.nil?
|
75
|
+
raise FbRuby::Exceptions::FacebookError.new("Gagal membuat akun Facebook, sepertinya anda sudah memiliki akun facebook dengan alamat email \"#{@email}\"") if (reg_submit.request.url.include?("/recover/code/") or reg_submit.request.url.include?('home.php')) and !reg_submit.request.url.include?("confirmemail")
|
76
|
+
raise FbRuby::Exceptions::AccountCheckPoint.new("Akun Anda Terkena Checkpoint :(") if (reg_submit.request.url.include? ('checkpoint') or reg_submit.request.cookies.member?('checkpoint'))
|
77
|
+
|
78
|
+
if save_login and reg_submit.request.url.include?('login/save-device/')
|
79
|
+
saveLoginForm = reg_res.at_css("form[action^='/login/']")
|
80
|
+
saveLoginData = {}
|
81
|
+
saveLoginForm.css("input[type = 'hidden']").each{|i| saveLoginData[i['name']] = i['value']}
|
82
|
+
@registerRequest = @sessions.post(URI.join(@url, saveLoginForm['action']), data = saveLoginData)
|
83
|
+
@registerRespons = @registerRequest.parse_html
|
84
|
+
elsif !save_login and reg_submit.request.url.include?('login/save-device/')
|
85
|
+
cancel = reg_res.at_css("a[href^='/login/save-device/cancel']")
|
86
|
+
@registerRequest = @sessions.get(URI.join(@url,cancel['href']))
|
87
|
+
@registerRespons = @registerRequest.parse_html
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Mengembalikan string representasi dari objek CreateAccount.
|
92
|
+
#
|
93
|
+
# @return [String] Representasi string dari objek CreateAccount.
|
94
|
+
def to_s
|
95
|
+
return "Facebook CreateAccount: firstname=#{@firstname}, lastname=#{@lastname}, email=#{@email} gender=#{@gender}, date_of_birth=#{@date_of_birth.strftime("%d/%m/%Y")}, password=#{@password}"
|
96
|
+
end
|
97
|
+
|
98
|
+
# Mengembalikan string representasi dari objek CreateAccount.
|
99
|
+
#
|
100
|
+
# @return [String] Representasi string dari objek CreateAccount.
|
101
|
+
def inspect
|
102
|
+
return to_s
|
103
|
+
end
|
104
|
+
|
105
|
+
# Konfirmasi Pembuatan Akun Facebook
|
106
|
+
#
|
107
|
+
# @param verification_code[String] Kode Konfirmasi yang di kirim ke email / nomor ponsel
|
108
|
+
def confirm_account(verification_code)
|
109
|
+
formConfirm = @registerRespons.at_css("form[action^='/confirmemail.php']")
|
110
|
+
dataConfirm = {"c"=>verification_code}
|
111
|
+
|
112
|
+
if @registerRequest.request.url.include?('confirmemail.php') and !formConfirm.nil?
|
113
|
+
formConfirm.css("input[type = 'hidden']").each{|i| dataConfirm[i['name']] = i['value']}
|
114
|
+
submitConfirm = @sessions.post(URI.join(@url, formConfirm['action']), data = dataConfirm)
|
115
|
+
responConfirm = submitConfirm.parse_html
|
116
|
+
errorConfirm = responConfirm.at_css("div[id = 'm_conf_cliff_root_id']")
|
117
|
+
raise FbRuby::Exceptions::FacebookError.new(errorConfirm.text) unless errorConfirm.nil?
|
118
|
+
super
|
119
|
+
else
|
120
|
+
raise FbRuby::Exceptions::FacebookError.new("Tidak dapat mengkonfirmasi akun!")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Kirim ulang kode konfirmasi
|
125
|
+
#
|
126
|
+
# @return [Boolean]
|
127
|
+
def resend_code
|
128
|
+
resend = @registerRespons.at_css("input[class][type = 'submit']:not(name)")
|
129
|
+
unless resend.nil?
|
130
|
+
resendForm = @registerRespons.at_xpath("//form[starts-with(@action,'confirmemail.php')]")
|
131
|
+
resendData = {}
|
132
|
+
resendForm.css("input[type = 'hidden']").each{|i| resendData[i['name']] = i['value']}
|
133
|
+
send = @sessions.post(URI.join(@url, resendForm["action"]), data = resendData)
|
134
|
+
|
135
|
+
return send.ok?
|
136
|
+
else
|
137
|
+
raise FbRuby::Exceptions::FacebookError.new("Tidak dapat mengirim ulang kode konfirmasi :(")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|