chatgpt_assistant 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "helpers/discord_helper"
4
+ require_relative "helpers/discord_voice_helper"
5
+
3
6
  module ChatgptAssistant
4
7
  # This class is responsible to handle the discord bot
5
8
  class DiscordBot < ApplicationBot
@@ -21,274 +24,132 @@ module ChatgptAssistant
21
24
 
22
25
  private
23
26
 
24
- attr_reader :message
25
- attr_accessor :evnt, :user, :chats, :chat
27
+ include DiscordHelper
28
+ include DiscordVoiceHelper
26
29
 
27
- def bot
28
- @bot ||= Discordrb::Commands::CommandBot.new(
29
- token: discord_token,
30
- client_id: discord_client_id,
31
- prefix: discord_prefix
32
- )
33
- end
30
+ attr_reader :message
31
+ attr_accessor :evnt, :user, :chats, :chat
34
32
 
35
- def start_event
36
- bot.command :start do |event|
37
- @evnt = event
38
- @user = event.user
39
- start_action
33
+ def start_event
34
+ bot.command :start do |event|
35
+ @evnt = event
36
+ @user = event.user
37
+ start_action
38
+ end
40
39
  end
41
- end
42
-
43
- def start_action
44
- evnt.respond commom_messages[:start_helper].gsub("register/", "gpt!register ")
45
- evnt.respond commom_messages[:start_sec_helper].gsub("login/", "gpt!login ")
46
- end
47
40
 
48
- def login_event
49
- bot.command :login do |event|
50
- @message = event.message.content.split(" ")[1]
51
- @evnt = event
52
- message.nil? ? event.respond(commom_messages[:login]) : login_action
41
+ def login_event
42
+ bot.command :login do |event|
43
+ @message = event.message.content.split[1]
44
+ @evnt = event
45
+ message.nil? ? event.respond(commom_messages[:login]) : login_action
46
+ end
53
47
  end
54
- end
55
48
 
56
- def login_action
57
- user_email = message.split(":")[0]
58
- user_password = message.split(":")[1]
59
- case auth_userdiscord(user_email, user_password, evnt.user.id)
60
- when "user not found"
61
- evnt.respond error_messages[:user_not_found]
62
- when "wrong password"
63
- evnt.respond error_messages[:wrong_password]
64
- when find_useremail(user_email)
65
- evnt.respond success_messages[:user_logged_in]
49
+ def register_event
50
+ bot.command :register do |event|
51
+ @message = event.message.content.split[1]
52
+ @evnt = event
53
+ message.nil? ? event.respond(commom_messages[:register]) : register_action
54
+ end
66
55
  end
67
- end
68
56
 
69
- def register_event
70
- bot.command :register do |event|
71
- @message = event.message.content.split(" ")[1]
72
- @evnt = event
73
- message.nil? ? event.respond(commom_messages[:register]) : register_action
57
+ def list_event
58
+ bot.command :list do |event|
59
+ @evnt = event
60
+ @user = find_user(discord_id: event.user.id)
61
+ event.respond error_messages[:user_not_logged_in] if user.nil?
62
+ event.respond error_messages[:chat_not_found] if user.chats.empty? && user
63
+ list_action if user && !user.chats.empty?
64
+ end
74
65
  end
75
- end
76
-
77
- def register_action
78
- user_email = message.split(":")[0]
79
- user_password = message.split(":")[1]
80
- find_useremail(user_email).nil? ? create_user_action(user_email, user_password) : evnt.respond(error_messages[:user_already_exists])
81
- end
82
-
83
- def create_user_action(mail, pass)
84
- id = evnt.user.id
85
- name = evnt.user.username
86
- discord_user_create(id, mail, pass, name) ? evnt.respond(success_messages[:user_created]) : evnt.respond(error_messages[:user_not_created])
87
- end
88
-
89
- def list_event
90
- bot.command :list do |event|
91
- @evnt = event
92
- @user = find_userdiscord(event.user.id)
93
- event.respond error_messages[:user_not_logged_in] if user.nil?
94
- event.respond error_messages[:chat_not_found] if user.chats.empty? && user
95
- list_action if user && !user.chats.empty?
96
- end
97
- end
98
66
 
99
- def list_action
100
- chats_title = user.chats.map(&:title)
101
- evnt.respond commom_messages[:chat_list]
102
- evnt.respond chats_title.join("\n")
103
- end
104
-
105
- def hist_event
106
- bot.command :hist do |event|
107
- @evnt = event
108
- @user = find_userdiscord(event.user.id)
109
- event.respond error_messages[:user_not_logged_in] if user.nil?
110
- title = event.message.content.split(" ")[1..].join(" ")
111
- @chat = user.chat_by_title(title)
112
- event.respond error_messages[:chat_not_found] if chat.nil? && user
113
- hist_action if user && chat
67
+ def hist_event
68
+ bot.command :hist do |event|
69
+ @evnt = event
70
+ event.respond error_messages[:user_not_logged_in] if user.nil?
71
+ title = event.message.content.split[1..].join(" ")
72
+ @chat = user.chat_by_title(title)
73
+ event.respond error_messages[:chat_not_found] if chat.nil? && user
74
+ hist_action if user && chat
75
+ end
114
76
  end
115
- end
116
77
 
117
- def hist_action
118
- messages = Message.where(chat_id: chat.id).order(:created_at)
119
- messages.each do |message|
120
- evnt.respond "#{message.role} - #{message.content}\n#{message.created_at.strftime("%d/%m/%Y %H:%M")}"
78
+ def help_event
79
+ bot.command :help do |event|
80
+ @evnt = event
81
+ help_action
82
+ end
121
83
  end
122
- "This is the end of the chat history"
123
- end
124
84
 
125
- def help_event
126
- bot.command :help do |event|
127
- @evnt = event
128
- help_action
85
+ def new_chat_event
86
+ bot.command :new_chat do |event|
87
+ @evnt = event
88
+ @user = find_user(discord_id: event.user.id)
89
+ event.respond error_messages[:user_not_logged_in] if user.nil?
90
+ create_chat_action if user
91
+ end
129
92
  end
130
- end
131
93
 
132
- def help_action
133
- message = help_messages.join("\n").gsub(" /", discord_prefix)
134
- .gsub("register/", "#{discord_prefix}register ")
135
- .gsub("login/", "#{discord_prefix}login ")
136
- .gsub("new_chat/", "#{discord_prefix}new_chat/")
137
- .gsub("sl_chat/", "#{discord_prefix}sl_chat/")
138
- evnt.respond message
139
- end
94
+ def sl_chat_event
95
+ bot.command :sl_chat do |event|
96
+ @evnt = event
97
+ chat_to_select = event.message.content.split[1..].join(" ")
98
+ @user = find_user(discord_id: event.user.id)
99
+ event.respond error_messages[:user_not_logged_in] if user.nil?
140
100
 
141
- def new_chat_event
142
- bot.command :new_chat do |event|
143
- @evnt = event
144
- @user = find_userdiscord(event.user.id)
145
- event.respond error_messages[:user_not_logged_in] if user.nil?
146
- create_chat_action if user
101
+ sl_chat_action(chat_to_select) if user
102
+ end
147
103
  end
148
- end
149
104
 
150
- def create_chat_action
151
- chat_title = evnt.message.content.split(" ")[1..].join(" ")
152
- @chat = Chat.new(user_id: user.id, title: chat_title, status: 0)
153
- chat.save ? respond_with_success : evnt.respond(error_messages[:chat_creation])
154
- end
155
-
156
- def respond_with_success
157
- user.update(current_chat_id: chat.id)
158
- evnt.respond success_messages[:chat_created]
159
- end
160
-
161
- def sl_chat_event
162
- bot.command :sl_chat do |event|
163
- @evnt = event
164
- chat_to_select = event.message.content.split(" ")[1..].join(" ")
165
- @user = find_userdiscord(event.user.id)
166
- event.respond error_messages[:user_not_logged_in] if user.nil?
167
-
168
- sl_chat_action(chat_to_select) if user
105
+ def ask_event
106
+ bot.command :ask do |event|
107
+ @evnt = event
108
+ @message = event.message.content.split[1..].join(" ")
109
+ @user = find_user(discord_id: event.user.id)
110
+ event.respond error_messages[:user_not_logged_in] if user.nil?
111
+ ask_action if user
112
+ end
169
113
  end
170
- end
171
-
172
- def sl_chat_action(chat_to_select)
173
- @chat = user.chat_by_title(chat_to_select)
174
- evnt.respond error_messages[:chat_not_found] if chat.nil?
175
- user.update(current_chat_id: chat.id) if chat
176
- evnt.respond success_messages[:chat_selected] if chat
177
- end
178
114
 
179
- def ask_event
180
- bot.command :ask do |event|
181
- @evnt = event
182
- @message = event.message.content.split(" ")[1..].join(" ")
183
- @user = find_userdiscord(event.user.id)
184
- event.respond error_messages[:user_not_logged_in] if user.nil?
185
- ask_action if user
115
+ def voice_connect_event
116
+ bot.command :connect do |event|
117
+ @evnt = event
118
+ @user = find_user(discord_id: event.user.id)
119
+ @chat = Chat.where(id: user.current_chat_id).last
120
+ voice_connect_checker_action
121
+ voice_connection_checker_action
122
+ discord_voice_bot_connect
123
+ end
186
124
  end
187
- end
188
-
189
- def ask_action
190
- @chat = Chat.where(id: user.current_chat_id).last
191
- evnt.respond error_messages[:chat_not_found] if chat.nil?
192
- @message = Message.new(chat_id: chat.id, content: message, role: "user") if chat
193
- (message.save ? answer_action : evnt.respond(error_messages[:message_not_saved])) if chat
194
- end
195
-
196
- def answer_action
197
- response = chatter.chat(message.content, chat.id)
198
- evnt.respond response
199
- end
200
125
 
201
- def voice_connect_event
202
- bot.command :connect do |event|
203
- @evnt = event
204
- @user = find_userdiscord(event.user.id)
205
- @chat = Chat.where(id: user.current_chat_id).last
206
- voice_connect_checker_action
207
- voice_connection_checker_action
208
- bot.voice_connect(event.user.voice_channel) if bot_disconnected?
209
- bot_connected? ? "Connected to voice channel" : "Error connecting to voice channel"
126
+ def disconnect_event
127
+ bot.command :disconnect do |event|
128
+ @evnt = event
129
+ @user = find_user(discord_id: event.user.id)
130
+ disconnect_checker_action
131
+ disconnect_action if user && event.user.voice_channel && event.voice
132
+ end
210
133
  end
211
- end
212
-
213
- def voice_connect_checker_action
214
- evnt.respond error_messages[:user_not_logged_in] if user.nil?
215
- evnt.respond error_messages[:chat_not_found] if user && chat.nil?
216
- end
217
134
 
218
- def voice_connection_checker_action
219
- evnt.respond error_messages[:user_not_in_voice_channel] if evnt.user.voice_channel.nil? && user
220
- evnt.respond error_messages[:bot_already_connected] if evnt.voice && user
221
- end
222
-
223
- def bot_disconnected?
224
- user && evnt.user.voice_channel && !evnt.voice && !chat.nil?
225
- end
226
-
227
- def bot_connected?
228
- user && evnt.user.voice_channel && evnt.voice && !chat.nil?
229
- end
230
-
231
- def disconnect_event
232
- bot.command :disconnect do |event|
233
- @evnt = event
234
- @user = find_userdiscord(event.user.id)
235
- disconnect_checker_action
236
- disconnect_action if user && event.user.voice_channel && event.voice
135
+ def speak_event
136
+ bot.command :speak do |event|
137
+ @evnt = event
138
+ @message = event.message.content.split[1..].join(" ")
139
+ @user = find_user(discord_id: event.user.id)
140
+ @chat = user.current_chat
141
+ speak_connect_checker_action
142
+ speak_connection_checker_action
143
+ ask_to_speak_action if user && event.user.voice_channel && event.voice && !chat.nil?
144
+ end
237
145
  end
238
- end
239
146
 
240
- def disconnect_checker_action
241
- evnt.respond error_messages[:user_not_logged_in] if user.nil?
242
- evnt.respond error_messages[:user_not_in_voice_channel] if evnt.user.voice_channel.nil? && user
243
- evnt.respond error_messages[:user_not_connected] if !evnt.voice && user
244
- end
245
-
246
- def disconnect_action
247
- bot.voice_destroy(evnt.user.voice_channel)
248
- "Disconnected from voice channel"
249
- end
250
-
251
- def speak_event
252
- bot.command :speak do |event|
253
- @evnt = event
254
- @message = event.message.content.split(" ")[1..].join(" ")
255
- @user = find_userdiscord(event.user.id)
256
- @chat = user.current_chat
257
- speak_connect_checker_action
258
- speak_connection_checker_action
259
- ask_to_speak_action if user && event.user.voice_channel && event.voice && !chat.nil?
147
+ def bot_init
148
+ at_exit { bot.stop }
149
+ bot.run
150
+ rescue StandardError => e
151
+ Error.create(message: e.message, backtrace: e.backtrace)
152
+ retry
260
153
  end
261
- end
262
-
263
- def speak_connect_checker_action
264
- evnt.respond error_messages[:user_not_logged_in] if user.nil?
265
- evnt.respond error_messages[:chat_not_found] if user && evnt.user.voice_channel && evnt.voice && chat.nil?
266
- end
267
-
268
- def speak_connection_checker_action
269
- evnt.respond error_messages[:user_not_in_voice_channel] if evnt.user.voice_channel.nil? && user
270
- evnt.respond error_messages[:bot_not_in_voice_channel] if !evnt.voice && user
271
- end
272
-
273
- def ask_to_speak_action
274
- Message.create(chat_id: chat.id, content: message, role: "user")
275
- response = chatter.chat(message, chat.id)
276
- audio_path = audio_synthesis.synthesize_text(response)
277
- speak_answer_action(audio_path, response)
278
- end
279
-
280
- def speak_answer_action(audio_path, response)
281
- evnt.respond response
282
- evnt.voice.play_file(audio_path)
283
- delete_all_voice_files
284
- "OK"
285
- end
286
-
287
- def bot_init
288
- at_exit { bot.stop }
289
- bot.run
290
- rescue StandardError
291
- start
292
- end
293
154
  end
294
155
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ # Helper for audio
5
+ module AudioHelper
6
+ def recognition
7
+ @recognition ||= AudioRecognition.new(openai_api_key)
8
+ end
9
+
10
+ def synthesis
11
+ @synthesis ||= AudioSynthesis.new(config)
12
+ end
13
+
14
+ def transcribe_file(url)
15
+ recognition.transcribe_audio(url)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ # Helper for authentication
5
+ module AuthenticationHelper
6
+ def valid_password?(password, hash, salt)
7
+ BCrypt::Engine.hash_secret(password, salt) == hash
8
+ end
9
+
10
+ def telegram_user_auth(email, password, telegram_id)
11
+ return "wrong password" if password.nil?
12
+
13
+ visitor_access = find_visitor(telegram_id: telegram_id)
14
+ return "something went wrong" unless visitor_access
15
+
16
+ new_access = find_user(email: email)
17
+ return "user not found" unless new_access
18
+
19
+ hash = new_access.password_hash
20
+ salt = new_access.password_salt
21
+ valid_password?(password, hash, salt) ? telegram_user_access(visitor_access, new_access) : "wrong password"
22
+ end
23
+
24
+ def telegram_user_access(visitor, new_access)
25
+ other_access = where_user(telegram_id: visitor.telegram_id)
26
+ other_access&.each { |access| access.update(telegram_id: nil) }
27
+ new_access.update(telegram_id: visitor.telegram_id)
28
+ new_access.email
29
+ end
30
+
31
+ def discord_user_auth(email, password, discord_id)
32
+ user = find_user(email: email)
33
+ return "user not found" unless user
34
+ return "wrong passwords" if password.nil?
35
+
36
+ valid_password?(password, user.password_hash, user.password_salt) ? discord_user_access(discord_id, user.email) : "wrong password"
37
+ end
38
+
39
+ def discord_user_access(discord_id, user_email)
40
+ last_access = find_user(discord_id: discord_id)
41
+ new_access = find_user(email: user_email)
42
+ last_acess.update(discord_id: nil) if last_access&.email != new_access&.email
43
+ new_access&.update(discord_id: discord_id)
44
+ new_access.email
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ # Helper for discord
5
+ module DiscordHelper
6
+ def bot
7
+ @bot ||= Discordrb::Commands::CommandBot.new(
8
+ token: discord_token,
9
+ client_id: discord_client_id,
10
+ prefix: discord_prefix
11
+ )
12
+ end
13
+
14
+ def start_action
15
+ send_message commom_messages[:start_helper].gsub("register/", "gpt!register ")
16
+ send_message commom_messages[:start_sec_helper].gsub("login/", "gpt!login ")
17
+ end
18
+
19
+ def login_action
20
+ user_email, user_password = message.split(":")
21
+ case discord_user_auth(user_email, user_password, evnt.user.id)
22
+ when "user not found"
23
+ send_message error_messages[:user_not_found]
24
+ when "wrong password"
25
+ puts "wrong password"
26
+ send_message error_messages[:wrong_password]
27
+ when find_user(email: user_email).email
28
+ send_message success_messages[:user_logged_in]
29
+ end
30
+ end
31
+
32
+ def create_user_action(mail, pass)
33
+ id = evnt.user.id
34
+ return send_message(success_messages[:user_created]) if discord_user_create(id, mail, pass)
35
+
36
+ send_message(error_messages[:user_not_created])
37
+ end
38
+
39
+ def register_action
40
+ user_email = message.split(":")[0]
41
+ user_password = message.split(":")[1]
42
+ return create_user_action(user_email, user_password) if find_user(email: user_email).nil?
43
+
44
+ send_message(error_messages[:user_already_exists])
45
+ end
46
+
47
+ def list_action
48
+ chats_title = user.chats.map(&:title)
49
+ send_message commom_messages[:chat_list]
50
+ send_message chats_title.join("\n")
51
+ end
52
+
53
+ def hist_action
54
+ messages = Message.where(chat_id: chat.id).order(:created_at)
55
+ messages.each { |m| send_message "#{m.role} - #{m.content}\n#{m.created_at.strftime("%d/%m/%Y %H:%M")}" }
56
+ "This is the end of the chat history"
57
+ end
58
+
59
+ def help_action
60
+ message = discord_help_message
61
+ send_message message
62
+ end
63
+
64
+ def ask_action
65
+ @chat = Chat.where(id: user.current_chat_id).last
66
+ send_message error_messages[:chat_not_found] if chat.nil?
67
+ @message = Message.new(chat_id: chat.id, content: message, role: "user") if chat
68
+ (message.save ? answer_action : send_message(error_messages[:message_not_saved])) if chat
69
+ end
70
+
71
+ def sl_chat_action(chat_to_select)
72
+ @chat = user.chat_by_title(chat_to_select)
73
+ send_message error_messages[:chat_not_found] if chat.nil?
74
+ user.update(current_chat_id: chat.id) if chat
75
+ send_message success_messages[:chat_selected] if chat
76
+ end
77
+
78
+ def create_chat_action
79
+ chat_title = evnt.message.content.split[1..].join(" ")
80
+ @chat = Chat.new(user_id: user.id, title: chat_title, status: 0)
81
+ chat.save ? respond_with_success : send_message(error_messages[:chat_creation])
82
+ end
83
+
84
+ def answer_action
85
+ response = chatter.chat(message.content, chat.id)
86
+ send_message response
87
+ end
88
+
89
+ def disconnect_checker_action
90
+ send_message error_messages[:user_not_logged_in] if user.nil?
91
+ send_message error_messages[:user_not_in_voice_channel] if evnt.user.voice_channel.nil? && user
92
+ send_message error_messages[:user_not_connected] if !evnt.voice && user
93
+ end
94
+
95
+ def discord_user_create(discord_id, email, password)
96
+ user = User.new(discord_id: discord_id, email: email, password: password)
97
+ last_access = find_user(discord_id: discord_id)
98
+ last_access&.update(discord_id: nil)
99
+ user.save
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ # Helper for voice actions
5
+ module DiscordVoiceHelper
6
+ def voice_connect_checker_action
7
+ send_message error_messages[:user_not_logged_in] if user.nil?
8
+ send_message error_messages[:chat_not_found] if user && chat.nil?
9
+ end
10
+
11
+ def voice_connection_checker_action
12
+ send_message error_messages[:user_not_in_voice_channel] if evnt.user.voice_channel.nil? && user
13
+ send_message error_messages[:bot_already_connected] if evnt.voice && user
14
+ end
15
+
16
+ def speak_connect_checker_action
17
+ send_message error_messages[:user_not_logged_in] if user.nil?
18
+ send_message error_messages[:chat_not_found] if user && evnt.user.voice_channel && evnt.voice && chat.nil?
19
+ end
20
+
21
+ def speak_connection_checker_action
22
+ send_message error_messages[:user_not_in_voice_channel] if evnt.user.voice_channel.nil? && user
23
+ send_message error_messages[:bot_not_in_voice_channel] if !evnt.voice && user
24
+ end
25
+
26
+ def ask_to_speak_action
27
+ Message.create(chat_id: chat.id, content: message, role: "user")
28
+ response = chatter.chat(message, chat.id)
29
+ audio_path = synthesis.synthesize_text(response)
30
+ speak_answer_action(audio_path, response)
31
+ end
32
+
33
+ def speak_answer_action(audio_path, response)
34
+ send_message response
35
+ evnt.voice.play_file(audio_path)
36
+ delete_file audio_path
37
+ "OK"
38
+ end
39
+
40
+ def discord_voice_bot_connect
41
+ bot.voice_connect(evnt.user.voice_channel) if discord_voice_bot_disconnected?
42
+ discord_voice_bot_connected? ? "Connected to voice channel" : "Error connecting to voice channel"
43
+ end
44
+
45
+ def disconnect_action
46
+ bot.voice_destroy(evnt.user.voice_channel)
47
+ "Disconnected from voice channel"
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ # Helper for files
5
+ module FileHelper
6
+ def delete_file(file)
7
+ File.delete file
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ # Helper for logger action
5
+ module LoggerActionHelper
6
+ def register_visitor_action(action, visitor_id)
7
+ VisitorAction.create(visitor_id: visitor_id, action: action, description: msg.text)
8
+ end
9
+
10
+ def register_user_action(action, user_id)
11
+ UserAction.create(user_id: user_id, action: action, description: msg.text)
12
+ end
13
+ end
14
+ end