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.
- checksums.yaml +7 -0
- data/bin/kogno +92 -0
- data/lib/boot.rb +9 -0
- data/lib/core/bin_helpers/messenger_ctl.rb +48 -0
- data/lib/core/bin_helpers/scaffolding.rb +203 -0
- data/lib/core/bin_helpers/scheduled_messages_ctl.rb +95 -0
- data/lib/core/bin_helpers/sequences_ctl.rb +95 -0
- data/lib/core/bin_helpers/server_ctl.rb +127 -0
- data/lib/core/bin_helpers/telegram_ctl.rb +48 -0
- data/lib/core/bin_helpers/webhook_ctl.rb +96 -0
- data/lib/core/db.rb +8 -0
- data/lib/core/extensions/array.rb +28 -0
- data/lib/core/extensions/hash.rb +12 -0
- data/lib/core/extensions/logger.rb +70 -0
- data/lib/core/extensions/string.rb +6 -0
- data/lib/core/extensions/wit.rb +60 -0
- data/lib/core/global_methods.rb +67 -0
- data/lib/core/helpers/string.rb +105 -0
- data/lib/core/lib/base_config.rb +17 -0
- data/lib/core/lib/block_params.rb +4 -0
- data/lib/core/lib/context.rb +1573 -0
- data/lib/core/lib/error_handler.rb +36 -0
- data/lib/core/lib/message.rb +182 -0
- data/lib/core/lib/messenger/api.rb +281 -0
- data/lib/core/lib/messenger/facebook_graph.rb +32 -0
- data/lib/core/lib/messenger/message.rb +202 -0
- data/lib/core/lib/messenger/notification.rb +351 -0
- data/lib/core/lib/messenger/post_comment.rb +104 -0
- data/lib/core/lib/messenger/recurring_notification.rb +81 -0
- data/lib/core/lib/nlp.rb +191 -0
- data/lib/core/lib/notification.rb +371 -0
- data/lib/core/lib/spelling.rb +13 -0
- data/lib/core/lib/telegram/api.rb +197 -0
- data/lib/core/lib/telegram/chat_activity.rb +111 -0
- data/lib/core/lib/telegram/inline_query.rb +112 -0
- data/lib/core/lib/telegram/message.rb +327 -0
- data/lib/core/lib/telegram/notification.rb +507 -0
- data/lib/core/lib/whatsapp/api.rb +153 -0
- data/lib/core/lib/whatsapp/message.rb +132 -0
- data/lib/core/lib/whatsapp/notification.rb +206 -0
- data/lib/core/lib/whatsapp/status_message.rb +58 -0
- data/lib/core/loaders/config_files.rb +15 -0
- data/lib/core/models/chat_log.rb +4 -0
- data/lib/core/models/long_payload.rb +25 -0
- data/lib/core/models/matched_message.rb +5 -0
- data/lib/core/models/messenger_recurring_notification.rb +16 -0
- data/lib/core/models/scheduled_message.rb +40 -0
- data/lib/core/models/sequence.rb +29 -0
- data/lib/core/models/telegram_chat_group.rb +26 -0
- data/lib/core/models/user.rb +285 -0
- data/lib/core/web/webhook.rb +198 -0
- data/lib/kogno.rb +130 -0
- data/scaffolding/new_project/Gemfile +3 -0
- data/scaffolding/new_project/application.rb +5 -0
- data/scaffolding/new_project/bot/contexts/main_context.rb +10 -0
- data/scaffolding/new_project/bot/conversation.rb +14 -0
- data/scaffolding/new_project/bot/models/user.rb +3 -0
- data/scaffolding/new_project/config/application.rb +28 -0
- data/scaffolding/new_project/config/database.yml +8 -0
- data/scaffolding/new_project/config/locales/en.yml +4 -0
- data/scaffolding/new_project/config/locales/es.yml +3 -0
- data/scaffolding/new_project/config/nlp.rb +23 -0
- data/scaffolding/new_project/config/platforms/messenger.rb +74 -0
- data/scaffolding/new_project/config/platforms/telegram.rb +45 -0
- data/scaffolding/new_project/config/platforms/whatsapp.rb +13 -0
- data/scaffolding/new_project/web/routes.rb +10 -0
- metadata +220 -0
@@ -0,0 +1,327 @@
|
|
1
|
+
module Kogno
|
2
|
+
module Telegram
|
3
|
+
class Message < Kogno::Message
|
4
|
+
|
5
|
+
@overwritten_payload = nil
|
6
|
+
|
7
|
+
def initialize(data, type=nil)
|
8
|
+
@data = data
|
9
|
+
@type = type
|
10
|
+
end
|
11
|
+
|
12
|
+
def type
|
13
|
+
@type
|
14
|
+
end
|
15
|
+
|
16
|
+
def platform
|
17
|
+
:telegram
|
18
|
+
end
|
19
|
+
|
20
|
+
def chat
|
21
|
+
if @type == :callback_query
|
22
|
+
@data[:message][:chat]
|
23
|
+
else
|
24
|
+
@data[:chat]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def chat_id
|
29
|
+
self.chat[:id]
|
30
|
+
end
|
31
|
+
|
32
|
+
def chat_title
|
33
|
+
self.chat[:title]
|
34
|
+
end
|
35
|
+
|
36
|
+
def chat_type
|
37
|
+
self.chat[:type].to_sym
|
38
|
+
end
|
39
|
+
|
40
|
+
def via_bot
|
41
|
+
@data[:via_bot] rescue nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def inviter_user_id
|
45
|
+
@data[:from][:id]
|
46
|
+
end
|
47
|
+
|
48
|
+
def page_id
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def attachments
|
53
|
+
a = nil
|
54
|
+
a = @data[:audio]
|
55
|
+
a = @data[:document] if a.nil?
|
56
|
+
a = @data[:photo] if a.nil?
|
57
|
+
a = @data[:sticker] if a.nil?
|
58
|
+
a = @data[:video] if a.nil?
|
59
|
+
a = @data[:voice] if a.nil?
|
60
|
+
return a
|
61
|
+
end
|
62
|
+
|
63
|
+
def sender_id
|
64
|
+
return @data[:from][:id]
|
65
|
+
end
|
66
|
+
|
67
|
+
def sender_first_name
|
68
|
+
return @data[:from][:first_name] rescue ""
|
69
|
+
end
|
70
|
+
|
71
|
+
def sender_last_name
|
72
|
+
return @data[:from][:last_name] rescue ""
|
73
|
+
end
|
74
|
+
|
75
|
+
def sender_language
|
76
|
+
return @data[:from][:language_code] rescue ""
|
77
|
+
end
|
78
|
+
|
79
|
+
def callback_query_id
|
80
|
+
if @type == :callback_query
|
81
|
+
return @data[:id]
|
82
|
+
else
|
83
|
+
return nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def raw_payload
|
88
|
+
payload = @data[:data] rescue nil
|
89
|
+
payload = get_long_payload(payload) unless payload.nil?
|
90
|
+
payload = @overwritten_payload if payload.nil?
|
91
|
+
return(payload)
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_long_payload(data)
|
95
|
+
return @long_payload unless @long_payload.nil?
|
96
|
+
|
97
|
+
long_data = data.split("kogno__",2)
|
98
|
+
if long_data.length == 2
|
99
|
+
token = long_data[1]
|
100
|
+
@long_payload = LongPayload.get(token)
|
101
|
+
else
|
102
|
+
@long_payload = data
|
103
|
+
end
|
104
|
+
|
105
|
+
return @long_payload
|
106
|
+
end
|
107
|
+
|
108
|
+
def payload(action_only=false)
|
109
|
+
if action_only
|
110
|
+
pl = self.raw_payload.split(":",2)[0] rescue nil
|
111
|
+
if pl.nil?
|
112
|
+
return pl
|
113
|
+
else
|
114
|
+
return pl.split(Regexp.union(["/","-"])).last
|
115
|
+
end
|
116
|
+
else
|
117
|
+
self.raw_payload.split(":",2)[0] rescue nil
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def referral(field=nil)
|
122
|
+
nil
|
123
|
+
end
|
124
|
+
|
125
|
+
def payload_action
|
126
|
+
payload(true)
|
127
|
+
end
|
128
|
+
|
129
|
+
def command(command_only=true)
|
130
|
+
bot_command_entity = @data[:entities].find{|e| e[:type] == "bot_command"} rescue nil
|
131
|
+
if !bot_command_entity.nil?
|
132
|
+
if command_only
|
133
|
+
return @data[:text].split(" ").first.sub("/","").split("@")[0]
|
134
|
+
else
|
135
|
+
return @data[:text]
|
136
|
+
end
|
137
|
+
else
|
138
|
+
return nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def deep_link_data
|
143
|
+
if self.command == "start"
|
144
|
+
command_param = self.command_text.to_s
|
145
|
+
if !command_param.empty?
|
146
|
+
return command_param
|
147
|
+
end
|
148
|
+
end
|
149
|
+
return nil
|
150
|
+
end
|
151
|
+
|
152
|
+
def deep_link_params
|
153
|
+
end
|
154
|
+
|
155
|
+
def command_text
|
156
|
+
command = self.command(false)
|
157
|
+
unless command.nil?
|
158
|
+
a = command.split(" ")
|
159
|
+
a.shift
|
160
|
+
return a.join(" ")
|
161
|
+
else
|
162
|
+
return ""
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def empty_thread_from_ad?
|
167
|
+
if self.empty?
|
168
|
+
unless self.referral.nil?
|
169
|
+
if self.referral(:source) == "ADS" and self.referral(:type) == "OPEN_THREAD"
|
170
|
+
return true
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
return false
|
176
|
+
end
|
177
|
+
|
178
|
+
def params
|
179
|
+
raw_params = self.raw_payload.to_s.split(":",2)[1].to_s
|
180
|
+
if raw_params.empty?
|
181
|
+
return({})
|
182
|
+
else
|
183
|
+
p = (JSON.parse(raw_params, {:symbolize_names => true}) rescue nil)
|
184
|
+
p = raw_params if p.nil?
|
185
|
+
return(p)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def get_kgn_id
|
190
|
+
self.params[:kgn_id] rescue nil
|
191
|
+
end
|
192
|
+
|
193
|
+
def raw_message
|
194
|
+
t = @data[:text] rescue nil
|
195
|
+
unless t.nil?
|
196
|
+
return({
|
197
|
+
:type => :text,
|
198
|
+
:value => t
|
199
|
+
})
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def text
|
204
|
+
return self.raw_message[:value].to_s rescue ""
|
205
|
+
end
|
206
|
+
|
207
|
+
def overwrite_postback(payload)
|
208
|
+
@overwritten_payload = payload
|
209
|
+
end
|
210
|
+
|
211
|
+
def location
|
212
|
+
if (self.raw_message[:type] == :location rescue false)
|
213
|
+
return self.raw_message[:value]
|
214
|
+
else
|
215
|
+
return nil
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def get_context(user,notification,chat)
|
220
|
+
|
221
|
+
if !(context_from_postback = Context.get_from_payload(self.payload)).nil?
|
222
|
+
context_route = context_from_postback
|
223
|
+
elsif !(context_in_link = Context.get(self.deep_link_data)).nil?
|
224
|
+
context_route = context_in_link[:context]
|
225
|
+
@data[:deep_link_param] = context_in_link[:param]
|
226
|
+
logger.write "-----context_from_deep_link:#{context_route}-----", :pink
|
227
|
+
elsif !(context_from_typed_postback = Context.get_from_typed_postback(self,user)).nil?
|
228
|
+
context_route = context_from_typed_postback
|
229
|
+
else
|
230
|
+
context_route = user.context
|
231
|
+
end
|
232
|
+
|
233
|
+
context_class = Context.router(context_route)[:class]
|
234
|
+
if context_class.nil?
|
235
|
+
user.exit_context
|
236
|
+
context_class = Context.router(Kogno::Application.config.routes.default)[:class]
|
237
|
+
end
|
238
|
+
context = context_class.new(user,self,notification,context_route, nil, chat)
|
239
|
+
context
|
240
|
+
end
|
241
|
+
|
242
|
+
|
243
|
+
def handle_event(debug=false)
|
244
|
+
|
245
|
+
begin
|
246
|
+
|
247
|
+
unless self.via_bot.nil?
|
248
|
+
logger.debug "Shared message via inline_query detected. We don't do nothing here yet.", :pink
|
249
|
+
return false
|
250
|
+
end
|
251
|
+
|
252
|
+
user = User.find_or_create_by_psid(self.sender_id, :telegram)
|
253
|
+
user.get_session_vars
|
254
|
+
user.first_name = self.sender_first_name
|
255
|
+
user.last_name = self.sender_last_name
|
256
|
+
user.locale = self.sender_language if user.locale.nil?
|
257
|
+
user.save
|
258
|
+
|
259
|
+
self.set_nlp(user.locale)
|
260
|
+
I18n.locale = user.locale unless user.locale.nil?
|
261
|
+
|
262
|
+
if [:group,:channel, :supergroup].include?(self.chat_type)
|
263
|
+
chat = TelegramChatGroup.find_by_chat_id(self.chat_id)
|
264
|
+
else
|
265
|
+
chat = user
|
266
|
+
end
|
267
|
+
|
268
|
+
|
269
|
+
unless user.vars[:nlp_context_ref].nil?
|
270
|
+
self.nlp.set_context_reference(user.vars[:nlp_context_ref])
|
271
|
+
user.vars.delete(:nlp_context_ref) # context references will only be used once
|
272
|
+
end
|
273
|
+
|
274
|
+
if [:group,:channel, :supergroup].include?(self.chat_type)
|
275
|
+
notification = Notification.new(chat,self)
|
276
|
+
else
|
277
|
+
notification = Notification.new(user,self)
|
278
|
+
end
|
279
|
+
|
280
|
+
self.log_message_info(user)
|
281
|
+
|
282
|
+
context = get_context(user,notification,chat)
|
283
|
+
|
284
|
+
return({msg: self, user: user, notification: notification, context: context, chat: chat}) if debug
|
285
|
+
|
286
|
+
unless empty_thread_from_ad?
|
287
|
+
|
288
|
+
called_action = context.run
|
289
|
+
if Kogno::Application.config.store_log_in_database
|
290
|
+
message_log_id = user.log_message(self).id
|
291
|
+
else
|
292
|
+
message_chat_log_id = 0
|
293
|
+
end
|
294
|
+
|
295
|
+
notification.answer_callback_query if self.type == :callback_query
|
296
|
+
notification.send
|
297
|
+
|
298
|
+
response_log_id = 0
|
299
|
+
if Kogno::Application.config.store_log_in_database
|
300
|
+
response_log = user.log_response(notification)
|
301
|
+
response_log_id = response_log.id unless response_log.nil?
|
302
|
+
end
|
303
|
+
|
304
|
+
# user.set_last_usage
|
305
|
+
user.save_session_vars
|
306
|
+
context.handle_message_from_memory
|
307
|
+
|
308
|
+
else
|
309
|
+
context.run_class_callbacks_only
|
310
|
+
user.save_session_vars
|
311
|
+
user.log_message(self) if Kogno::Application.config.store_log_in_database
|
312
|
+
end
|
313
|
+
logger.write "- Current user context: #{user.context}", :blue unless user.context.nil?
|
314
|
+
|
315
|
+
rescue StandardError => e
|
316
|
+
error_token = Digest::MD5.hexdigest("#{Time.now}#{rand(1000)}") # This helps to identify the error that arrives to Slack in order to search it in logs/http.log
|
317
|
+
logger.write e.message, :red
|
318
|
+
logger.write "Error Token: #{error_token}", :red
|
319
|
+
logger.write "Backtrace:\n\t#{e.backtrace.join("\n\t")}", :red
|
320
|
+
ErrorHandler.notify_by_slack(Kogno::Application.config.app_name,e, error_token) if Kogno::Application.config.error_notifier.slack[:enable] rescue false
|
321
|
+
end
|
322
|
+
|
323
|
+
end
|
324
|
+
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|