kogno 1.0.1

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.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/bin/kogno +92 -0
  3. data/lib/boot.rb +9 -0
  4. data/lib/core/bin_helpers/messenger_ctl.rb +48 -0
  5. data/lib/core/bin_helpers/scaffolding.rb +203 -0
  6. data/lib/core/bin_helpers/scheduled_messages_ctl.rb +95 -0
  7. data/lib/core/bin_helpers/sequences_ctl.rb +95 -0
  8. data/lib/core/bin_helpers/server_ctl.rb +127 -0
  9. data/lib/core/bin_helpers/telegram_ctl.rb +48 -0
  10. data/lib/core/bin_helpers/webhook_ctl.rb +96 -0
  11. data/lib/core/db.rb +8 -0
  12. data/lib/core/extensions/array.rb +28 -0
  13. data/lib/core/extensions/hash.rb +12 -0
  14. data/lib/core/extensions/logger.rb +70 -0
  15. data/lib/core/extensions/string.rb +6 -0
  16. data/lib/core/extensions/wit.rb +60 -0
  17. data/lib/core/global_methods.rb +67 -0
  18. data/lib/core/helpers/string.rb +105 -0
  19. data/lib/core/lib/base_config.rb +17 -0
  20. data/lib/core/lib/block_params.rb +4 -0
  21. data/lib/core/lib/context.rb +1573 -0
  22. data/lib/core/lib/error_handler.rb +36 -0
  23. data/lib/core/lib/message.rb +182 -0
  24. data/lib/core/lib/messenger/api.rb +281 -0
  25. data/lib/core/lib/messenger/facebook_graph.rb +32 -0
  26. data/lib/core/lib/messenger/message.rb +202 -0
  27. data/lib/core/lib/messenger/notification.rb +351 -0
  28. data/lib/core/lib/messenger/post_comment.rb +104 -0
  29. data/lib/core/lib/messenger/recurring_notification.rb +81 -0
  30. data/lib/core/lib/nlp.rb +191 -0
  31. data/lib/core/lib/notification.rb +371 -0
  32. data/lib/core/lib/spelling.rb +13 -0
  33. data/lib/core/lib/telegram/api.rb +197 -0
  34. data/lib/core/lib/telegram/chat_activity.rb +111 -0
  35. data/lib/core/lib/telegram/inline_query.rb +112 -0
  36. data/lib/core/lib/telegram/message.rb +327 -0
  37. data/lib/core/lib/telegram/notification.rb +507 -0
  38. data/lib/core/lib/whatsapp/api.rb +153 -0
  39. data/lib/core/lib/whatsapp/message.rb +132 -0
  40. data/lib/core/lib/whatsapp/notification.rb +206 -0
  41. data/lib/core/lib/whatsapp/status_message.rb +58 -0
  42. data/lib/core/loaders/config_files.rb +15 -0
  43. data/lib/core/models/chat_log.rb +4 -0
  44. data/lib/core/models/long_payload.rb +25 -0
  45. data/lib/core/models/matched_message.rb +5 -0
  46. data/lib/core/models/messenger_recurring_notification.rb +16 -0
  47. data/lib/core/models/scheduled_message.rb +40 -0
  48. data/lib/core/models/sequence.rb +29 -0
  49. data/lib/core/models/telegram_chat_group.rb +26 -0
  50. data/lib/core/models/user.rb +285 -0
  51. data/lib/core/web/webhook.rb +198 -0
  52. data/lib/kogno.rb +130 -0
  53. data/scaffolding/new_project/Gemfile +3 -0
  54. data/scaffolding/new_project/application.rb +5 -0
  55. data/scaffolding/new_project/bot/contexts/main_context.rb +10 -0
  56. data/scaffolding/new_project/bot/conversation.rb +14 -0
  57. data/scaffolding/new_project/bot/models/user.rb +3 -0
  58. data/scaffolding/new_project/config/application.rb +28 -0
  59. data/scaffolding/new_project/config/database.yml +8 -0
  60. data/scaffolding/new_project/config/locales/en.yml +4 -0
  61. data/scaffolding/new_project/config/locales/es.yml +3 -0
  62. data/scaffolding/new_project/config/nlp.rb +23 -0
  63. data/scaffolding/new_project/config/platforms/messenger.rb +74 -0
  64. data/scaffolding/new_project/config/platforms/telegram.rb +45 -0
  65. data/scaffolding/new_project/config/platforms/whatsapp.rb +13 -0
  66. data/scaffolding/new_project/web/routes.rb +10 -0
  67. metadata +220 -0
@@ -0,0 +1,507 @@
1
+ module Kogno
2
+ module Telegram
3
+ class Notification < Kogno::Notification
4
+
5
+ def send(recipient_id=nil,delete=true)
6
+ recipient_id = @recipient.chat_id if recipient_id.nil?
7
+ messages = @before_messages+@messages+@after_messages
8
+ @message_log = messages
9
+ logger.write("\n\nSENDING MESSAGES...\n", :bright) unless messages.empty?
10
+ messages.each do |message|
11
+ case message[:type].to_sym
12
+ when :action
13
+ sleep(message[:value][:duration]) if message[:value][:action].to_sym == :typing_on
14
+ sent_response = nil
15
+ when :photo
16
+ sent_response = Api::send(recipient_id,message[:value], "sendPhoto")
17
+ when :edit_media
18
+ sent_response = Api::send(recipient_id,message[:value], "editMessageMedia")
19
+ when :edit_text_message
20
+ sent_response = Api::send(recipient_id,message[:value], "editMessageText")
21
+ when :contact
22
+ sent_response = Api::send(recipient_id,message[:value], "sendContact")
23
+ when :location
24
+ sent_response = Api::send(recipient_id,message[:value], "sendLocation")
25
+ when :message
26
+ sent_response = Api::send(recipient_id,message[:value], "sendMessage")
27
+ else #raw
28
+ sent_response = Api::send(recipient_id,message[:value], message[:type])
29
+ end
30
+ unless sent_response.nil?
31
+ if !@recipient.nil? and @recipient.type == :user
32
+ if sent_response[:ok]
33
+ @recipient.save
34
+ match_message_ids(message[:matched_message_id], sent_response[:result][:message_id]) unless message[:matched_message_id].nil?
35
+ end
36
+ end
37
+ @response_log << sent_response
38
+ end
39
+ end
40
+ self.delete_messages() if delete
41
+ end
42
+
43
+ def match_message_ids(id, message_id)
44
+ return false unless @recipient.type == :user
45
+ matched_message = @recipient.matched_messages.find(id)
46
+ matched_message.platform_message_id = message_id
47
+ matched_message.save
48
+ end
49
+
50
+ def match_next_message()
51
+ return false unless @recipient.type == :user
52
+ matched_message = @recipient.matched_messages.create()
53
+ @matched_message_id = matched_message.id
54
+ return @matched_message_id
55
+ end
56
+
57
+ def get_matched_message_id(id)
58
+ return false unless @recipient.type == :user
59
+ @recipient.matched_messages.find(id).platform_message_id
60
+ end
61
+
62
+ def answer_inline_query(inline_query_id, delete=true)
63
+ @response_log << Api::answer_inline_query(inline_query_id, @inline_query_results)
64
+ @inline_query_results = [] if delete
65
+ end
66
+
67
+ def answer_callback_query(params={},callback_query_id=nil)
68
+ callback_query_id = @message.callback_query_id if callback_query_id.nil?
69
+ Api::answer_callback_query(callback_query_id, params)
70
+ end
71
+
72
+ def text(text, extra_params={})
73
+ extra_params[:disable_web_page_preview] = !extra_params[:preview_url] unless extra_params[:preview_url].nil?
74
+ extra_params = {disable_web_page_preview: true}.merge(extra_params)
75
+ params = {
76
+ text: text
77
+ }.merge(extra_params)
78
+ self.push_message(params, :message)
79
+ end
80
+
81
+ def html(code, reply_markup = {} ,extra_params={})
82
+ extra_params[:disable_web_page_preview] = !extra_params[:preview_url] unless extra_params[:preview_url].nil?
83
+ extra_params = {disable_web_page_preview: true}.merge(extra_params)
84
+ params = {
85
+ text: code,
86
+ parse_mode: "HTML"
87
+ }.merge(self.class.format_to_reply_markup(reply_markup)).merge(extra_params)
88
+ self.push_message(params, :message)
89
+ end
90
+
91
+ def markdown(syntax, reply_markup = {} ,extra_params={})
92
+ extra_params[:disable_web_page_preview] = !extra_params[:preview_url] unless extra_params[:preview_url].nil?
93
+ extra_params = {disable_web_page_preview: true}.merge(extra_params)
94
+ params = {
95
+ text: syntax,
96
+ parse_mode: "MarkdownV2"
97
+ }.merge(self.class.format_to_reply_markup(reply_markup)).merge(extra_params)
98
+ self.push_message(params, :message)
99
+ end
100
+
101
+ def typing_on(duration)
102
+ self.push_message({:action => :typing_on, :duration => duration}, :action)
103
+ end
104
+
105
+ def inline_keyboard(text,replies, extra_settings={})
106
+ settings = {typed_postbacks: Kogno::Application.config.typed_postbacks, push_message: true}.merge(extra_settings) # defaults
107
+ text = t(text) if text.class == Symbol
108
+ text = Notification::rand_text(text)
109
+ begin
110
+ set_typed_postbacks(replies.map{|reply|
111
+ [reply[:text].to_payload, reply[:callback_data]] unless reply[:text].nil?
112
+ }.compact.to_h) if settings[:typed_postbacks]
113
+ rescue
114
+ nil
115
+ end
116
+
117
+ replies = replies.each_slice(settings[:slice_replies]).to_a unless settings[:slice_replies].nil?
118
+ result = Api::inline_keyboard_markup(text, replies, settings[:update])
119
+ if settings[:push_message]
120
+ self.push_message(result)
121
+ else
122
+ result
123
+ end
124
+ end
125
+
126
+ def keyboard(text,buttons, extra_settings={})
127
+ settings = {typed_postbacks: Kogno::Application.config.typed_postbacks, push_message: true, one_time_keyboard: true}.merge(extra_settings) # defaults
128
+ text = t(text) if text.class == Symbol
129
+ text = Notification::rand_text(text)
130
+
131
+ begin
132
+ set_typed_postbacks(buttons.map{|reply|
133
+ [reply[:text].to_payload, reply[:callback_data]] unless reply[:text].nil?
134
+ }.compact.to_h) if settings[:typed_postbacks]
135
+ rescue
136
+ nil
137
+ end
138
+
139
+ buttons = buttons.each_slice(settings[:slice_replies]).to_a unless settings[:slice_replies].nil?
140
+ result = Api::keyboard(text, buttons, settings[:one_time_keyboard])
141
+ if settings[:push_message]
142
+ self.push_message(result)
143
+ else
144
+ result
145
+ end
146
+ end
147
+
148
+ def button(text,buttons,extra_settings={})
149
+ settings = {push_message: false, one_time_keyboard: true}.merge(extra_settings) # defaults
150
+ buttons = buttons.replace_keys({payload: :callback_data, title: :text})
151
+ self.push_message(self.keyboard(text,buttons,settings))
152
+ end
153
+
154
+ def quick_reply(text,replies,extra_settings={})
155
+ settings = {typed_postbacks: true, push_message: false, editable: false}.merge(extra_settings) # defaults
156
+ replies = [replies] if replies.class == Hash
157
+ replies = replies.replace_keys({payload: :callback_data, title: :text})
158
+
159
+
160
+ kgn_id = @message.get_kgn_id rescue nil
161
+ if !kgn_id.nil?
162
+ if kgn_id.class == String
163
+ kogno_message_id = kgn_id.split("-")[1].to_i
164
+ update_message_id = self.get_matched_message_id(kogno_message_id)
165
+ elsif kgn_id.class == Integer
166
+ update_message_id = kgn_id
167
+ end
168
+ elsif settings[:updateable]
169
+ kgn_id = "kgn-#{self.match_next_message}"
170
+ replies = self.class.add_params_to_reply_payloads(replies, {kgn_id: kgn_id})
171
+ end
172
+
173
+ if update_message_id.nil?
174
+ self.push_message(self.inline_keyboard(text,replies,settings))
175
+ else
176
+ replies = self.class.add_params_to_reply_payloads(replies, {kgn_id: update_message_id})
177
+ self.push_message(self.inline_keyboard(text,replies,settings.merge({update: {message_id: update_message_id}})), :edit_text_message)
178
+ end
179
+
180
+ end
181
+
182
+ def location_request(text, button_text="📍")
183
+ self.push_message(Api::keyboard(text, [{text: button_text, request_location: true}]))
184
+ end
185
+
186
+ def contact_request(text, button_text="📝")
187
+ self.push_message(Api::keyboard(text, [{text: button_text, request_contact: true}]))
188
+ end
189
+
190
+ def contact(params)
191
+ self.push_message(params, :contact)
192
+ end
193
+
194
+ def location(params)
195
+ self.push_message(params, :location)
196
+ end
197
+
198
+ def image(params)
199
+
200
+ message = {
201
+ photo: params[:url],
202
+ caption: params[:caption]
203
+ }
204
+ unless params[:buttons].nil?
205
+ replies = params[:buttons].replace_keys({payload: :callback_data, title: :text})
206
+ replies = self.class.array_of_arrays(replies)
207
+ message = message.merge(Api::add_inline_keyboard_markup(replies))
208
+ end
209
+ self.push_message(message, :photo)
210
+
211
+ end
212
+
213
+
214
+ def video(params)
215
+
216
+ message = {
217
+ video: params[:url],
218
+ caption: params[:caption]
219
+ }
220
+ unless params[:buttons].nil?
221
+ replies = params[:buttons].replace_keys({payload: :callback_data, title: :text})
222
+ replies = self.class.array_of_arrays(replies)
223
+ message = message.merge(Api::add_inline_keyboard_markup(replies))
224
+ end
225
+ self.push_message(message, "sendVideo")
226
+
227
+ end
228
+
229
+ def url(params)
230
+
231
+ inline_keyboard = !params[:button].nil? ? [
232
+ [
233
+ {
234
+ text: params[:button],
235
+ url: params[:url]
236
+ }
237
+ ]
238
+ ] : []
239
+
240
+ message = {
241
+ caption: "<strong><a href=\"#{params[:url]}\">#{params[:title]}</a></strong>\n#{params[:sub_title]}",
242
+ parse_mode: "HTML",
243
+ photo: params[:image],
244
+ reply_markup:{
245
+ inline_keyboard: inline_keyboard
246
+ }
247
+ }
248
+
249
+ self.push_message(message,:photo)
250
+
251
+ end
252
+
253
+ # def carousel(args)
254
+
255
+ # if args[:update_message_id].nil?
256
+ # update_message_id = "kgn-#{self.match_next_message}"
257
+ # elsif args[:update_message_id].class == String
258
+ # kogno_message_id = args[:update_message_id].split("-")[1].to_i
259
+ # update_message_id = self.get_matched_message_id(kogno_message_id)
260
+ # else
261
+ # update_message_id = args[:update_message_id]
262
+ # end
263
+
264
+ # pagination_buttons = []
265
+
266
+ # pagination_back = self.class.convert_keys_to_telegram(args[:pagination][:back])
267
+ # pagination_next = self.class.convert_keys_to_telegram(args[:pagination][:next])
268
+
269
+ # pagination_back[:callback_data] = self.class.add_params_to_payload(pagination_back[:callback_data], {kgn_id: update_message_id, page: args[:pagination][:current] - 1})
270
+ # pagination_next[:callback_data] = self.class.add_params_to_payload(pagination_next[:callback_data], {kgn_id: update_message_id, page: args[:pagination][:current] + 1})
271
+
272
+ # pagination_buttons << {text: "«"}.merge(pagination_back) if args[:pagination][:current] > 0
273
+ # pagination_buttons << {text: "»"}.merge(pagination_next) if args[:pagination][:current] < (args[:pagination][:total]-1)
274
+
275
+ # reply_markup = self.class.format_to_reply_markup({quick_reply: args[:buttons]})
276
+ # logger.debug "reply_markup", :pink
277
+ # logger.debug_json reply_markup, :pink
278
+ # logger.debug "pagination_buttons", :pink
279
+ # reply_markup[:reply_markup][:inline_keyboard] << pagination_buttons
280
+ # logger.debug_json reply_markup, :pink
281
+ # if args[:update_message_id].nil?
282
+ # params = {
283
+ # caption: "<pre><strong>#{args[:title]}</strong></pre>\n<i>#{args[:description]}</i>",
284
+ # parse_mode: "HTML",
285
+ # photo: args[:image]
286
+ # }.merge(reply_markup)
287
+ # self.push_message(params,:photo)
288
+ # else
289
+ # params = {
290
+ # message_id: update_message_id,
291
+ # media: {
292
+ # type: :photo,
293
+ # caption: "<pre><strong>#{args[:title]}</strong></pre>\n<i>#{args[:description]}</i>",
294
+ # parse_mode: "HTML",
295
+ # media: args[:image]
296
+ # }
297
+ # }.merge(reply_markup)
298
+ # self.push_message(params, :edit_media)
299
+ # end
300
+ # end
301
+
302
+ # def url_carousel(args)
303
+
304
+ # if args[:update_message_id].nil?
305
+ # update_message_id = "kgn-#{self.match_next_message}"
306
+ # elsif args[:update_message_id].class == String
307
+ # kogno_message_id = args[:update_message_id].split("-")[1].to_i
308
+ # update_message_id = self.get_matched_message_id(kogno_message_id)
309
+ # else
310
+ # update_message_id = args[:update_message_id]
311
+ # end
312
+
313
+ # pagination_buttons = []
314
+
315
+ # pagination_back = self.class.convert_keys_to_telegram(args[:pagination][:back])
316
+ # pagination_next = self.class.convert_keys_to_telegram(args[:pagination][:next])
317
+
318
+ # pagination_back[:callback_data] = self.class.add_params_to_payload(pagination_back[:callback_data], {kgn_id: update_message_id, page: args[:pagination][:current] - 1})
319
+ # pagination_next[:callback_data] = self.class.add_params_to_payload(pagination_next[:callback_data], {kgn_id: update_message_id, page: args[:pagination][:current] + 1})
320
+
321
+ # pagination_buttons << {text: "«"}.merge(pagination_back) if args[:pagination][:current] > 0
322
+ # pagination_buttons << {text: "»"}.merge(pagination_next) if args[:pagination][:current] < (args[:pagination][:total]-1)
323
+
324
+ # if args[:update_message_id].nil?
325
+ # self.push_message(
326
+ # {
327
+
328
+ # caption: "<strong><a href=\"#{args[:url]}\">#{args[:title]}</a></strong>\n<i>#{args[:description]}</i>",
329
+ # parse_mode: "HTML",
330
+ # photo: args[:image],
331
+ # reply_markup:{
332
+ # inline_keyboard: [
333
+ # [
334
+ # {
335
+ # text: args[:button_label],
336
+ # url: args[:url]
337
+ # }
338
+ # ],
339
+ # pagination_buttons
340
+ # ]
341
+ # }
342
+ # },
343
+ # :photo
344
+ # )
345
+ # else
346
+ # self.push_message(
347
+
348
+ # {
349
+ # message_id: update_message_id,
350
+ # media: {
351
+ # type: :photo,
352
+ # caption: "<strong><a href=\"#{args[:url]}\">#{args[:title]}</a></strong>\n<i>#{args[:description]}</i>",
353
+ # parse_mode: "HTML",
354
+ # media: args[:image]
355
+ # },
356
+ # reply_markup:{
357
+ # inline_keyboard: [
358
+ # [
359
+ # {
360
+ # text: args[:button_label],
361
+ # url: args[:url]
362
+ # }
363
+ # ],
364
+ # pagination_buttons
365
+ # ]
366
+ # }
367
+ # },
368
+ # :edit_media
369
+ # )
370
+ # end
371
+ # end
372
+
373
+ def inline_query_result(type, results)
374
+ body = self.push_inline_query_result(
375
+ {
376
+ type: type,
377
+ id: @inline_query_results.count+1
378
+ }.merge(results)
379
+ )
380
+ body
381
+ end
382
+
383
+ protected
384
+
385
+ def push_message(message,type=:message) # :message o :action
386
+ new_message = {:type => type, :value => message}
387
+ unless @matched_message_id.nil?
388
+ new_message[:matched_message_id] = @matched_message_id
389
+ @matched_message_id = nil
390
+ end
391
+ logger.debug_json new_message, :blue
392
+ new_message[:value][:reply_markup][:inline_keyboard] = self.class.replace_long_callback_data(new_message[:value][:reply_markup][:inline_keyboard]) if (!new_message[:value][:reply_markup][:inline_keyboard].nil? rescue false)
393
+ new_message[:value][:reply_markup][:keyboard] = self.class.replace_long_callback_data(new_message[:value][:reply_markup][:keyboard]) if (!new_message[:value][:reply_markup][:keyboard].nil? rescue false)
394
+ @messages << new_message
395
+ end
396
+
397
+ def push_inline_query_result(result)
398
+ logger.write_json result, :blue
399
+ @inline_query_results << result
400
+ end
401
+
402
+ def self.format_to_reply_markup(args)
403
+ args = {typed_postbacks: Kogno::Application.config.typed_postbacks}.merge(args)
404
+ if !args[:quick_reply].nil?
405
+ inline_keyboard = args[:quick_reply]
406
+ inline_keyboard = convert_keys_to_telegram(inline_keyboard)
407
+ begin
408
+ set_typed_postbacks(inline_keyboard.map{|reply|
409
+ [reply[:text].to_payload, reply[:callback_data]] unless reply[:text].nil?
410
+ }.compact.to_h) if args[:typed_postbacks]
411
+ rescue
412
+ nil
413
+ end
414
+ inline_keyboard = inline_keyboard.each_slice(args[:slice_replies]).to_a unless args[:slice_replies].nil?
415
+ inline_keyboard = array_of_arrays(inline_keyboard)
416
+ {
417
+ reply_markup: {
418
+ inline_keyboard: inline_keyboard
419
+ }
420
+ }
421
+ elsif !args[:button].nil?
422
+ keyboard = args[:button]
423
+ keyboard = convert_keys_to_telegram(keyboard)
424
+ begin
425
+ set_typed_postbacks(keyboard.map{|reply|
426
+ [reply[:text].to_payload, reply[:callback_data]] unless reply[:text].nil?
427
+ }.compact.to_h) if args[:typed_postbacks]
428
+ rescue
429
+ nil
430
+ end
431
+ keyboard = keyboard.each_slice(args[:slice_replies]).to_a unless args[:slice_replies].nil?
432
+ keyboard = array_of_arrays(keyboard)
433
+
434
+ {
435
+ reply_markup: {
436
+ keyboard: keyboard,
437
+ one_time_keyboard: true
438
+ }
439
+ }
440
+ elsif !args.nil?
441
+ {
442
+ reply_markup: args
443
+ }
444
+ else
445
+ {}
446
+ end
447
+
448
+ end
449
+
450
+ def self.array_of_arrays(data)
451
+ array = data.class == Array ? data : [data]
452
+ array = [array] unless array.map{|v| v.class}.uniq[0] == Array
453
+ array
454
+ end
455
+
456
+ def self.convert_keys_to_telegram(hash)
457
+ hash.replace_keys({payload: :callback_data, label: :text, title: :text})
458
+ end
459
+
460
+ def self.add_params_to_payload(callback_data, params_to_add)
461
+ payload = callback_data.split(":",2)[0] rescue nil
462
+ raw_params = callback_data.to_s.split(":",2)[1].to_s
463
+ unless raw_params.empty?
464
+ params = JSON.parse(raw_params, {:symbolize_names => true})
465
+ set_payload(payload, params.merge(params_to_add))
466
+ else
467
+ set_payload(payload, params_to_add)
468
+ end
469
+ end
470
+
471
+ def self.add_params_to_reply_payloads(replies, params_to_add)
472
+ new_replies = []
473
+ replies.each do |reply|
474
+ if reply.class == Array
475
+ new_replies << add_params_to_reply_payloads(reply, params_to_add)
476
+ elsif reply.class == Hash
477
+ new_reply = reply
478
+ new_reply[:callback_data] = add_params_to_payload(new_reply[:callback_data], params_to_add)
479
+ new_replies << new_reply
480
+ else
481
+ new_replies << reply
482
+ end
483
+ end
484
+ return new_replies
485
+ end
486
+
487
+ def self.replace_long_callback_data(messages)
488
+ new_messages = []
489
+ messages.each do |message|
490
+ if message.class == Array
491
+ new_messages << replace_long_callback_data(message)
492
+ elsif message.class == Hash
493
+ new_message = message
494
+ unless message[:callback_data].nil?
495
+ new_message[:callback_data] = message[:callback_data].length > 64 ? "kogno__#{LongPayload.set(message[:callback_data])}" : message[:callback_data]
496
+ end
497
+ new_messages << new_message
498
+ else
499
+ new_messages << message
500
+ end
501
+ end
502
+ return new_messages
503
+ end
504
+
505
+ end
506
+ end
507
+ end
@@ -0,0 +1,153 @@
1
+ module Kogno
2
+ module WhatsApp
3
+
4
+ class Api
5
+
6
+ require 'uri'
7
+ require 'net/http'
8
+ require 'openssl'
9
+
10
+ class << self
11
+
12
+ def request(body,type,method=:post) # :messages, :messenger_profile
13
+
14
+ url = URI("#{Kogno::Application.config.whatsapp.graph_url}/#{Kogno::Application.config.whatsapp.phone_number_id}/#{type}")
15
+
16
+ logger.write "REQUEST TO: #{url}", :pink
17
+ logger.write "SENT: #{JSON.parse(body)}", :blue
18
+
19
+ http = Net::HTTP.new(url.host, url.port)
20
+ http.use_ssl = true
21
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
22
+
23
+ case method
24
+ when :delete
25
+ request = Net::HTTP::Delete.new(url)
26
+ else
27
+ request = Net::HTTP::Post.new(url)
28
+ end
29
+
30
+ request["Authorization"] = "Bearer #{Kogno::Application.config.whatsapp.access_token}"
31
+ request["content-type"] = "application/json"
32
+
33
+ request.body = body
34
+
35
+ response = http.request(request)
36
+ # logger.debug_json JSON.parse(body), :green
37
+ response_hash = JSON.parse(response.read_body, {:symbolize_names => true})
38
+ logger.write "RESPONSE: #{response_hash}\n", :light_blue
39
+ return(response_hash)
40
+
41
+ end
42
+
43
+
44
+ def send(recipient,message, type="messages")
45
+ body = {
46
+ messaging_product: :whatsapp,
47
+ recipient_type: :individual,
48
+ to: recipient,
49
+ }.merge(message).to_json
50
+
51
+ return(self.request(body,type))
52
+
53
+ end
54
+
55
+ def template_message(template_name, components=[], lang="en_US")
56
+
57
+ {
58
+ type: :template,
59
+ template: {
60
+ name: template_name,
61
+ language: {
62
+ code: lang
63
+ },
64
+ components: components
65
+ }
66
+ }
67
+
68
+ end
69
+
70
+ def interactive_buttons(text, buttons)
71
+
72
+ {
73
+ type: :interactive,
74
+ interactive: {
75
+ type: :button,
76
+ body: {
77
+ text: text
78
+ },
79
+ action: {
80
+ buttons: buttons
81
+ }
82
+ }
83
+ }
84
+
85
+ end
86
+
87
+ def interactive_buttons(text, buttons)
88
+
89
+ {
90
+ type: :interactive,
91
+ interactive: {
92
+ type: :button,
93
+ body: {
94
+ text: text
95
+ },
96
+ action: {
97
+ buttons: buttons
98
+ }
99
+ }
100
+ }
101
+
102
+ end
103
+
104
+
105
+ def interactive_list(params)
106
+
107
+ {
108
+ type: :interactive,
109
+ interactive: {
110
+ type: :list,
111
+ header: params[:header],
112
+ footer: params[:footer],
113
+ body: {
114
+ text: params[:text]
115
+ },
116
+ action: {
117
+ button: params[:button],
118
+ sections: params[:sections]
119
+ }
120
+ }
121
+ }
122
+
123
+ end
124
+
125
+ def location(location_data)
126
+ {
127
+ type: :location,
128
+ location: location_data
129
+ }
130
+ end
131
+
132
+ def media(type, params)
133
+ media_object = {
134
+ type: type
135
+ }
136
+ media_object[type] = params
137
+ media_object
138
+ end
139
+
140
+ def contacts(params)
141
+ {
142
+ type: :contacts,
143
+ contacts: params
144
+ }
145
+ end
146
+
147
+
148
+ end
149
+
150
+ end
151
+
152
+ end
153
+ end