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.
@@ -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
+