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.
- checksums.yaml +4 -4
- data/.env_sample +35 -10
- data/.rubocop.yml +14 -3
- data/Dockerfile +11 -5
- data/Gemfile +25 -23
- data/Gemfile.lock +123 -85
- data/README.md +22 -22
- data/Rakefile +1 -0
- data/docker-compose.yml +8 -4
- data/exe/chatgpt_assistant +1 -1
- data/lib/chatgpt_assistant/audio_synthesis.rb +54 -15
- data/lib/{bots → chatgpt_assistant/bots}/application_bot.rb +0 -6
- data/lib/chatgpt_assistant/bots/discord/actions.rb +103 -0
- data/lib/chatgpt_assistant/bots/discord/auth.rb +36 -0
- data/lib/chatgpt_assistant/bots/discord/bot.rb +29 -0
- data/lib/chatgpt_assistant/bots/discord/chat_actions.rb +33 -0
- data/lib/chatgpt_assistant/bots/discord/events.rb +138 -0
- data/lib/chatgpt_assistant/bots/discord/validations.rb +38 -0
- data/lib/chatgpt_assistant/bots/discord/voice_actions.rb +33 -0
- data/lib/chatgpt_assistant/bots/discord/voice_checkers.rb +35 -0
- data/lib/chatgpt_assistant/bots/discord_bot.rb +41 -0
- data/lib/chatgpt_assistant/bots/helpers/messenger_helper.rb +16 -0
- data/lib/{bots → chatgpt_assistant/bots}/jobs/register_job.rb +2 -2
- data/lib/chatgpt_assistant/bots/mailers/account_mailer.rb +30 -0
- data/lib/chatgpt_assistant/bots/mailers/application_mailer.rb +21 -0
- data/lib/chatgpt_assistant/bots/services/new_chat_service.rb +59 -0
- data/lib/chatgpt_assistant/bots/services/register_service.rb +45 -0
- data/lib/chatgpt_assistant/bots/telegram/actions.rb +54 -0
- data/lib/chatgpt_assistant/bots/telegram/auth.rb +40 -0
- data/lib/chatgpt_assistant/bots/telegram/bot.rb +17 -0
- data/lib/chatgpt_assistant/bots/telegram/chat_actions.rb +30 -0
- data/lib/chatgpt_assistant/bots/telegram/events.rb +121 -0
- data/lib/chatgpt_assistant/bots/telegram/events_controller.rb +48 -0
- data/lib/chatgpt_assistant/bots/telegram/permissions.rb +48 -0
- data/lib/chatgpt_assistant/bots/telegram/validations.rb +55 -0
- data/lib/chatgpt_assistant/bots/telegram/voice_actions.rb +36 -0
- data/lib/chatgpt_assistant/bots/telegram_bot.rb +44 -0
- data/lib/chatgpt_assistant/chatter.rb +10 -2
- data/lib/chatgpt_assistant/config.rb +7 -1
- data/lib/chatgpt_assistant/default_messages.rb +10 -4
- data/lib/chatgpt_assistant/error.rb +9 -0
- data/lib/chatgpt_assistant/migrations.rb +5 -0
- data/lib/chatgpt_assistant/models.rb +20 -0
- data/lib/chatgpt_assistant/version.rb +1 -1
- data/lib/chatgpt_assistant.rb +5 -3
- metadata +35 -25
- data/.env_prod_sample +0 -18
- data/docker-compose.prod.yml +0 -34
- data/lib/bots/discord_bot.rb +0 -182
- data/lib/bots/helpers/authentication_helper.rb +0 -48
- data/lib/bots/helpers/discord_helper.rb +0 -124
- data/lib/bots/helpers/discord_voice_helper.rb +0 -50
- data/lib/bots/helpers/messenger_helper.rb +0 -133
- data/lib/bots/helpers/telegram_helper.rb +0 -73
- data/lib/bots/helpers/telegram_voice_helper.rb +0 -33
- data/lib/bots/helpers/validation_helper.rb +0 -38
- data/lib/bots/helpers/visit_helper.rb +0 -28
- data/lib/bots/services/new_chat_service.rb +0 -34
- data/lib/bots/services/register_service.rb +0 -36
- data/lib/bots/telegram_bot.rb +0 -180
- /data/lib/{bots → chatgpt_assistant/bots}/helpers/audio_helper.rb +0 -0
- /data/lib/{bots → chatgpt_assistant/bots}/helpers/file_helper.rb +0 -0
- /data/lib/{bots → chatgpt_assistant/bots}/helpers/search_helper.rb +0 -0
- /data/lib/{bots → chatgpt_assistant/bots}/jobs/new_chat_job.rb +0 -0
- /data/lib/{bots → chatgpt_assistant/bots}/jobs/voice_connect_job.rb +0 -0
- /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
|