chatgpt_assistant 0.1.6 → 0.1.7

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/.env_sample +16 -7
  3. data/.rubocop.yml +14 -3
  4. data/Dockerfile +11 -5
  5. data/Gemfile +25 -23
  6. data/Gemfile.lock +123 -85
  7. data/README.md +15 -18
  8. data/Rakefile +1 -0
  9. data/docker-compose.yml +8 -4
  10. data/exe/chatgpt_assistant +1 -1
  11. data/lib/{bots → chatgpt_assistant/bots}/application_bot.rb +0 -6
  12. data/lib/chatgpt_assistant/bots/discord/actions.rb +104 -0
  13. data/lib/chatgpt_assistant/bots/discord/auth.rb +36 -0
  14. data/lib/chatgpt_assistant/bots/discord/bot.rb +29 -0
  15. data/lib/chatgpt_assistant/bots/discord/chat_actions.rb +33 -0
  16. data/lib/chatgpt_assistant/bots/discord/events.rb +138 -0
  17. data/lib/chatgpt_assistant/bots/discord/validations.rb +38 -0
  18. data/lib/chatgpt_assistant/bots/discord/voice_actions.rb +33 -0
  19. data/lib/chatgpt_assistant/bots/discord/voice_checkers.rb +35 -0
  20. data/lib/chatgpt_assistant/bots/discord_bot.rb +42 -0
  21. data/lib/chatgpt_assistant/bots/helpers/messenger_helper.rb +16 -0
  22. data/lib/{bots → chatgpt_assistant/bots}/jobs/register_job.rb +2 -2
  23. data/lib/chatgpt_assistant/bots/mailers/account_mailer.rb +30 -0
  24. data/lib/chatgpt_assistant/bots/mailers/application_mailer.rb +21 -0
  25. data/lib/chatgpt_assistant/bots/services/new_chat_service.rb +59 -0
  26. data/lib/chatgpt_assistant/bots/services/register_service.rb +45 -0
  27. data/lib/chatgpt_assistant/bots/telegram/actions.rb +54 -0
  28. data/lib/chatgpt_assistant/bots/telegram/auth.rb +40 -0
  29. data/lib/chatgpt_assistant/bots/telegram/bot.rb +17 -0
  30. data/lib/chatgpt_assistant/bots/telegram/chat_actions.rb +30 -0
  31. data/lib/chatgpt_assistant/bots/telegram/events.rb +120 -0
  32. data/lib/chatgpt_assistant/bots/telegram/events_controller.rb +48 -0
  33. data/lib/chatgpt_assistant/bots/telegram/permissions.rb +48 -0
  34. data/lib/chatgpt_assistant/bots/telegram/validations.rb +55 -0
  35. data/lib/chatgpt_assistant/bots/telegram/voice_actions.rb +36 -0
  36. data/lib/chatgpt_assistant/bots/telegram_bot.rb +44 -0
  37. data/lib/chatgpt_assistant/chatter.rb +10 -2
  38. data/lib/chatgpt_assistant/config.rb +4 -1
  39. data/lib/chatgpt_assistant/default_messages.rb +10 -4
  40. data/lib/chatgpt_assistant/error.rb +9 -0
  41. data/lib/chatgpt_assistant/migrations.rb +5 -0
  42. data/lib/chatgpt_assistant/models.rb +20 -0
  43. data/lib/chatgpt_assistant/version.rb +1 -1
  44. data/lib/chatgpt_assistant.rb +5 -3
  45. metadata +34 -24
  46. data/.env_prod_sample +0 -18
  47. data/docker-compose.prod.yml +0 -34
  48. data/lib/bots/discord_bot.rb +0 -182
  49. data/lib/bots/helpers/authentication_helper.rb +0 -48
  50. data/lib/bots/helpers/discord_helper.rb +0 -124
  51. data/lib/bots/helpers/discord_voice_helper.rb +0 -50
  52. data/lib/bots/helpers/messenger_helper.rb +0 -133
  53. data/lib/bots/helpers/telegram_helper.rb +0 -73
  54. data/lib/bots/helpers/telegram_voice_helper.rb +0 -33
  55. data/lib/bots/helpers/validation_helper.rb +0 -38
  56. data/lib/bots/helpers/visit_helper.rb +0 -28
  57. data/lib/bots/services/new_chat_service.rb +0 -34
  58. data/lib/bots/services/register_service.rb +0 -36
  59. data/lib/bots/telegram_bot.rb +0 -180
  60. /data/lib/{bots → chatgpt_assistant/bots}/helpers/audio_helper.rb +0 -0
  61. /data/lib/{bots → chatgpt_assistant/bots}/helpers/file_helper.rb +0 -0
  62. /data/lib/{bots → chatgpt_assistant/bots}/helpers/search_helper.rb +0 -0
  63. /data/lib/{bots → chatgpt_assistant/bots}/jobs/new_chat_job.rb +0 -0
  64. /data/lib/{bots → chatgpt_assistant/bots}/jobs/voice_connect_job.rb +0 -0
  65. /data/lib/{bots → chatgpt_assistant/bots}/services/voice_connect_service.rb +0 -0
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ # This class is responsible to background the new chat service
5
+ class NewChatService
6
+ def initialize(chat_title, user_id, chat_id, config)
7
+ @chat_title = chat_title
8
+ @user_id = user_id
9
+ @chat_id = chat_id
10
+ @config = config
11
+ end
12
+
13
+ def telegram_async
14
+ TelegramBot.new(@config)
15
+ end
16
+
17
+ def actors
18
+ @actors ||= AwesomeChatgptActors::CastControl.actors
19
+ end
20
+
21
+ def actor
22
+ @actor_name = actors[@actor_mode.to_i - 1] if @actor_mode
23
+ @actor = AwesomeChatgptActors::Actor.new(role: @actor_name, language: @config.language) if @actor_name
24
+ end
25
+
26
+ def chat
27
+ @chat = Chat.new(title: @chat_title, user_id: @user_id, status: 0, actor: @actor_name, prompt: @actor.prompt) if !@actor.nil? && @actor_name
28
+ @chat = Chat.new(title: @chat_title, user_id: @user_id, status: 0) unless @actor_name
29
+ end
30
+
31
+ def parse_title
32
+ return @chat_title.strip! unless @chat_title.include?("actor:")
33
+
34
+ @actor_mode = @chat_title.split("actor:")[1].strip
35
+ @chat_title = @chat_title.split("actor:")[0].strip
36
+ end
37
+
38
+ def call
39
+ raise NilError if @chat_title.nil?
40
+ raise NilError if @user_id.nil?
41
+ raise NilError if @chat_id.nil?
42
+
43
+ parse_title
44
+
45
+ raise InvalidModeError unless (@actor_mode.to_i >= 1 && @actor_mode.to_i <= actors.size + 1) || @actor_mode.nil?
46
+ raise InvalidChatTitleError if @chat_title.nil? || @chat_title.empty?
47
+ raise ChatAlreadyExistsError if Chat.find_by(title: @chat_title)
48
+
49
+ if chat.save
50
+ telegram_async.send_message("Chat created succesfully", @chat_id)
51
+ else
52
+ raise ChatAlreadyExistsError if Chat.find_by(title: @chat_title)
53
+ raise NilError if chat.errors[:title].any?
54
+ end
55
+ rescue ChatAlreadyExistsError, NilError => e
56
+ telegram_async.send_message(e.message, @chat_id)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ # This class is responsible to background the register service
5
+ class RegisterService
6
+ def initialize(email, password, name, chat_id)
7
+ @name = name
8
+ @email = email
9
+ @password = password
10
+ @chat_id = chat_id
11
+ @config = Config.new
12
+ @config.db_connection
13
+ end
14
+
15
+ def call
16
+ return if user_already_exists?
17
+
18
+ @user = User.new(email: @email, password: @password, telegram_id: @chat_id, name: @name)
19
+ @user.save ? success_message : error_message
20
+ rescue UserAlreadyExistsError, WrongEmailError, WrongPasswordError => e
21
+ telegram_async.send_message(e.message, @chat_id)
22
+ end
23
+
24
+ private
25
+
26
+ def telegram_async
27
+ TelegramBot.new(@config)
28
+ end
29
+
30
+ def success_message
31
+ confirmation_token = @user.encrypt_token
32
+ telegram_async.send_message("Registration successful! Check your email for confirmation.", @chat_id)
33
+ AccountMailer.register_email(@user, confirmation_token).deliver_now
34
+ end
35
+
36
+ def error_message
37
+ raise WrongEmailError if @user.errors[:email].any?
38
+ raise WrongPasswordError if @user.errors[:password].any?
39
+ end
40
+
41
+ def user_already_exists?
42
+ raise UserAlreadyExistsError if User.find_by(email: @email)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ module Bots
5
+ module Telegram
6
+ module Actions
7
+ def telegram_user_create(visitor_id, email, password)
8
+ visitor = Visitor.find_by(id: visitor_id)
9
+ return false unless visitor
10
+
11
+ visitor.tel_user.update(telegram_id: nil) if visitor.tel_user.present?
12
+ user = User.new(telegram_id: visitor.telegram_id, email: email, password: password)
13
+ user.save ? user.email : user.errors.full_messages
14
+ end
15
+
16
+ def telegram_send_start_message
17
+ send_message common_messages[:start], msg.chat.id
18
+ help_message = help_messages.join("\n").to_s
19
+ send_message help_message, msg.chat.id
20
+ send_message common_messages[:start_helper], msg.chat.id
21
+ send_message common_messages[:start_sec_helper], msg.chat.id
22
+ end
23
+
24
+ def telegram_create_chat
25
+ text = msg.text
26
+ title = text.split("/").last
27
+ mode = nil
28
+ if title.include?(":")
29
+ mode = title.split(":").last
30
+ title = title.split(":").first
31
+ end
32
+ actor_modes = AwesomeChatgptActors::CastControl.actors
33
+ return send_message "invalid mode", msg.chat.id unless (mode.to_i >= 1 && mode.to_i <= actor_modes.size + 1) || mode.nil?
34
+ return send_message "invalid chat title", msg.chat.id if title.nil? || title.empty?
35
+ return send_message "You already have a chat with this title", msg.chat.id if user.chat_by_title(title)
36
+
37
+ actor_name = actor_modes[mode.to_i - 1] if mode
38
+ actor = AwesomeChatgptActors::Actor.new(prompt_type: actor_name) if actor_name
39
+ chat = Chat.new(user_id: user.id, status: 0, title: title, actor: actor_name, prompt: actor.prompt) if actor
40
+ chat = Chat.new(user_id: user.id, status: 0, title: title) unless actor
41
+ return send_message "Something went wrong", msg.chat.id unless chat
42
+
43
+ chat.save ? chat_created_message(chat) : send_message(chat_id: msg.chat.id, text: error_messages[:chat_creation_failed])
44
+ end
45
+
46
+ def chat_created_message(chat)
47
+ bot.api.send_message(chat_id: msg.chat.id, text: "Intructions sended to actor:\n#{chat.prompt}") unless chat.actor.nil?
48
+ bot.api.send_message(chat_id: msg.chat.id, text: "Response from assistant:\n#{chat.messages[1].content}") unless chat.actor.nil?
49
+ bot.api.send_message(chat_id: msg.chat.id, text: success_messages[:chat_created]) if bot.respond_to?(:api)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ module Bots
5
+ module Telegram
6
+ module Auth
7
+ def authenticate_user(email, password)
8
+ case telegram_user_auth(email, password, msg.chat.id)
9
+ when "user not found"
10
+ raise UserNotFoundError
11
+ when "wrong password"
12
+ raise WrongPasswordError
13
+ when email
14
+ send_message(chat_id: msg.chat.id, text: success_messages[:user_logged_in])
15
+ end
16
+ end
17
+
18
+ def telegram_user_auth(email, password, telegram_id)
19
+ return "wrong password" if password.nil?
20
+
21
+ visitor_access = find_visitor(telegram_id: telegram_id)
22
+ return "something went wrong" unless visitor_access
23
+
24
+ new_access = find_user(email: email)
25
+ return "user not found" unless new_access
26
+
27
+ user.valid_password?(password) ? telegram_user_access(visitor_access, new_access) : "wrong password"
28
+ end
29
+
30
+ def telegram_user_access(visitor, new_access)
31
+ other_access = where_user(telegram_id: visitor.telegram_id)
32
+ other_access&.each { |access| access.update(telegram_id: nil) } if other_access&.class == Array
33
+ other_access&.update(telegram_id: nil) if other_access&.class == User
34
+ new_access.update(telegram_id: visitor.telegram_id)
35
+ new_access.email
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ module Bots
5
+ module Telegram
6
+ module Bot
7
+ def bot
8
+ @bot ||= ::Telegram::Bot::Client.new(telegram_token, logger: Logger.new($stderr))
9
+ end
10
+
11
+ def user
12
+ @user = find_user(telegram_id: msg.chat.id)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ module Bots
5
+ module Telegram
6
+ module ChatActions
7
+ def chat_if_exists
8
+ chat = Chat.find_by(user_id: user.id, id: user.current_chat_id)
9
+ chat ? chat_success(chat.id) : send_message(chat_id: msg.chat.id, text: error_messages[:no_chat_selected])
10
+ end
11
+
12
+ def chat_success(chat_id)
13
+ user_message = Message.new(chat_id: chat_id, content: msg.text, role: "user")
14
+ if user_message&.save
15
+ text = chatter.chat(msg.text, chat_id, error_messages[:something_went_wrong])
16
+ mess = parse_message(text, 4096)
17
+ mess.each { |m| send_message m, msg.chat.id }
18
+ else
19
+ send_message error_messages[:something_went_wrong], msg.chat.id
20
+ end
21
+ end
22
+
23
+ def send_message(text, chat_id)
24
+ messages = parse_message(text, 4096)
25
+ messages.each { |m| bot.api.send_message(chat_id: chat_id, text: m) }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ module Bots
5
+ module Telegram
6
+ module Events
7
+ def start_event
8
+ telegram_send_start_message
9
+ end
10
+
11
+ def help_event
12
+ help_messages.each { |m| send_message m, msg.chat.id }
13
+ end
14
+
15
+ def hist_event
16
+ hist_allowed?
17
+
18
+ user.chat_history.each do |m|
19
+ send_message m, msg.chat.id
20
+ end
21
+ rescue NoChatSelectedError, UserNotLoggedInError, NoMessagesFoundedError, AccountNotVerifiedError => e
22
+ send_message e.message, msg.chat.id
23
+ end
24
+
25
+ def list_event
26
+ list_allowed?
27
+
28
+ send_message common_messages[:chat_list], msg.chat.id
29
+ chats_str = ""
30
+ user.chats.each_with_index { |c, i| chats_str += "Chat #{i + 1} - #{c.title}\n" }
31
+ send_message chats_str, msg.chat.id
32
+ rescue NoChatsFoundedError, UserNotLoggedInError, AccountNotVerifiedError => e
33
+ send_message e.message, msg.chat.id
34
+ end
35
+
36
+ def confirm_account_event
37
+ raise UserNotLoggedInError if user.nil?
38
+
39
+ user_info = msg.text.split("/* ").last
40
+ name, token = user_info.split(":")
41
+ send_message "#{name} - #{token}", msg.chat.id
42
+ if user_confirmed?
43
+ send_message success_messages[:account_confirmed], msg.chat.id
44
+ else
45
+ send_message error_messages[:account_not_confirmed], msg.chat.id
46
+ end
47
+ rescue UserNotLoggedInError => e
48
+ send_message e.message, msg.chat.id
49
+ end
50
+
51
+ def login_event
52
+ raise UserLoggedInError if user
53
+
54
+ user_info = msg.text.split("/").last
55
+ email, password = user_info.split(":")
56
+ authenticate_user(email, password)
57
+ rescue UserNotFoundError, WrongPasswordError, UserLoggedInError => e
58
+ send_message e.message, msg.chat.id
59
+ end
60
+
61
+ def register_event
62
+ user_info = msg.text.split("/").last
63
+ email, password = register_allowed?(user_info)
64
+ name = msg.from.first_name || "Anonymous"
65
+
66
+ RegisterJob.perform_async(email, password, name, visitor.telegram_id)
67
+ rescue NoRegisterInfoError, UserLoggedInError => e
68
+ send_message e.message, msg.chat.id
69
+ end
70
+
71
+ def sign_out_event
72
+ raise UserNotLoggedInError if user.nil?
73
+
74
+ user.update(telegram_id: nil)
75
+ send_message success_messages[:user_logged_out], msg.chat.id
76
+ rescue UserNotLoggedInError => e
77
+ send_message e.message, msg.chat.id
78
+ end
79
+
80
+ def new_chat_event
81
+ common_allowed?
82
+ NewChatJob.perform_async(msg.text.split("/").last, user.id, msg.chat.id)
83
+ rescue UserNotLoggedInError, AccountNotVerifiedError => e
84
+ send_message e.message, msg.chat.id
85
+ end
86
+
87
+ def select_chat_event
88
+ common_allowed?
89
+ title = msg.text.split("/").last
90
+ chat = user.chat_by_title(title)
91
+ select_allowed?(chat)
92
+
93
+ send_message success_messages[:chat_selected], msg.chat.id
94
+ rescue UserNotLoggedInError, ChatNotFoundError, AccountNotVerifiedError => e
95
+ send_message e.message, msg.chat.id
96
+ end
97
+
98
+ def audio_event
99
+ audio_allowed?
100
+ user_audio = transcribe_file(telegram_audio_url)
101
+ message = Message.new(content: user_audio[:text], chat_id: user.current_chat_id, role: "user")
102
+ raise MessageNotCreatedError unless message.save
103
+
104
+ ai_response = telegram_process_ai_voice(user_audio[:file])
105
+ telegram_send_voice_message(voice: ai_response[:voice], text: ai_response[:text])
106
+ delete_file ai_response[:voice]
107
+ rescue UserNotLoggedInError, NoChatSelectedError, MessageNotCreatedError, AccountNotVerifiedError => e
108
+ send_message e.message, msg.chat.id
109
+ end
110
+
111
+ def telegram_chat_event
112
+ common_allowed?
113
+ chat_if_exists
114
+ rescue UserNotLoggedInError, AccountNotVerifiedError => e
115
+ send_message e.message, msg.chat.id
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ module Bots
5
+ module Telegram
6
+ module EventsController
7
+ def auth_events
8
+ return login_event if msg.text.include?("login/")
9
+ return register_event if msg.text.include?("register/")
10
+ return sign_out_event if msg.text.include?("sign_out/")
11
+ return confirm_account_event if msg.text.include?("confirm/* ")
12
+ end
13
+
14
+ def action_events
15
+ return auth_events if auth_event?
16
+ return new_chat_event if msg.text.include?("new_chat/")
17
+ return select_chat_event if msg.text.include?("sl_chat/")
18
+ return telegram_chat_event unless telegram_actions?
19
+
20
+ raise InvalidCommandError
21
+ rescue InvalidCommandError => e
22
+ send_message e.message, msg.chat.id
23
+ end
24
+
25
+ def text_events
26
+ case msg.text
27
+ when "/start"
28
+ start_event
29
+ when "/help"
30
+ help_event
31
+ when "/hist"
32
+ hist_event
33
+ when "/list"
34
+ list_event
35
+ when "/stop"
36
+ stop_event
37
+ when nil
38
+ raise NilError
39
+ else
40
+ action_events
41
+ end
42
+ rescue NilError => e
43
+ send_message e.message, msg.chat.id
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ module Bots
5
+ module Telegram
6
+ module Permissions
7
+ def hist_allowed?
8
+ raise UserNotLoggedInError if user.nil?
9
+ raise AccountNotVerifiedError unless user.active?
10
+ raise NoChatSelectedError if user.current_chat.nil?
11
+ raise NoMessagesFoundedError if user.current_chat.messages.count.zero?
12
+ end
13
+
14
+ def list_allowed?
15
+ raise UserNotLoggedInError if user.nil?
16
+ raise AccountNotVerifiedError unless user.active?
17
+ raise NoChatsFoundedError if user.chats.count.zero?
18
+ end
19
+
20
+ def register_allowed?(user_info)
21
+ raise NoRegisterInfoError if user_info.nil?
22
+ raise UserLoggedInError if user
23
+
24
+ email, password = user_info.split(":")
25
+ raise NoRegisterEmailError if email.nil? || password.nil?
26
+
27
+ [email, password]
28
+ end
29
+
30
+ def common_allowed?
31
+ raise UserNotLoggedInError if user.nil?
32
+ raise AccountNotVerifiedError unless user.active?
33
+ end
34
+
35
+ def select_allowed?(chat)
36
+ raise ChatNotFoundError if chat.nil?
37
+ raise ChatNotFoundError unless user.update(current_chat_id: chat.id)
38
+ end
39
+
40
+ def audio_allowed?
41
+ raise UserNotLoggedInError if user.nil?
42
+ raise AccountNotVerifiedError unless user.active?
43
+ raise NoChatSelectedError if user.current_chat.nil?
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ module Bots
5
+ module Telegram
6
+ module Validations
7
+ def telegram_actions?
8
+ msg.text.include?("new_chat/") || msg.text.include?("sl_chat/") || msg.text.include?("login/") || msg.text.include?("register/")
9
+ end
10
+
11
+ def telegram_text_or_audio?
12
+ msg.respond_to?(:text) || msg.respond_to?(:audio) || msg.respond_to?(:voice)
13
+ end
14
+
15
+ def telegram_message_has_text?
16
+ msg.text.present?
17
+ end
18
+
19
+ def telegram_message_has_audio?
20
+ msg.audio.present? || msg.voice.present?
21
+ end
22
+
23
+ def telegram_visited?(chat_id)
24
+ return unless msg
25
+
26
+ visitor = Visitor.find_by(telegram_id: chat_id, name: msg.from.first_name)
27
+ if visitor.nil?
28
+ Visitor.create(telegram_id: chat_id, name: msg.from.first_name)
29
+ else
30
+ visitor
31
+ end
32
+ end
33
+
34
+ def visitor_user?
35
+ visitor&.tel_user.nil?
36
+ end
37
+
38
+ def valid_for_list_action?
39
+ send_message(chat_id: msg.chat.id, text: error_messages[:user_not_logged_in]) if user.nil?
40
+ send_message(chat_id: msg.chat.id, text: error_messages[:account_not_verified]) unless user.active?
41
+ send_message(chat_id: msg.chat.id, text: error_messages[:chat_not_found]) if user.chats.count.zero? && user.active?
42
+ !user.nil? && user.active? && user.chats.count.positive?
43
+ end
44
+
45
+ def auth_event?
46
+ msg.text.include?("login/") || msg.text.include?("register/") || msg.text.include?("sign_out/") || msg.text.include?("confirm/* ")
47
+ end
48
+
49
+ def user_confirmed?
50
+ user.name == name && user.confirm_account(token)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ module Bots
5
+ module Telegram
6
+ module VoiceActions
7
+ def telegram_audio_info
8
+ bot.api.get_file(file_id: telegram_audio.file_id)
9
+ end
10
+
11
+ def telegram_audio_url
12
+ "https://api.telegram.org/file/bot#{telegram_token}/#{telegram_audio_info["result"]["file_path"]}"
13
+ end
14
+
15
+ def telegram_audio
16
+ msg.audio || msg.voice
17
+ end
18
+
19
+ def telegram_process_ai_voice(user_audio)
20
+ ai_text = chatter.chat(user_audio["text"], user.current_chat_id, error_messages[:something_went_wrong])
21
+ ai_voice = synthesis.synthesize_text(ai_text)
22
+ {
23
+ voice: ai_voice,
24
+ text: ai_text
25
+ }
26
+ end
27
+
28
+ def telegram_send_voice_message(voice: nil, text: nil)
29
+ messages = parse_message text, 4096
30
+ bot.api.send_voice(chat_id: msg.chat.id, voice: Faraday::UploadIO.new(voice, "audio/mp3"))
31
+ messages.each { |message| send_message message, msg.chat.id }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "telegram/bot"
4
+ require_relative "telegram/auth"
5
+ require_relative "telegram/actions"
6
+ require_relative "telegram/events"
7
+ require_relative "telegram/chat_actions"
8
+ require_relative "telegram/validations"
9
+ require_relative "telegram/voice_actions"
10
+ require_relative "telegram/permissions"
11
+ require_relative "telegram/events_controller"
12
+
13
+ module ChatgptAssistant
14
+ # This class is responsible for the telegram bot features
15
+ class TelegramBot < ApplicationBot
16
+ def start
17
+ bot.listen do |message|
18
+ @msg = message
19
+ @visitor = telegram_visited?(@msg.chat.id)
20
+ next unless telegram_text_or_audio?
21
+
22
+ text_events if telegram_message_has_text?
23
+ audio_event if telegram_message_has_audio?
24
+ end
25
+ rescue StandardError => e
26
+ Error.create(message: e.message, backtrace: e.backtrace)
27
+ retry
28
+ end
29
+
30
+ private
31
+
32
+ attr_accessor :msg, :visitor, :chat, :chat_id
33
+
34
+ include Bots::Telegram::Bot
35
+ include Bots::Telegram::Auth
36
+ include Bots::Telegram::Actions
37
+ include Bots::Telegram::Events
38
+ include Bots::Telegram::ChatActions
39
+ include Bots::Telegram::Validations
40
+ include Bots::Telegram::VoiceActions
41
+ include Bots::Telegram::Permissions
42
+ include Bots::Telegram::EventsController
43
+ end
44
+ end
@@ -17,7 +17,7 @@ module ChatgptAssistant
17
17
  @response = request(message)
18
18
  @json = JSON.parse(response.body)
19
19
 
20
- return no_response_error if json["choices"].empty?
20
+ return no_response_error if json["choices"] && json["choices"].empty?
21
21
  return bot_offline_error if response.status != 200
22
22
 
23
23
  text = json["choices"][0]["message"]["content"]
@@ -57,7 +57,8 @@ module ChatgptAssistant
57
57
  end
58
58
 
59
59
  def request_params(message)
60
- messages = Message.where(chat_id: chat_id).order(id: :asc).last(10)
60
+ messages_from_chat = Message.where(chat_id: chat_id)
61
+ messages = messages_from_chat.order(id: :asc).last(10)
61
62
  messages = if messages.empty?
62
63
  [{ role: "user", content: message }]
63
64
  else
@@ -66,6 +67,13 @@ module ChatgptAssistant
66
67
  content: mess.content }
67
68
  end
68
69
  end
70
+
71
+ first_message = messages_from_chat.order(id: :asc).first
72
+ system_message = first_message if first_message&.role == "system"
73
+ if system_message && Message.where(chat_id: chat_id).count > 10
74
+ messages.unshift({ role: system_message.role,
75
+ content: system_message.content })
76
+ end
69
77
  {
70
78
  model: "gpt-3.5-turbo",
71
79
  messages: messages,
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "active_record"
4
4
  require "active_model"
5
+ require "action_mailer"
5
6
  require_relative "migrations"
6
7
  require "fileutils"
7
8
 
@@ -30,7 +31,9 @@ module ChatgptAssistant
30
31
 
31
32
  attr_reader :openai_api_key, :telegram_token, :discord_token, :ibm_api_key, :ibm_url,
32
33
  :aws_access_key_id, :aws_secret_access_key, :aws_region, :mode, :language,
33
- :discord_client_id, :discord_public_key, :env_type, :discord_prefix
34
+ :discord_client_id, :discord_public_key, :env_type, :discord_prefix,
35
+ :smtp_address, :smtp_port, :smtp_domain, :smtp_user_name, :smtp_password,
36
+ :smtp_authentication, :smtp_enable_starttls_auto
34
37
 
35
38
  def db_connection
36
39
  ActiveRecord::Base.establish_connection(