chatgpt_assistant 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.env_sample +1 -1
  3. data/.rubocop.yml +4 -4
  4. data/Gemfile +18 -6
  5. data/Gemfile.lock +62 -59
  6. data/README.md +14 -13
  7. data/docker-compose.prod.yml +1 -1
  8. data/docker-compose.yml +18 -0
  9. data/exe/chatgpt_bot +3 -0
  10. data/lib/bots/application_bot.rb +15 -5
  11. data/lib/bots/discord_bot.rb +6 -9
  12. data/lib/bots/helpers/authentication_helper.rb +3 -2
  13. data/lib/bots/helpers/discord_helper.rb +4 -4
  14. data/lib/bots/helpers/messenger_helper.rb +14 -15
  15. data/lib/bots/helpers/search_helper.rb +3 -3
  16. data/lib/bots/helpers/telegram_helper.rb +3 -7
  17. data/lib/bots/helpers/validation_helper.rb +1 -1
  18. data/lib/bots/helpers/visit_helper.rb +4 -0
  19. data/lib/bots/jobs/new_chat_job.rb +17 -0
  20. data/lib/bots/jobs/register_job.rb +16 -0
  21. data/lib/bots/jobs/voice_connect_job.rb +14 -0
  22. data/lib/bots/services/new_chat_service.rb +34 -0
  23. data/lib/bots/services/register_service.rb +36 -0
  24. data/lib/bots/services/voice_connect_service.rb +29 -0
  25. data/lib/bots/telegram_bot.rb +70 -39
  26. data/lib/chatgpt_assistant/config.rb +23 -1
  27. data/lib/chatgpt_assistant/default_messages.rb +72 -30
  28. data/lib/chatgpt_assistant/error.rb +219 -0
  29. data/lib/chatgpt_assistant/models.rb +18 -13
  30. data/lib/chatgpt_assistant/sidekiq.rb +7 -0
  31. data/lib/chatgpt_assistant/sidekiq.yml +10 -0
  32. data/lib/chatgpt_assistant/version.rb +1 -1
  33. data/lib/chatgpt_assistant.rb +3 -12
  34. data/prompts-data/{awesome-chatgpt-prompts.csv → awesome-en-prompts.csv} +164 -164
  35. data/prompts-data/awesome-pt-prompts.csv +164 -0
  36. metadata +14 -5
  37. data/lib/bots/helpers/logger_action_helper.rb +0 -7
@@ -3,15 +3,15 @@
3
3
  module ChatgptAssistant
4
4
  # This class is responsible for storing the default messages
5
5
  class DefaultMessages
6
- def initialize(language = "en")
6
+ def initialize(language = "en", _discord_prefix = "!")
7
7
  @language = language
8
8
  load_message_context
9
9
  end
10
10
 
11
- attr_reader :language, :commom_messages, :success_messages, :error_messages, :help_messages
11
+ attr_reader :language, :common_messages, :success_messages, :error_messages, :help_messages
12
12
 
13
13
  def load_message_context
14
- @commom_messages = send("commom_messages_#{language}")
14
+ @common_messages = send("common_messages_#{language}")
15
15
  @success_messages = send("success_messages_#{language}")
16
16
  @error_messages = send("error_messages_#{language}")
17
17
  @help_messages = send("help_messages_#{language}")
@@ -19,7 +19,7 @@ module ChatgptAssistant
19
19
 
20
20
  private
21
21
 
22
- def commom_messages_pt
22
+ def common_messages_pt
23
23
  {
24
24
  start: "Olá, eu sou o Chatgpt Assistant, um chatbot que usa a API da OpenAI para responder suas perguntas no Telegram e Discord.",
25
25
  stop: "Até mais!",
@@ -42,6 +42,7 @@ module ChatgptAssistant
42
42
  chat_created: "Chat criado com sucesso!",
43
43
  chat_selected: "Chat selecionado com sucesso!",
44
44
  user_logged_in: "Login realizado com sucesso!",
45
+ user_logged_out: "Logout realizado com sucesso!",
45
46
  voice_channel_connected: "O bot entrou no canal de voz com sucesso!"
46
47
  }
47
48
  end
@@ -49,26 +50,34 @@ module ChatgptAssistant
49
50
  def error_messages_pt
50
51
  {
51
52
  nil: "Não entendi o que você disse. Tente novamente",
52
- email: "O email que você digitou não é válido. Tente novamente",
53
- password: "A senha que você digitou não é válida. Tente novamente",
53
+ wrong_email: "O email que você digitou não é válido. Tente novamente",
54
54
  wrong_password: "A senha que você digitou não é válida. Tente novamente",
55
- user: "O usuário que você digitou não existe. Tente novamente",
56
- user_creation: "Erro ao criar usuário. Tente novamente",
55
+
57
56
  user_already_exists: "O usuário que você digitou já existe. Tente novamente",
58
- chat_creation: "Erro ao criar chat. Tente novamente",
59
- no_messages_founded: "Nenhuma mensagem encontrada",
57
+ chat_already_exists: "Você possui um chat com este titulo. Tente novamente",
58
+
59
+ no_register_info: "Você não digitou o email e a senha. Tente novamente",
60
+ sign_up_error: "Erro ao criar usuário. Tente novamente",
61
+ chat_not_created_error: "Erro ao criar chat. Tente novamente",
62
+ message_not_created_error: "Erro ao criar mensagem. Tente novamente",
60
63
  no_chat_selected: "Nenhum chat selecionado",
61
- chat_not_found: "Chat não encontrado",
64
+
65
+ no_messages_founded: "Nenhuma mensagem encontrada",
62
66
  no_chats_founded: "Nenhum chat encontrado",
67
+ chat_not_found: "Chat não encontrado",
68
+ user_not_found: "O usuário que você digitou não existe. Tente novamente",
69
+ user_not_registered: "O usuário não está registrado no sistema",
70
+ user_logged_in: "Usuário está logado no sistema, faça logout para continuar",
63
71
  user_not_logged_in: "Usuário não logado",
64
- user_not_found: "Usuário não encontrado",
65
- something_went_wrong: "Algo deu errado. Tente novamente mais tarde.",
66
- message_history_too_long: "O histórico mensagem é muito longo.",
67
- text_length: "O texto de resposta é muito longo. Tente diminuir a quantidade de respostas na mesma mensagem.",
72
+
68
73
  user_not_in_voice_channel: "Você não está em um canal de voz.",
69
74
  bot_not_in_voice_channel: "O bot não está em um canal de voz.",
75
+
76
+ message_history_too_long: "O histórico mensagem é muito longo.",
77
+ text_length_too_long: "O texto de resposta é muito longo. Tente diminuir a quantidade de respostas na mesma mensagem.",
78
+
70
79
  invalid_command: "Comando inválido. Tente novamente.",
71
- message_creation_error: "Erro ao criar mensagem. Tente novamente."
80
+ something_went_wrong: "Algo deu errado. Tente novamente mais tarde."
72
81
  }
73
82
  end
74
83
 
@@ -83,7 +92,18 @@ module ChatgptAssistant
83
92
  "Para ver esta mensagem novamente, digite /help"]
84
93
  end
85
94
 
86
- def commom_messages_en
95
+ def help_message_discord_pt
96
+ ["Para começar a conversar comigo, digite #{discord_prefix}start",
97
+ "Para parar de conversar comigo, digite #{discord_prefix}stop",
98
+ "Para se registrar no sistema, digite #{discord_prefix}register email:senha (a senha deve ser um numero de 4 digitos ex: 1234)",
99
+ "Para fazer login no sistema, digite #{discord_prefix}login email:senha (a senha deve ser um numero de 4 digitos ex: 1234)",
100
+ "Para criar um novo chat, digite #{discord_prefix}new_chat nome do chat",
101
+ "Para selecionar um chat, digite #{discord_prefix}sl_chat nome do chat",
102
+ "Para listar os chats que você criou, digite #{discord_prefix}list",
103
+ "Para ver esta mensagem novamente, digite #{discord_prefix}help"]
104
+ end
105
+
106
+ def common_messages_en
87
107
  {
88
108
  start: "Hello, I'm the Chatgpt Assistant, a chatbot that uses the OpenAI API to answer your questions on Telegram and Discord.",
89
109
  stop: "See you later!",
@@ -105,32 +125,43 @@ module ChatgptAssistant
105
125
  user_created: "User created successfully!",
106
126
  chat_created: "Chat created successfully!",
107
127
  chat_selected: "Chat selected successfully!",
108
- user_logged_in: "Login successfully!"
128
+ user_logged_in: "Login successfully!",
129
+ user_logged_out: "Logout successfully!",
130
+ voice_channel_connected: "The bot entered the voice channel successfully!"
109
131
  }
110
132
  end
111
133
 
112
134
  def error_messages_en
113
135
  {
114
- nil: "I didn't understand what you said. Try again",
115
- email: "The email you typed is not valid. Try again",
116
- password: "The password you typed is not valid. Try again",
136
+ nil: "I don't understand what you said. Try again",
137
+ wrong_email: "The email you typed is not valid. Try again",
117
138
  wrong_password: "The password you typed is not valid. Try again",
118
- user: "The user you typed does not exist. Try again",
119
- user_creation: "Error creating user. Try again",
120
- chat_creation: "Error creating chat. Try again",
121
- no_messages_founded: "No messages found",
139
+
140
+ user_already_exists: "The user you typed already exists. Try again",
141
+ chat_already_exists: "You already have a chat with this title. Try again",
142
+
143
+ no_register_info: "You did not type the email and password. Try again",
144
+ sign_up_error: "Error creating user. Try again",
145
+ chat_not_created_error: "Error creating chat. Try again",
146
+ message_not_created_error: "Error creating message. Try again",
122
147
  no_chat_selected: "No chat selected",
148
+
149
+ no_messages_founded: "No messages found",
123
150
  no_chats_founded: "No chats found",
124
151
  chat_not_found: "Chat not found",
152
+ user_not_found: "The user you typed does not exist. Try again",
153
+ user_not_registered: "The user is not registered in the system",
154
+ user_logged_in: "User is logged in the system, do logout to continue",
125
155
  user_not_logged_in: "User not logged in",
126
- user_not_found: "User not found",
127
- something_went_wrong: "Something went wrong. Try again later.",
128
- message_history_too_long: "The message history is too long.",
129
- text_length: "The response text is too long. Try to reduce the number of answers in the same message.",
156
+
130
157
  user_not_in_voice_channel: "You are not in a voice channel.",
131
158
  bot_not_in_voice_channel: "The bot is not in a voice channel.",
159
+
160
+ message_history_too_long: "The message history is too long.",
161
+ text_length_too_long: "The response text is too long. Try to reduce the number of responses in the same message.",
162
+
132
163
  invalid_command: "Invalid command. Try again.",
133
- message_creation_error: "Error creating message. Try again."
164
+ something_went_wrong: "Something went wrong. Try again later."
134
165
  }
135
166
  end
136
167
 
@@ -144,5 +175,16 @@ module ChatgptAssistant
144
175
  "To list the chats you created, type /list",
145
176
  "To see this message again, type /help"]
146
177
  end
178
+
179
+ def help_message_discord_en
180
+ ["To start talking to me, type #{discord_prefix}start",
181
+ "To stop talking to me, type #{discord_prefix}stop",
182
+ "To register in the system, type #{discord_prefix}register email:password (the password must be a 4 digit number ex: 1234)",
183
+ "To log in to the system, type #{discord_prefix}login email:password (the password must be a 4 digit number ex: 1234)",
184
+ "To create a new chat, type #{discord_prefix}new_chat chat name",
185
+ "To select a chat, type #{discord_prefix}sl_chat chat name",
186
+ "To list the chats you created, type #{discord_prefix}list",
187
+ "To see this message again, type #{discord_prefix}help"]
188
+ end
147
189
  end
148
190
  end
@@ -0,0 +1,219 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ # Load Error
5
+ module LoadError
6
+ def load_error_context
7
+ language = ENV.fetch("LANGUAGE", "en")
8
+ discord_prefix = ENV.fetch("DISCORD_PREFIX", "!")
9
+ DefaultMessages.new(language, discord_prefix).error_messages
10
+ end
11
+ end
12
+
13
+ # No User Error
14
+ class NoRegisterInfoError < StandardError
15
+ def initialize(message = load_error_context[:no_register_info])
16
+ super(message)
17
+ end
18
+
19
+ include LoadError
20
+ end
21
+
22
+ # Nil Command Error
23
+ class NilError < StandardError
24
+ def initialize(message = load_error_context[:nil])
25
+ super(message)
26
+ end
27
+
28
+ include LoadError
29
+ end
30
+
31
+ # Wrong Email Error
32
+ class WrongEmailError < StandardError
33
+ def initialize(message = load_error_context[:wrong_email])
34
+ super(message)
35
+ end
36
+
37
+ include LoadError
38
+ end
39
+
40
+ # Wrong Password Error
41
+ class WrongPasswordError < StandardError
42
+ def initialize(message = load_error_context[:wrong_password])
43
+ super(message)
44
+ end
45
+
46
+ include LoadError
47
+ end
48
+
49
+ # User Already Exists Error
50
+ class UserAlreadyExistsError < StandardError
51
+ def initialize(message = load_error_context[:user_already_exists])
52
+ super(message)
53
+ end
54
+
55
+ include LoadError
56
+ end
57
+
58
+ # Chat Already Exists Error
59
+ class ChatAlreadyExistsError < StandardError
60
+ def initialize(message = load_error_context[:chat_already_exists])
61
+ super(message)
62
+ end
63
+
64
+ include LoadError
65
+ end
66
+
67
+ # Sign Up Error
68
+ class SignUpError < StandardError
69
+ def initialize(message = load_error_context[:sign_up_error])
70
+ super(message)
71
+ end
72
+
73
+ include LoadError
74
+ end
75
+
76
+ # Chat Not Created Error
77
+ class ChatNotCreatedError < StandardError
78
+ def initialize(message = load_error_context[:chat_not_created_error])
79
+ super(message)
80
+ end
81
+
82
+ include LoadError
83
+ end
84
+
85
+ # Message Not Created Error
86
+ class MessageNotCreatedError < StandardError
87
+ def initialize(message = load_error_context[:message_not_created_error])
88
+ super(message)
89
+ end
90
+
91
+ include LoadError
92
+ end
93
+
94
+ # No Chat Selected Error
95
+ class NoChatSelectedError < StandardError
96
+ def initialize(message = load_error_context[:no_chat_selected])
97
+ super(message)
98
+ end
99
+
100
+ include LoadError
101
+ end
102
+
103
+ # No Messages Founded Error
104
+ class NoMessagesFoundedError < StandardError
105
+ def initialize(message = load_error_context[:no_messages_founded])
106
+ super(message)
107
+ end
108
+
109
+ include LoadError
110
+ end
111
+
112
+ # No Chats Founded Error
113
+ class NoChatsFoundedError < StandardError
114
+ def initialize(message = load_error_context[:no_chats_founded])
115
+ super(message)
116
+ end
117
+
118
+ include LoadError
119
+ end
120
+
121
+ # Chat Not Found Error
122
+ class ChatNotFoundError < StandardError
123
+ def initialize(message = load_error_context[:chat_not_found])
124
+ super(message)
125
+ end
126
+
127
+ include LoadError
128
+ end
129
+
130
+ # User Not Found Error
131
+ class UserNotFoundError < StandardError
132
+ def initialize(message = load_error_context[:user_not_found])
133
+ super(message)
134
+ end
135
+
136
+ include LoadError
137
+ end
138
+
139
+ # User Not Registered Error
140
+ class UserNotRegisteredError < StandardError
141
+ def initialize(message = load_error_context[:user_not_registered])
142
+ super(message)
143
+ end
144
+
145
+ include LoadError
146
+ end
147
+
148
+ # User Logged In Error
149
+ class UserLoggedInError < StandardError
150
+ def initialize(message = load_error_context[:user_logged_in])
151
+ super(message)
152
+ end
153
+
154
+ include LoadError
155
+ end
156
+
157
+ # User Not Logged In Error
158
+ class UserNotLoggedInError < StandardError
159
+ def initialize(message = load_error_context[:user_not_logged_in])
160
+ super(message)
161
+ end
162
+
163
+ include LoadError
164
+ end
165
+
166
+ # User Not In Voice Channel Error
167
+ class UserNotInVoiceChannelError < StandardError
168
+ def initialize(message = load_error_context[:user_not_in_voice_channel])
169
+ super(message)
170
+ end
171
+
172
+ include LoadError
173
+ end
174
+
175
+ # Bot Not In Voice Channel Error
176
+ class BotNotInVoiceChannelError < StandardError
177
+ def initialize(message = load_error_context[:bot_not_in_voice_channel])
178
+ super(message)
179
+ end
180
+
181
+ include LoadError
182
+ end
183
+
184
+ # Message Not Found Error
185
+ class MessageHistoryTooLongError < StandardError
186
+ def initialize(message = load_error_context[:message_history_too_long])
187
+ super(message)
188
+ end
189
+
190
+ include LoadError
191
+ end
192
+
193
+ # Text Length Too Long Error
194
+ class TextLengthTooLongError < StandardError
195
+ def initialize(message = load_error_context[:text_length_too_long])
196
+ super(message)
197
+ end
198
+
199
+ include LoadError
200
+ end
201
+
202
+ # Invalid Command Error
203
+ class InvalidCommandError < StandardError
204
+ def initialize(message = load_error_context[:invalid_command])
205
+ super(message)
206
+ end
207
+
208
+ include LoadError
209
+ end
210
+
211
+ # Something Went Wrong Error
212
+ class SomethingWentWrongError < StandardError
213
+ def initialize(message = load_error_context[:something_went_wrong])
214
+ super(message)
215
+ end
216
+
217
+ include LoadError
218
+ end
219
+ end
@@ -5,8 +5,6 @@ require "active_record"
5
5
  # Visitor model
6
6
  class Visitor < ActiveRecord::Base
7
7
  has_many :visitor_actions
8
- # has_one :tel_user, foreign_key: "telegram_id", class_name: "User"
9
- # has_one :dis_user, foreign_key: "discord_id", class_name: "User"
10
8
  validates :name, presence: true
11
9
  validates :platform, presence: true
12
10
  enum platform: { telegram: 0, discord: 1 }
@@ -26,19 +24,23 @@ class User < ActiveRecord::Base
26
24
 
27
25
  belongs_to :tel_visitor, optional: true, foreign_key: "telegram_id", class_name: "Visitor"
28
26
  belongs_to :dis_visitor, optional: true, foreign_key: "discord_id", class_name: "Visitor"
29
- before_save :encrypt_password
30
- validates :email, presence: true, uniqueness: true
31
- validates :role, presence: true
32
- validates :open_chats, presence: true
33
- validates :closed_chats, presence: true
34
- validates :total_chats, presence: true
35
- validates :total_messages, presence: true
27
+
28
+ validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }, length: { maximum: 100 }, on: :create
29
+ validates :role, presence: true, on: :create
30
+ validates :open_chats, presence: true, on: :create
31
+ validates :closed_chats, presence: true, on: :create
32
+ validates :total_chats, presence: true, on: :create
33
+ validates :total_messages, presence: true, on: :create
34
+ validates :password, presence: true, on: :create
35
+
36
+ before_save :encrypt_password, if: :password
37
+
36
38
  has_many :chats
37
39
 
38
40
  def encrypt_password
39
41
  return if password.nil?
40
42
 
41
- self.password_salt = BCrypt::Engine.generate_salt.to_s
43
+ self.password_salt = BCrypt::Engine.generate_salt
42
44
  self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
43
45
  end
44
46
 
@@ -53,6 +55,10 @@ class User < ActiveRecord::Base
53
55
  def chat_by_title(title)
54
56
  chats.find_by(title: title)
55
57
  end
58
+
59
+ def chat_history
60
+ current_chat.messages.last(10).map { |m| "#{m.role}: #{m.content}\nat: #{m.created_at}" }
61
+ end
56
62
  end
57
63
 
58
64
  # Chat model
@@ -69,15 +75,14 @@ class Chat < ActiveRecord::Base
69
75
  def init_chat_if_actor_provided
70
76
  return if actor.nil?
71
77
 
72
- messages.create(content: prompt, role: "user")
73
- messages.create(content: "Hello, I'm #{actor}. I will follow #{prompt}", role: "assistant")
78
+ messages.create(content: prompt, role: "system")
74
79
  end
75
80
  end
76
81
 
77
82
  # Message model
78
83
  class Message < ActiveRecord::Base
79
84
  validates :content, presence: true
80
- enum role: { user: 0, assistant: 1 }
85
+ enum role: { user: 0, assistant: 1, system: 2 }
81
86
 
82
87
  belongs_to :chat
83
88
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../chatgpt_assistant"
4
+
5
+ Sidekiq.configure_server do |config|
6
+ config.redis = { url: ENV.fetch("REDIS_URL", "redis://redis:6379/1") }
7
+ end
@@ -0,0 +1,10 @@
1
+ development:
2
+ :concurrency: 5
3
+
4
+ production:
5
+ :concurrency: 5
6
+
7
+ :max_retries: 1
8
+
9
+ :queues:
10
+ - default
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ChatgptAssistant
4
- VERSION = "0.1.5"
4
+ VERSION = "0.1.6"
5
5
  end
@@ -7,6 +7,7 @@ require_relative "chatgpt_assistant/chatter"
7
7
  require_relative "chatgpt_assistant/version"
8
8
  require_relative "chatgpt_assistant/config"
9
9
  require_relative "chatgpt_assistant/models"
10
+ require_relative "chatgpt_assistant/error"
10
11
  require_relative "bots/application_bot"
11
12
  require_relative "bots/telegram_bot"
12
13
  require_relative "bots/discord_bot"
@@ -16,6 +17,8 @@ require "aws-sdk-polly"
16
17
  require "telegram/bot"
17
18
  require "ibm_watson"
18
19
  require "discordrb"
20
+ require "sidekiq"
21
+ require "sidekiq-scheduler"
19
22
  require "faraday"
20
23
  require "bcrypt"
21
24
 
@@ -32,24 +35,12 @@ module ChatgptAssistant
32
35
  return discord_bot if discord_mode?
33
36
 
34
37
  raise "Invalid mode"
35
- rescue StandardError => e
36
- save_error(e)
37
- retry
38
38
  end
39
39
 
40
40
  private
41
41
 
42
42
  attr_reader :mode, :config
43
43
 
44
- def save_error(err)
45
- puts "Error: #{err.message}"
46
- err.backtrace.each { |line| puts line }
47
- Error.create(message: err.message, backtrace: err.backtrace) unless err.message == Error.last&.message
48
- rescue StandardError
49
- puts "Error: #{err.message}"
50
- puts "Backtrace: #{err.backtrace}"
51
- end
52
-
53
44
  def telegram_mode?
54
45
  mode == "telegram"
55
46
  end