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,132 @@
|
|
1
|
+
module Kogno
|
2
|
+
module WhatsApp
|
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
|
+
:whatsapp
|
18
|
+
end
|
19
|
+
|
20
|
+
def metadata
|
21
|
+
@data[:metadata]
|
22
|
+
end
|
23
|
+
|
24
|
+
def sender_id
|
25
|
+
return @data[:contacts][0][:wa_id]
|
26
|
+
end
|
27
|
+
|
28
|
+
def sender_name
|
29
|
+
return @data[:contacts][0][:profile][:name] rescue ""
|
30
|
+
end
|
31
|
+
|
32
|
+
def attachments
|
33
|
+
message = @data[:messages][0]
|
34
|
+
a = nil
|
35
|
+
a = message[:audio]
|
36
|
+
a = message[:document] if a.nil?
|
37
|
+
a = message[:image] if a.nil?
|
38
|
+
a = message[:video] if a.nil?
|
39
|
+
return a
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def raw_message
|
44
|
+
t = @data[:messages][0][:text][:body] rescue nil
|
45
|
+
unless t.nil?
|
46
|
+
return({
|
47
|
+
:type => :text,
|
48
|
+
:value => t
|
49
|
+
})
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def raw_payload
|
54
|
+
payload = @data[:messages][0][:button][:payload] rescue nil
|
55
|
+
payload = (@data[:messages][0][:interactive][:button_reply][:id] rescue nil) if payload.nil?
|
56
|
+
payload = (@data[:messages][0][:interactive][:list_reply][:id] rescue nil) if payload.nil?
|
57
|
+
payload = @overwritten_payload if payload.nil?
|
58
|
+
return(payload)
|
59
|
+
end
|
60
|
+
|
61
|
+
def text
|
62
|
+
return self.raw_message[:value].to_s rescue ""
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def handle_event(debug=false)
|
67
|
+
|
68
|
+
begin
|
69
|
+
|
70
|
+
user = User.find_or_create_by_psid(self.sender_id, :whatsapp)
|
71
|
+
user.get_session_vars
|
72
|
+
|
73
|
+
self.set_nlp(user.locale)
|
74
|
+
|
75
|
+
I18n.locale = user.locale unless user.locale.nil?
|
76
|
+
|
77
|
+
self.set_nlp(I18n.locale)
|
78
|
+
|
79
|
+
unless user.vars[:nlp_context_ref].nil?
|
80
|
+
self.nlp.set_context_reference(user.vars[:nlp_context_ref])
|
81
|
+
user.vars.delete(:nlp_context_ref) # context references will only be used once
|
82
|
+
end
|
83
|
+
|
84
|
+
notification = Notification.new(user,self)
|
85
|
+
|
86
|
+
self.log_message_info(user)
|
87
|
+
|
88
|
+
context = get_context(user,self,notification)
|
89
|
+
|
90
|
+
return({msg: self, user: user, notification: notification, context: context}) if debug
|
91
|
+
|
92
|
+
unless empty_thread_from_ad?
|
93
|
+
|
94
|
+
called_action = context.run
|
95
|
+
if Kogno::Application.config.store_log_in_database
|
96
|
+
message_log_id = user.log_message(self).id
|
97
|
+
else
|
98
|
+
message_chat_log_id = 0
|
99
|
+
end
|
100
|
+
|
101
|
+
notification.send
|
102
|
+
|
103
|
+
response_log_id = 0
|
104
|
+
if Kogno::Application.config.store_log_in_database
|
105
|
+
response_log = user.log_response(notification)
|
106
|
+
response_log_id = response_log.id unless response_log.nil?
|
107
|
+
end
|
108
|
+
|
109
|
+
# user.set_last_usage
|
110
|
+
user.save_session_vars
|
111
|
+
context.handle_message_from_memory
|
112
|
+
|
113
|
+
else
|
114
|
+
context.run_class_callbacks_only
|
115
|
+
user.save_session_vars
|
116
|
+
user.log_message(self) if Kogno::Application.config.store_log_in_database
|
117
|
+
end
|
118
|
+
logger.write "- Current user context: #{user.context}", :blue unless user.context.nil?
|
119
|
+
|
120
|
+
rescue StandardError => e
|
121
|
+
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
|
122
|
+
logger.write e.message, :red
|
123
|
+
logger.write "Error Token: #{error_token}", :red
|
124
|
+
logger.write "Backtrace:\n\t#{e.backtrace.join("\n\t")}", :red
|
125
|
+
ErrorHandler.notify_by_slack(Kogno::Application.config.app_name,e, error_token) if Kogno::Application.config.error_notifier.slack[:enable] rescue false
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
module Kogno
|
2
|
+
module WhatsApp
|
3
|
+
class Notification < Kogno::Notification
|
4
|
+
|
5
|
+
def send(recipient_id=nil,delete=true)
|
6
|
+
recipient_id = @recipient.psid if recipient_id.nil?
|
7
|
+
page_id = @recipient.page_id if page_id.nil?
|
8
|
+
messages = @before_messages+@messages+@after_messages
|
9
|
+
@message_log = messages
|
10
|
+
messages.each do |message|
|
11
|
+
if message[:type].to_sym == :action
|
12
|
+
sleep(message[:value][:duration]) if message[:value][:action].to_sym == :typing_on
|
13
|
+
else
|
14
|
+
message = self.replace_place_holders(message[:value])
|
15
|
+
@response_log << Api::send(recipient_id,message)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
self.delete_messages() if delete
|
19
|
+
@recipient.mark_last_message_as_unread unless @recipient.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
def text(text, extra_params={})
|
23
|
+
extra_params = {preview_url: false}.merge(extra_params)
|
24
|
+
params = {
|
25
|
+
type: :text,
|
26
|
+
text: {
|
27
|
+
body: text
|
28
|
+
}.merge(extra_params)
|
29
|
+
}
|
30
|
+
self.push_message(params, :message)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def typing_on(duration)
|
35
|
+
self.push_message({:action => :typing_on, :duration => duration}, :action)
|
36
|
+
end
|
37
|
+
|
38
|
+
def whatsapp_template(name, components=[], lang="en_US")
|
39
|
+
self.push_message(Api::template_message(name, components, lang), :message)
|
40
|
+
end
|
41
|
+
|
42
|
+
def button(text, replies, extra_settings={})
|
43
|
+
replies = [replies] if replies.class == Hash
|
44
|
+
settings = {typed_postbacks: Kogno::Application.config.typed_postbacks}.merge(extra_settings) # defaults
|
45
|
+
replies = replies.replace_keys({payload: :id})
|
46
|
+
buttons = replies.map do |reply|
|
47
|
+
{
|
48
|
+
type: :reply,
|
49
|
+
reply: reply
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
set_typed_postbacks(replies.map{|button|
|
54
|
+
[button[:title].to_payload, button[:id]] unless button[:title].nil?
|
55
|
+
}.compact.to_h) if settings[:typed_postbacks]
|
56
|
+
|
57
|
+
self.push_message(Api::interactive_buttons(text, buttons), :message)
|
58
|
+
end
|
59
|
+
|
60
|
+
def quick_reply(text, replies, extra_settings={})
|
61
|
+
self.button(text, replies, extra_settings)
|
62
|
+
end
|
63
|
+
|
64
|
+
def list(params,header={},footer={})
|
65
|
+
params[:sections] = params[:sections].map{|s|
|
66
|
+
{
|
67
|
+
title: s[:title],
|
68
|
+
rows: s[:rows].replace_keys({payload: :id})
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
params[:header] = header unless header.empty?
|
73
|
+
params[:footer] = footer unless footer.empty?
|
74
|
+
|
75
|
+
self.push_message(Api::interactive_list(params), :message)
|
76
|
+
end
|
77
|
+
|
78
|
+
def url(params)
|
79
|
+
self.raw(
|
80
|
+
{
|
81
|
+
type: :image,
|
82
|
+
image: {
|
83
|
+
link: params[:image],
|
84
|
+
caption: "#{params[:title]}\n#{params[:sub_title]}\n#{params[:url]}"
|
85
|
+
}
|
86
|
+
}
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
def location(params)
|
91
|
+
self.push_message(Api::location(params), :message)
|
92
|
+
end
|
93
|
+
|
94
|
+
def image(params)
|
95
|
+
# params = params.replace_keys({url: :link})
|
96
|
+
if params[:buttons].nil?
|
97
|
+
|
98
|
+
self.raw(
|
99
|
+
{
|
100
|
+
type: :image,
|
101
|
+
image: {
|
102
|
+
link: params[:url],
|
103
|
+
caption: params[:caption]
|
104
|
+
}
|
105
|
+
}
|
106
|
+
)
|
107
|
+
|
108
|
+
else
|
109
|
+
|
110
|
+
buttons = params[:buttons]
|
111
|
+
buttons = [buttons] if buttons.class == Hash
|
112
|
+
buttons = buttons.replace_keys({payload: :id})
|
113
|
+
replies = buttons.map do |reply|
|
114
|
+
{
|
115
|
+
type: :reply,
|
116
|
+
reply: reply
|
117
|
+
}
|
118
|
+
end
|
119
|
+
self.raw(
|
120
|
+
{
|
121
|
+
type: :interactive,
|
122
|
+
interactive: {
|
123
|
+
type: :button,
|
124
|
+
header: {
|
125
|
+
type: :image,
|
126
|
+
image: {
|
127
|
+
link: params[:url]
|
128
|
+
}
|
129
|
+
},
|
130
|
+
body:{
|
131
|
+
text: params[:caption]
|
132
|
+
},
|
133
|
+
action:{
|
134
|
+
buttons: replies
|
135
|
+
}
|
136
|
+
}
|
137
|
+
}
|
138
|
+
)
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
def video(params)
|
145
|
+
|
146
|
+
if params[:buttons].nil?
|
147
|
+
|
148
|
+
self.raw(
|
149
|
+
{
|
150
|
+
type: :video,
|
151
|
+
video: {
|
152
|
+
link: params[:url],
|
153
|
+
caption: params[:caption]
|
154
|
+
}
|
155
|
+
}
|
156
|
+
)
|
157
|
+
|
158
|
+
else
|
159
|
+
|
160
|
+
buttons = params[:buttons]
|
161
|
+
buttons = [buttons] if buttons.class == Hash
|
162
|
+
buttons = buttons.replace_keys({payload: :id})
|
163
|
+
replies = buttons.map do |reply|
|
164
|
+
{
|
165
|
+
type: :reply,
|
166
|
+
reply: reply
|
167
|
+
}
|
168
|
+
end
|
169
|
+
self.raw(
|
170
|
+
{
|
171
|
+
type: :interactive,
|
172
|
+
interactive: {
|
173
|
+
type: :button,
|
174
|
+
header: {
|
175
|
+
type: :video,
|
176
|
+
video: {
|
177
|
+
link: params[:url]
|
178
|
+
}
|
179
|
+
},
|
180
|
+
body:{
|
181
|
+
text: params[:caption]
|
182
|
+
},
|
183
|
+
action:{
|
184
|
+
buttons: replies
|
185
|
+
}
|
186
|
+
}
|
187
|
+
}
|
188
|
+
)
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
def document(params)
|
195
|
+
self.push_message(Api::media(:document, params), :message)
|
196
|
+
end
|
197
|
+
|
198
|
+
def contact(params)
|
199
|
+
self.push_message(Api::contacts(params), :message)
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Kogno
|
2
|
+
module WhatsApp
|
3
|
+
class StatusMessage < 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
|
+
:whatsapp
|
18
|
+
end
|
19
|
+
|
20
|
+
def status_raw
|
21
|
+
@data[:statuses][0]
|
22
|
+
end
|
23
|
+
|
24
|
+
def status
|
25
|
+
self.status_raw[:status]
|
26
|
+
end
|
27
|
+
|
28
|
+
def metadata
|
29
|
+
@data[:metadata]
|
30
|
+
end
|
31
|
+
|
32
|
+
def sender_id
|
33
|
+
return self.status_raw[:recipient_id]
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def handle_event(debug=false)
|
38
|
+
|
39
|
+
begin
|
40
|
+
|
41
|
+
user = User.find_or_create_by_psid(self.sender_id, :whatsapp)
|
42
|
+
if self.status == "read"
|
43
|
+
user.mark_last_message_as_read
|
44
|
+
end
|
45
|
+
|
46
|
+
rescue StandardError => e
|
47
|
+
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
|
48
|
+
logger.write e.message, :red
|
49
|
+
logger.write "Error Token: #{error_token}", :red
|
50
|
+
logger.write "Backtrace:\n\t#{e.backtrace.join("\n\t")}", :red
|
51
|
+
ErrorHandler.notify_by_slack(Kogno::Application.config.app_name,e, error_token) if Kogno::Application.config.error_notifier.slack[:enable] rescue false
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Kogno
|
2
|
+
|
3
|
+
Dir[File.join(Application.project_path,'config','*.rb')].each do |required_file|
|
4
|
+
require required_file
|
5
|
+
end
|
6
|
+
|
7
|
+
Dir[File.join(Application.project_path,'config','platforms','*.rb')].each do |required_file|
|
8
|
+
require required_file
|
9
|
+
end
|
10
|
+
|
11
|
+
Dir[File.join(Application.project_path,'config','initializers','*.rb')].each do |required_file|
|
12
|
+
require required_file
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class LongPayload < ActiveRecord::Base
|
2
|
+
self.table_name = "kogno_long_payloads"
|
3
|
+
before_create :generate_token
|
4
|
+
|
5
|
+
def generate_token
|
6
|
+
self.token = Digest::MD5.hexdigest "#{Time.now}#{rand(100000)}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.set(data)
|
10
|
+
data = data.split(":",2)
|
11
|
+
payload = data[0]
|
12
|
+
params = data[1]
|
13
|
+
payload_param = create(payload: payload, params: params)
|
14
|
+
return payload_param.token
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get(token)
|
18
|
+
payload = find_by_token(token)
|
19
|
+
unless payload.nil?
|
20
|
+
return ("#{payload.payload}:#{payload.params}")
|
21
|
+
else
|
22
|
+
return {}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class MessengerRecurringNotification < ActiveRecord::Base
|
2
|
+
self.table_name = "kogno_messenger_recurring_notifications"
|
3
|
+
belongs_to :user
|
4
|
+
|
5
|
+
def data
|
6
|
+
{
|
7
|
+
token: self.token,
|
8
|
+
frecuency: self.frecuency,
|
9
|
+
expires_at: self.expires_at,
|
10
|
+
token_status: self.token_status,
|
11
|
+
timezone: self.timezone,
|
12
|
+
status: self.active ? :active : :stopped
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class ScheduledMessage < ActiveRecord::Base
|
2
|
+
self.table_name = "kogno_scheduled_messages"
|
3
|
+
belongs_to :user
|
4
|
+
|
5
|
+
def self.process_all(sleep=60)
|
6
|
+
loop do
|
7
|
+
scheduled_messages = where("'#{Time.now.utc}' > send_at").includes(:user).order(:send_at)
|
8
|
+
scheduled_messages.each do |scheduled_message|
|
9
|
+
if scheduled_message.user.last_usage > Kogno::Application.config.sequences.time_elapsed_after_last_usage
|
10
|
+
scheduled_message.execute
|
11
|
+
else
|
12
|
+
logger.write "User ID #{scheduled_message.user.psid} wrote us recently, let's wait #{Kogno::Application.config.sequences.time_elapsed_after_last_usage - scheduled_message.user.last_usage} seconds before bother him.", :green
|
13
|
+
end
|
14
|
+
end
|
15
|
+
scheduled_messages.destroy_all
|
16
|
+
sleep(sleep)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute
|
21
|
+
if self.user.platform == "messenger"
|
22
|
+
notification = Kogno::Messenger::Notification.new(self.user)
|
23
|
+
elsif self.user.platform == "telegram"
|
24
|
+
notification = Kogno::Telegram::Notification.new(self.user)
|
25
|
+
elsif self.user.platform == "whatsapp"
|
26
|
+
notification = Kogno::WhatsApp::Notification.new(self.user)
|
27
|
+
else
|
28
|
+
logger.write "Platform '#{self.user.platform} not supported. User ID: #{self.user.id}"
|
29
|
+
notification = nil
|
30
|
+
end
|
31
|
+
unless notification.nil?
|
32
|
+
notification.import_messages(self.messages)
|
33
|
+
logger.write "Sending scheduled messages to #{self.user.psid}..", :green
|
34
|
+
logger.write_json JSON.parse(self.messages), :bright
|
35
|
+
notification.send
|
36
|
+
self.user.log_response(notification,true) if Kogno::Application.config.store_log_in_database
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Sequence < ActiveRecord::Base
|
2
|
+
self.table_name = "kogno_sequences"
|
3
|
+
belongs_to :user
|
4
|
+
before_create :set_last_hit_at
|
5
|
+
|
6
|
+
def set_last_hit_at
|
7
|
+
self.last_hit_at = Time.now.utc
|
8
|
+
end
|
9
|
+
|
10
|
+
def route
|
11
|
+
"#{context}.#{stage}"
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def self.process_all(sleep=60)
|
16
|
+
loop do
|
17
|
+
actions = where("'#{Time.now.utc}' > execution_time or execution_time is null").includes(:user).order(:execution_time)
|
18
|
+
actions.each do |action|
|
19
|
+
if action.user.last_usage > Kogno::Application.config.sequences.time_elapsed_after_last_usage
|
20
|
+
Kogno::Context.run_sequence(action)
|
21
|
+
else
|
22
|
+
logger.write "User ID #{action.user.psid} wrote us recently, let's wait #{Kogno::Application.config.sequences.time_elapsed_after_last_usage - action.user.last_usage} seconds before bother him.", :green
|
23
|
+
end
|
24
|
+
end
|
25
|
+
sleep(sleep)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class TelegramChatGroup < ActiveRecord::Base
|
2
|
+
self.table_name = "kogno_telegram_chat_groups"
|
3
|
+
belongs_to :user, foreign_key: :inviter_user_id
|
4
|
+
|
5
|
+
def type
|
6
|
+
self.kind.to_sym
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.find_or_create(args)
|
10
|
+
chat = find_by_chat_id(args[:chat_id])
|
11
|
+
if chat.nil?
|
12
|
+
chat = create(args)
|
13
|
+
else
|
14
|
+
chat.update(args)
|
15
|
+
end
|
16
|
+
return chat
|
17
|
+
end
|
18
|
+
|
19
|
+
def notification
|
20
|
+
if @notification.nil?
|
21
|
+
@notification = Kogno::Telegram::Notification.new(self)
|
22
|
+
end
|
23
|
+
@notification
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|