chatgpt_assistant 0.1.6 → 0.1.8

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/.env_sample +35 -10
  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 +22 -22
  8. data/Rakefile +1 -0
  9. data/docker-compose.yml +8 -4
  10. data/exe/chatgpt_assistant +1 -1
  11. data/lib/chatgpt_assistant/audio_synthesis.rb +54 -15
  12. data/lib/{bots → chatgpt_assistant/bots}/application_bot.rb +0 -6
  13. data/lib/chatgpt_assistant/bots/discord/actions.rb +103 -0
  14. data/lib/chatgpt_assistant/bots/discord/auth.rb +36 -0
  15. data/lib/chatgpt_assistant/bots/discord/bot.rb +29 -0
  16. data/lib/chatgpt_assistant/bots/discord/chat_actions.rb +33 -0
  17. data/lib/chatgpt_assistant/bots/discord/events.rb +138 -0
  18. data/lib/chatgpt_assistant/bots/discord/validations.rb +38 -0
  19. data/lib/chatgpt_assistant/bots/discord/voice_actions.rb +33 -0
  20. data/lib/chatgpt_assistant/bots/discord/voice_checkers.rb +35 -0
  21. data/lib/chatgpt_assistant/bots/discord_bot.rb +41 -0
  22. data/lib/chatgpt_assistant/bots/helpers/messenger_helper.rb +16 -0
  23. data/lib/{bots → chatgpt_assistant/bots}/jobs/register_job.rb +2 -2
  24. data/lib/chatgpt_assistant/bots/mailers/account_mailer.rb +30 -0
  25. data/lib/chatgpt_assistant/bots/mailers/application_mailer.rb +21 -0
  26. data/lib/chatgpt_assistant/bots/services/new_chat_service.rb +59 -0
  27. data/lib/chatgpt_assistant/bots/services/register_service.rb +45 -0
  28. data/lib/chatgpt_assistant/bots/telegram/actions.rb +54 -0
  29. data/lib/chatgpt_assistant/bots/telegram/auth.rb +40 -0
  30. data/lib/chatgpt_assistant/bots/telegram/bot.rb +17 -0
  31. data/lib/chatgpt_assistant/bots/telegram/chat_actions.rb +30 -0
  32. data/lib/chatgpt_assistant/bots/telegram/events.rb +121 -0
  33. data/lib/chatgpt_assistant/bots/telegram/events_controller.rb +48 -0
  34. data/lib/chatgpt_assistant/bots/telegram/permissions.rb +48 -0
  35. data/lib/chatgpt_assistant/bots/telegram/validations.rb +55 -0
  36. data/lib/chatgpt_assistant/bots/telegram/voice_actions.rb +36 -0
  37. data/lib/chatgpt_assistant/bots/telegram_bot.rb +44 -0
  38. data/lib/chatgpt_assistant/chatter.rb +10 -2
  39. data/lib/chatgpt_assistant/config.rb +7 -1
  40. data/lib/chatgpt_assistant/default_messages.rb +10 -4
  41. data/lib/chatgpt_assistant/error.rb +9 -0
  42. data/lib/chatgpt_assistant/migrations.rb +5 -0
  43. data/lib/chatgpt_assistant/models.rb +20 -0
  44. data/lib/chatgpt_assistant/version.rb +1 -1
  45. data/lib/chatgpt_assistant.rb +5 -3
  46. metadata +35 -25
  47. data/.env_prod_sample +0 -18
  48. data/docker-compose.prod.yml +0 -34
  49. data/lib/bots/discord_bot.rb +0 -182
  50. data/lib/bots/helpers/authentication_helper.rb +0 -48
  51. data/lib/bots/helpers/discord_helper.rb +0 -124
  52. data/lib/bots/helpers/discord_voice_helper.rb +0 -50
  53. data/lib/bots/helpers/messenger_helper.rb +0 -133
  54. data/lib/bots/helpers/telegram_helper.rb +0 -73
  55. data/lib/bots/helpers/telegram_voice_helper.rb +0 -33
  56. data/lib/bots/helpers/validation_helper.rb +0 -38
  57. data/lib/bots/helpers/visit_helper.rb +0 -28
  58. data/lib/bots/services/new_chat_service.rb +0 -34
  59. data/lib/bots/services/register_service.rb +0 -36
  60. data/lib/bots/telegram_bot.rb +0 -180
  61. /data/lib/{bots → chatgpt_assistant/bots}/helpers/audio_helper.rb +0 -0
  62. /data/lib/{bots → chatgpt_assistant/bots}/helpers/file_helper.rb +0 -0
  63. /data/lib/{bots → chatgpt_assistant/bots}/helpers/search_helper.rb +0 -0
  64. /data/lib/{bots → chatgpt_assistant/bots}/jobs/new_chat_job.rb +0 -0
  65. /data/lib/{bots → chatgpt_assistant/bots}/jobs/voice_connect_job.rb +0 -0
  66. /data/lib/{bots → chatgpt_assistant/bots}/services/voice_connect_service.rb +0 -0
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "discord/bot"
4
+ require_relative "discord/auth"
5
+ require_relative "discord/actions"
6
+ require_relative "discord/chat_actions"
7
+ require_relative "discord/events"
8
+ require_relative "discord/voice_actions"
9
+ require_relative "discord/voice_checkers"
10
+ require_relative "discord/validations"
11
+ module ChatgptAssistant
12
+ # This class is responsible to handle the discord bot
13
+ class DiscordBot < ApplicationBot
14
+ def start
15
+ start_event
16
+ login_event
17
+ list_event
18
+ hist_event
19
+ help_event
20
+ new_chat_event
21
+ sl_chat_event
22
+ ask_event
23
+ private_message_event
24
+ bot_init
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :message
30
+ attr_accessor :evnt, :chats, :chat
31
+
32
+ include Bots::Discord::Bot
33
+ include Bots::Discord::Auth
34
+ include Bots::Discord::Actions
35
+ include Bots::Discord::ChatActions
36
+ include Bots::Discord::Events
37
+ include Bots::Discord::VoiceActions
38
+ include Bots::Discord::VoiceCheckers
39
+ include Bots::Discord::Validations
40
+ end
41
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ChatgptAssistant
4
+ # Helper for messenger
5
+ module MessengerHelper
6
+ def parse_message(message, max_length)
7
+ if message.length > max_length
8
+ array = message.scan(/.{1,#{max_length}}/) if max_length.positive?
9
+ array = ["Something went wrong! Try again later"] if max_length <= 0
10
+ else
11
+ array = [message]
12
+ end
13
+ array
14
+ end
15
+ end
16
+ end
@@ -9,8 +9,8 @@ module ChatgptAssistant
9
9
 
10
10
  sidekiq_options queue: :default
11
11
 
12
- def perform(email, password, chat_id)
13
- RegisterService.new(email, password, chat_id).call
12
+ def perform(email, password, name, chat_id)
13
+ RegisterService.new(email, password, name, chat_id).call
14
14
  end
15
15
  end
16
16
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "application_mailer"
4
+
5
+ module ChatgptAssistant
6
+ # This class is responsible for the register mailer
7
+ class AccountMailer < ApplicationMailer
8
+ def register_email(user, token)
9
+ @user = user
10
+ @token = token
11
+ mail(to: user.email, subject: "Welcome to ChatGPT Assistant",
12
+ content_type: "text/html",
13
+ body: register_html)
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :user, :token
19
+
20
+ def register_html
21
+ "<h1>Welcome to ChatGPT Assistant</h1> \n
22
+ <p>Hi #{user.name}</p> \n
23
+ <p>You are now registered to ChatGPT Assistant</p> \n
24
+ <p>You can now start using the bot</p> \n
25
+ <p>To start using the bot, copy and paste the following link in TELEGRAM bot:</p> \n
26
+ <p>confirm/* #{user.name}:#{token}</p> \n
27
+ "
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Gem module
4
+ module ChatgptAssistant
5
+ ActionMailer::Base.raise_delivery_errors = true
6
+ ActionMailer::Base.delivery_method = :smtp
7
+ ActionMailer::Base.smtp_settings = {
8
+ address: ENV.fetch("SMTP_ADDRESS", nil),
9
+ port: ENV.fetch("SMTP_PORT", nil),
10
+ domain: ENV.fetch("SMTP_DOMAIN", nil),
11
+ user_name: ENV.fetch("SMTP_USER_NAME", nil),
12
+ password: ENV.fetch("SMTP_PASSWORD", nil),
13
+ authentication: ENV.fetch("SMTP_AUTHENTICATION", nil),
14
+ enable_starttls_auto: ENV.fetch("SMTP_ENABLE_STARTTLS_AUTO", nil) == "true"
15
+ }
16
+
17
+ # This class is responsible for the application mailer
18
+ class ApplicationMailer < ActionMailer::Base
19
+ default from: "support@chat.outerspacecoding.com"
20
+ end
21
+ end
@@ -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,121 @@
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?(name, token)
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
+ delete_file user_audio[:file]
108
+ rescue UserNotLoggedInError, NoChatSelectedError, MessageNotCreatedError, AccountNotVerifiedError => e
109
+ send_message e.message, msg.chat.id
110
+ end
111
+
112
+ def telegram_chat_event
113
+ common_allowed?
114
+ chat_if_exists
115
+ rescue UserNotLoggedInError, AccountNotVerifiedError => e
116
+ send_message e.message, msg.chat.id
117
+ end
118
+ end
119
+ end
120
+ end
121
+ 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?(name, token)
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