chatgpt_assistant 0.1.3 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -1
- data/Dockerfile +1 -1
- data/Gemfile +3 -1
- data/Gemfile.lock +17 -6
- data/Rakefile +2 -0
- data/SECURITY.md +15 -0
- data/exe/chatgpt_bot +1 -1
- data/lib/bots/discord_bot.rb +43 -13
- data/lib/bots/helpers/authentication_helper.rb +6 -6
- data/lib/bots/helpers/discord_helper.rb +26 -4
- data/lib/bots/helpers/discord_voice_helper.rb +1 -1
- data/lib/bots/helpers/logger_action_helper.rb +0 -7
- data/lib/bots/helpers/messenger_helper.rb +28 -26
- data/lib/bots/helpers/telegram_helper.rb +16 -28
- data/lib/bots/helpers/telegram_voice_helper.rb +33 -0
- data/lib/bots/helpers/validation_helper.rb +9 -0
- data/lib/bots/telegram_bot.rb +2 -15
- data/lib/chatgpt_assistant/audio_recognition.rb +4 -6
- data/lib/chatgpt_assistant/audio_synthesis.rb +2 -6
- data/lib/chatgpt_assistant/chatter.rb +17 -6
- data/lib/chatgpt_assistant/config.rb +17 -19
- data/lib/chatgpt_assistant/migrations.rb +4 -31
- data/lib/chatgpt_assistant/models.rb +9 -21
- data/lib/chatgpt_assistant/version.rb +1 -1
- data/lib/chatgpt_assistant.rb +1 -0
- data/prompts-data/awesome-chatgpt-prompts.csv +164 -0
- metadata +6 -2
@@ -25,5 +25,14 @@ module ChatgptAssistant
|
|
25
25
|
def discord_voice_bot_connected?
|
26
26
|
user && evnt.user.voice_channel && evnt.voice && !chat.nil?
|
27
27
|
end
|
28
|
+
|
29
|
+
def discord_next_action?
|
30
|
+
return true if evnt.channel.type != 1
|
31
|
+
|
32
|
+
%w[login register start help new_chat sl_chat ask list hist connect disconnect speak].each do |action|
|
33
|
+
return true if evnt.message.content.include?("#{discord_prefix}#{action}")
|
34
|
+
end
|
35
|
+
false
|
36
|
+
end
|
28
37
|
end
|
29
38
|
end
|
data/lib/bots/telegram_bot.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "helpers/telegram_helper"
|
4
|
+
require_relative "helpers/telegram_voice_helper"
|
4
5
|
|
5
6
|
module ChatgptAssistant
|
6
7
|
# This class is responsible for the telegram bot features
|
@@ -24,6 +25,7 @@ module ChatgptAssistant
|
|
24
25
|
private
|
25
26
|
|
26
27
|
include TelegramHelper
|
28
|
+
include TelegramVoiceHelper
|
27
29
|
|
28
30
|
attr_accessor :msg, :visitor, :chat, :chat_id
|
29
31
|
|
@@ -47,14 +49,10 @@ module ChatgptAssistant
|
|
47
49
|
end
|
48
50
|
|
49
51
|
def start_event
|
50
|
-
register_visitor_action("start", visitor.id) unless visitor.tel_user
|
51
|
-
register_user_action("start", visitor.tel_user.id) if visitor.tel_user
|
52
52
|
telegram_send_start_message
|
53
53
|
end
|
54
54
|
|
55
55
|
def help_event
|
56
|
-
register_visitor_action("help", visitor.id) unless visitor.tel_user
|
57
|
-
register_user_action("help", visitor.tel_user.id) if visitor.tel_user
|
58
56
|
help_messages.each { |m| send_message m, msg.chat.id }
|
59
57
|
end
|
60
58
|
|
@@ -63,7 +61,6 @@ module ChatgptAssistant
|
|
63
61
|
return no_chat_selected_message unless user.current_chat
|
64
62
|
return no_messages_founded_message if user.current_chat.messages.count.zero?
|
65
63
|
|
66
|
-
register_user_action("hist", user.id)
|
67
64
|
telegram_user_history.each do |m|
|
68
65
|
send_message m, msg.chat.id
|
69
66
|
end
|
@@ -72,7 +69,6 @@ module ChatgptAssistant
|
|
72
69
|
def list_event
|
73
70
|
return unless valid_for_list_action?
|
74
71
|
|
75
|
-
register_user_action("list", user.id)
|
76
72
|
send_message commom_messages[:chat_list], msg.chat.id
|
77
73
|
chats_str = ""
|
78
74
|
user.chats.each_with_index { |c, i| chats_str += "Chat #{i + 1} - #{c.title}\n" }
|
@@ -90,7 +86,6 @@ module ChatgptAssistant
|
|
90
86
|
end
|
91
87
|
|
92
88
|
def login_event
|
93
|
-
register_visitor_action("login", visitor.id) unless visitor.tel_user
|
94
89
|
user_info = msg.text.split("/").last
|
95
90
|
email, password = user_info.split(":")
|
96
91
|
case telegram_user_auth(email, password, msg.chat.id)
|
@@ -104,7 +99,6 @@ module ChatgptAssistant
|
|
104
99
|
end
|
105
100
|
|
106
101
|
def register_event
|
107
|
-
register_visitor_action("register", visitor.id)
|
108
102
|
user_info = msg.text.split("/").last
|
109
103
|
email, password = user_info.split(":")
|
110
104
|
registered_email = telegram_user_create visitor.id, email, password
|
@@ -114,14 +108,12 @@ module ChatgptAssistant
|
|
114
108
|
def new_chat_event
|
115
109
|
return not_logged_in_message unless user
|
116
110
|
|
117
|
-
register_user_action("new_chat", user.id)
|
118
111
|
telegram_create_chat
|
119
112
|
end
|
120
113
|
|
121
114
|
def select_chat_event
|
122
115
|
return not_logged_in_message unless user
|
123
116
|
|
124
|
-
register_user_action("select_chat", user.id)
|
125
117
|
title = msg.text.split("/").last
|
126
118
|
chat = user.chat_by_title(title)
|
127
119
|
return chat_not_found_message unless chat
|
@@ -131,15 +123,11 @@ module ChatgptAssistant
|
|
131
123
|
end
|
132
124
|
|
133
125
|
def stop_event
|
134
|
-
register_event_action("stop", visitor.id) unless visitor.tel_user
|
135
|
-
register_user_action("stop", visitor.tel_user.id) if visitor.tel_user
|
136
126
|
send_message commom_messages[:stop], msg.chat.id
|
137
127
|
bot.api.leave_chat(chat_id: msg.chat.id)
|
138
128
|
end
|
139
129
|
|
140
130
|
def nil_event
|
141
|
-
register_event_action("nil", visitor.id) unless visitor.tel_user
|
142
|
-
register_user_action("nil", visitor.tel_user.id) if visitor.tel_user
|
143
131
|
send_message error_messages[:nil], msg.chat.id
|
144
132
|
end
|
145
133
|
|
@@ -147,7 +135,6 @@ module ChatgptAssistant
|
|
147
135
|
return not_logged_in_message unless user
|
148
136
|
return no_chat_selected_message if user.current_chat_id.nil?
|
149
137
|
|
150
|
-
register_user_action("audio", user.id)
|
151
138
|
user_audio = transcribe_file(telegram_audio_url)
|
152
139
|
message = Message.new(content: user_audio[:text], chat_id: user.current_chat_id, role: "user")
|
153
140
|
if message.save
|
@@ -29,9 +29,7 @@ module ChatgptAssistant
|
|
29
29
|
|
30
30
|
def download_audio(audio_url)
|
31
31
|
audio_conn = Faraday.new(url: audio_url)
|
32
|
-
File.
|
33
|
-
file.write(audio_conn.get.body)
|
34
|
-
end
|
32
|
+
File.binwrite(dl_file_name, audio_conn.get.body)
|
35
33
|
FFMPEG::Movie.new(dl_file_name).transcode(file_name)
|
36
34
|
File.delete(dl_file_name)
|
37
35
|
end
|
@@ -39,14 +37,14 @@ module ChatgptAssistant
|
|
39
37
|
def header
|
40
38
|
{
|
41
39
|
"Content-Type": "multipart/form-data",
|
42
|
-
|
40
|
+
Authorization: "Bearer #{openai_api_key}"
|
43
41
|
}
|
44
42
|
end
|
45
43
|
|
46
44
|
def payload
|
47
45
|
{
|
48
|
-
|
49
|
-
|
46
|
+
file: Faraday::UploadIO.new(file_name, "audio/mp3"),
|
47
|
+
model: "whisper-1"
|
50
48
|
}
|
51
49
|
end
|
52
50
|
|
@@ -61,9 +61,7 @@ module ChatgptAssistant
|
|
61
61
|
engine: "neural"
|
62
62
|
)
|
63
63
|
|
64
|
-
File.
|
65
|
-
file.write(response.audio_stream.read)
|
66
|
-
end
|
64
|
+
File.binwrite("voice/aws-#{time}.mp3", response.audio_stream.read)
|
67
65
|
"voice/aws-#{time}.mp3"
|
68
66
|
end
|
69
67
|
|
@@ -86,9 +84,7 @@ module ChatgptAssistant
|
|
86
84
|
voice: voice
|
87
85
|
).result
|
88
86
|
|
89
|
-
File.
|
90
|
-
audio_file.write(audio)
|
91
|
-
end
|
87
|
+
File.binwrite("voice/ibm-#{time}.mp3", audio)
|
92
88
|
"voice/ibm-#{time}.mp3"
|
93
89
|
end
|
94
90
|
|
@@ -10,27 +10,36 @@ module ChatgptAssistant
|
|
10
10
|
@openai_api_key = openai_api_key
|
11
11
|
end
|
12
12
|
|
13
|
-
def chat(message, chat_id)
|
13
|
+
def chat(message, chat_id, error_message)
|
14
|
+
@error_message = error_message
|
14
15
|
@chat_id = chat_id
|
15
16
|
@message = message
|
16
17
|
@response = request(message)
|
17
18
|
@json = JSON.parse(response.body)
|
18
19
|
|
19
|
-
return
|
20
|
+
return no_response_error if json["choices"].empty?
|
21
|
+
return bot_offline_error if response.status != 200
|
20
22
|
|
21
23
|
text = json["choices"][0]["message"]["content"]
|
22
24
|
|
23
25
|
Message.create(content: text, role: "assistant", chat_id: chat_id)
|
24
26
|
text
|
27
|
+
rescue StandardError => e
|
28
|
+
Error.create(message: e.message, backtrace: e.backtrace)
|
29
|
+
error_message
|
25
30
|
end
|
26
31
|
|
27
32
|
private
|
28
33
|
|
29
34
|
attr_reader :openai_api_key, :response, :message
|
30
|
-
attr_accessor :chat_id, :json
|
35
|
+
attr_accessor :chat_id, :json, :error_message
|
31
36
|
|
32
|
-
def
|
33
|
-
"
|
37
|
+
def no_response_error
|
38
|
+
"I'm sorry, I didn't understand you. Please, try again."
|
39
|
+
end
|
40
|
+
|
41
|
+
def bot_offline_error
|
42
|
+
"I'm sorry, I'm offline. Please, try again later."
|
34
43
|
end
|
35
44
|
|
36
45
|
def header
|
@@ -59,7 +68,9 @@ module ChatgptAssistant
|
|
59
68
|
end
|
60
69
|
{
|
61
70
|
model: "gpt-3.5-turbo",
|
62
|
-
messages: messages
|
71
|
+
messages: messages,
|
72
|
+
max_tokens: 1000,
|
73
|
+
temperature: 0.1
|
63
74
|
}.to_json
|
64
75
|
end
|
65
76
|
|
@@ -9,23 +9,23 @@ module ChatgptAssistant
|
|
9
9
|
# This class is responsible for the configuration of the Chatgpt Assistant
|
10
10
|
class Config
|
11
11
|
def initialize
|
12
|
-
@env_type = ENV
|
13
|
-
@language = ENV
|
14
|
-
@mode = ENV
|
15
|
-
@database_host = ENV
|
16
|
-
@database_name = ENV
|
17
|
-
@database_username = ENV
|
18
|
-
@database_password = ENV
|
19
|
-
@openai_api_key = ENV
|
20
|
-
@telegram_token = ENV
|
21
|
-
@discord_token = ENV
|
22
|
-
@discord_client_id = ENV
|
23
|
-
@ibm_api_key = ENV
|
24
|
-
@ibm_url = ENV
|
25
|
-
@aws_access_key_id = ENV
|
26
|
-
@aws_secret_access_key = ENV
|
27
|
-
@aws_region = ENV
|
28
|
-
@discord_prefix = ENV
|
12
|
+
@env_type = ENV.fetch("ENV_TYPE", nil)
|
13
|
+
@language = ENV.fetch("LANGUAGE", nil)
|
14
|
+
@mode = ENV.fetch("MODE", nil)
|
15
|
+
@database_host = ENV.fetch("POSTGRES_HOST", nil)
|
16
|
+
@database_name = ENV.fetch("POSTGRES_DB", nil)
|
17
|
+
@database_username = ENV.fetch("POSTGRES_USER", nil)
|
18
|
+
@database_password = ENV.fetch("POSTGRES_PASSWORD", nil)
|
19
|
+
@openai_api_key = ENV.fetch("OPENAI_API_KEY", nil)
|
20
|
+
@telegram_token = ENV.fetch("TELEGRAM_TOKEN", nil)
|
21
|
+
@discord_token = ENV.fetch("DISCORD_TOKEN", nil)
|
22
|
+
@discord_client_id = ENV.fetch("DISCORD_CLIENT_ID", nil)
|
23
|
+
@ibm_api_key = ENV.fetch("IBM_API_KEY", nil)
|
24
|
+
@ibm_url = ENV.fetch("IBM_URL", nil)
|
25
|
+
@aws_access_key_id = ENV.fetch("AWS_ACCESS_KEY_ID", nil)
|
26
|
+
@aws_secret_access_key = ENV.fetch("AWS_SECRET_ACCESS_KEY", nil)
|
27
|
+
@aws_region = ENV.fetch("AWS_REGION", nil)
|
28
|
+
@discord_prefix = ENV.fetch("DISCORD_PREFIX", nil)
|
29
29
|
end
|
30
30
|
|
31
31
|
attr_reader :openai_api_key, :telegram_token, :discord_token, :ibm_api_key, :ibm_url,
|
@@ -48,9 +48,7 @@ module ChatgptAssistant
|
|
48
48
|
db_connection
|
49
49
|
ActiveRecord::Base.logger = Logger.new($stdout)
|
50
50
|
VisitorMigration.new.migrate(:up)
|
51
|
-
VisitorActionsMigration.new.migrate(:up)
|
52
51
|
UserMigration.new.migrate(:up)
|
53
|
-
UserActionsMigration.new.migrate(:up)
|
54
52
|
ChatMigration.new.migrate(:up)
|
55
53
|
MessageMigration.new.migrate(:up)
|
56
54
|
ErrorMigration.new.migrate(:up)
|
@@ -13,22 +13,7 @@ class VisitorMigration < ActiveRecord::Migration[5.2]
|
|
13
13
|
t.string :discord_id, limit: 100
|
14
14
|
t.integer :platform, null: false, default: 0
|
15
15
|
t.string :name, null: false
|
16
|
-
t.integer :current_user_id,
|
17
|
-
t.timestamps
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# VisitorActions model
|
23
|
-
class VisitorActionsMigration < ActiveRecord::Migration[5.2]
|
24
|
-
def change
|
25
|
-
return if ActiveRecord::Base.connection.table_exists? :visitor_actions
|
26
|
-
|
27
|
-
create_table :visitor_actions do |t|
|
28
|
-
t.references :visitor, null: false, foreign_key: true
|
29
|
-
t.text :action, null: false
|
30
|
-
t.text :description, null: false
|
31
|
-
t.integer :role, null: false, default: 0
|
16
|
+
t.integer :current_user_id, default: 0
|
32
17
|
t.timestamps
|
33
18
|
end
|
34
19
|
end
|
@@ -56,21 +41,6 @@ class UserMigration < ActiveRecord::Migration[5.2]
|
|
56
41
|
end
|
57
42
|
end
|
58
43
|
|
59
|
-
# UserActions model
|
60
|
-
class UserActionsMigration < ActiveRecord::Migration[5.2]
|
61
|
-
def change
|
62
|
-
return if ActiveRecord::Base.connection.table_exists? :user_actions
|
63
|
-
|
64
|
-
create_table :user_actions do |t|
|
65
|
-
t.references :user, null: false, foreign_key: true
|
66
|
-
t.text :action, null: false, default: ""
|
67
|
-
t.text :description, null: false, default: ""
|
68
|
-
t.integer :role, null: false, default: 0
|
69
|
-
t.timestamps
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
44
|
# Chat model
|
75
45
|
class ChatMigration < ActiveRecord::Migration[5.2]
|
76
46
|
def change
|
@@ -80,6 +50,9 @@ class ChatMigration < ActiveRecord::Migration[5.2]
|
|
80
50
|
t.references :user, null: false, foreign_key: true
|
81
51
|
t.text :title, null: false, default: "", limit: 100
|
82
52
|
t.integer :status, null: false, default: 0
|
53
|
+
t.integer :messages_count, null: false, default: 0
|
54
|
+
t.string :actor
|
55
|
+
t.text :prompt
|
83
56
|
t.timestamps
|
84
57
|
end
|
85
58
|
end
|
@@ -7,8 +7,6 @@ class Visitor < ActiveRecord::Base
|
|
7
7
|
has_many :visitor_actions
|
8
8
|
# has_one :tel_user, foreign_key: "telegram_id", class_name: "User"
|
9
9
|
# has_one :dis_user, foreign_key: "discord_id", class_name: "User"
|
10
|
-
validates :telegram_id, uniqueness: true
|
11
|
-
validates :discord_id, uniqueness: true
|
12
10
|
validates :name, presence: true
|
13
11
|
validates :platform, presence: true
|
14
12
|
enum platform: { telegram: 0, discord: 1 }
|
@@ -22,15 +20,6 @@ class Visitor < ActiveRecord::Base
|
|
22
20
|
end
|
23
21
|
end
|
24
22
|
|
25
|
-
# VisitorActions model
|
26
|
-
class VisitorAction < ActiveRecord::Base
|
27
|
-
belongs_to :visitor
|
28
|
-
validates :action, presence: true
|
29
|
-
validates :description, presence: true
|
30
|
-
validates :role, presence: true
|
31
|
-
enum role: { user: 0, assistant: 1, warning: 2 }
|
32
|
-
end
|
33
|
-
|
34
23
|
# User model
|
35
24
|
class User < ActiveRecord::Base
|
36
25
|
attr_accessor :password
|
@@ -66,16 +55,6 @@ class User < ActiveRecord::Base
|
|
66
55
|
end
|
67
56
|
end
|
68
57
|
|
69
|
-
# UserActions model
|
70
|
-
class UserAction < ActiveRecord::Base
|
71
|
-
belongs_to :user
|
72
|
-
validates :user_id, presence: true
|
73
|
-
validates :action, presence: true
|
74
|
-
validates :description, presence: true
|
75
|
-
validates :role, presence: true
|
76
|
-
enum role: { user: 0, assistant: 1, warning: 2 }
|
77
|
-
end
|
78
|
-
|
79
58
|
# Chat model
|
80
59
|
class Chat < ActiveRecord::Base
|
81
60
|
validates :user_id, presence: true
|
@@ -84,6 +63,15 @@ class Chat < ActiveRecord::Base
|
|
84
63
|
|
85
64
|
belongs_to :user
|
86
65
|
has_many :messages
|
66
|
+
|
67
|
+
after_create :init_chat_if_actor_provided
|
68
|
+
|
69
|
+
def init_chat_if_actor_provided
|
70
|
+
return if actor.nil?
|
71
|
+
|
72
|
+
messages.create(content: prompt, role: "user")
|
73
|
+
messages.create(content: "Hello, I'm #{actor}. I will follow #{prompt}", role: "assistant")
|
74
|
+
end
|
87
75
|
end
|
88
76
|
|
89
77
|
# Message model
|
data/lib/chatgpt_assistant.rb
CHANGED
@@ -10,6 +10,7 @@ require_relative "chatgpt_assistant/models"
|
|
10
10
|
require_relative "bots/application_bot"
|
11
11
|
require_relative "bots/telegram_bot"
|
12
12
|
require_relative "bots/discord_bot"
|
13
|
+
require "awesome_chatgpt_actors"
|
13
14
|
require "streamio-ffmpeg"
|
14
15
|
require "aws-sdk-polly"
|
15
16
|
require "telegram/bot"
|