diff --git a/.idea/OpenChatAiBot.iml b/.idea/OpenChatAiBot.iml
index 74d515a..e0fc69a 100644
--- a/.idea/OpenChatAiBot.iml
+++ b/.idea/OpenChatAiBot.iml
@@ -4,7 +4,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
index 14ea0b9..349fd04 100644
--- a/.idea/dataSources.xml
+++ b/.idea/dataSources.xml
@@ -1,18 +1,11 @@
-
+
sqlite.xerial
true
- Содержит в себе список(tg_id)
-пользователей бота с количеством
-истраченных символов, репутацией
-и лимитом символов для запросов.
org.sqlite.JDBC
- jdbc:sqlite:$PROJECT_DIR$/DataBase/UserList
-
-
-
+ jdbc:sqlite:$PROJECT_DIR$/DataBase/OCAB_DB.db
$ProjectFileDir$
diff --git a/src/OpenAI/GPT35turbo/OA_processing.py b/src/OpenAI/GPT35turbo/OA_processing.py
new file mode 100644
index 0000000..e9b3250
--- /dev/null
+++ b/src/OpenAI/GPT35turbo/OA_processing.py
@@ -0,0 +1,134 @@
+import sqlite3
+import os
+import configparser
+
+mother_path = os.path.dirname(os.path.dirname(os.getcwd()))
+
+config = configparser.ConfigParser()
+config.read(os.path.join(mother_path, 'src/config.ini'))
+
+database = sqlite3.connect(os.path.join(mother_path, 'DataBase/OCAB_DB.db'))
+cursor = database.cursor()
+
+# Импорт библиотек
+
+import openai
+max_token_count = int(config['Openai']['max_token_count'])
+
+base_message_formated_text = [
+ {
+ "role": "system",
+ "content": config['Openai']['story_model']
+ }
+]
+
+
+def openai_response(message_formated_text):
+ # Запуск OpenAI
+ # Считаем размер полученного текста
+ print(message_formated_text)
+ count_length = 0
+ for message in message_formated_text:
+ print(message["content"])
+ count_length += len(message["content"])
+ print(count_length)
+ response = openai.ChatCompletion.create(
+ model="gpt-3.5-turbo",
+ messages=message_formated_text,
+ max_tokens=max_token_count - count_length
+ )
+ return response
+
+def sort_message_from_user(message_formated_text, message_id):
+ print(int(*(
+ cursor.execute("SELECT message_sender FROM message_list WHERE message_id = ?", (message_id,)).fetchone())))
+ if int(*(
+ cursor.execute("SELECT message_sender FROM message_list WHERE message_id = ?",
+ (message_id,)).fetchone())) == 0:
+ message_formated_text.append({
+ "role": "assistant",
+ "content": str(*(cursor.execute("SELECT message_text FROM message_list WHERE message_id = ?",
+ (message_id,)).fetchone()))
+ })
+ else:
+ message_formated_text.append({
+ "role": "user",
+ "content": str(*(cursor.execute("SELECT message_text FROM message_list WHERE message_id = ?",
+ (message_id,)).fetchone()))
+ })
+ #Проверка что длина всех сообщений в кортеже не превышает max_token_count-500
+ count_length = 0
+ for message in message_formated_text:
+ count_length += len(message['content'])
+ if count_length > max_token_count-800:
+ message_formated_text.pop(1)
+ return message_formated_text
+
+def openai_collecting_message(message_id, message_formated_text):
+ # собирает цепочку сообщений для OpenAI длинной до max_token_count
+ # проверяем что сообщение отвечает на другое сообщение
+ if int(*(cursor.execute("SELECT answer_id FROM message_list WHERE message_id = ?", (message_id,)).fetchone())) not in (0, 643885, 476959, 1, 476977, 633077, 630664, 476966, 634567):
+ # Продолжаем искать ответы на сообщения
+ print(int(*(cursor.execute("SELECT answer_id FROM message_list WHERE message_id = ?", (message_id,)).fetchone())))
+ message_formated_text = openai_collecting_message(int(*(cursor.execute("SELECT answer_id FROM message_list WHERE message_id = ?", (message_id,)).fetchone())), message_formated_text)
+ #Проверяем ID отправителя сообщения, если 0 то это сообщение от бота
+ sort_message_from_user(message_formated_text, message_id)
+ else:
+ # Проверяем ID отправителя сообщения, если 0 то это сообщение от бота
+ sort_message_from_user(message_formated_text, message_id)
+ return message_formated_text
+
+
+
+
+
+
+
+
+
+
+
+
+
+ # if (((cursor.execute("SELECT answer_id FROM message_list WHERE message_id") is None)) or (cursor.execute("SELECT answer_id FROM message_list WHERE message_id") == 643885)):
+ # openai_collecting_message(cursor.execute("SELECT answer_id FROM message_list WHERE message_id"))
+ # # проверяем что с новым сообщение длина всех сообщений в цепочке не будет превышать max_token_count
+ # count_length = 0
+ # for message in message_formated_text:
+ # count_length += len(message['content'])
+ # if count_length + len(cursor.execute("SELECT message_text FROM message_list WHERE message_id = ?", (message_id,)).fetchone()) > max_token_count:
+ # message_formated_text.pop(1)
+ # print(int(*(cursor.execute("SELECT message_sender FROM message_list WHERE message_id = ?", (message_id,)).fetchone())))
+ # if int(*(cursor.execute("SELECT message_sender FROM message_list WHERE message_id = ?", (message_id,)).fetchone())) == 0:
+ # message_formated_text.append({
+ # "role": "assistant",
+ # "content": str(*(cursor.execute("SELECT message_text FROM message_list WHERE message_id = ?", (message_id,)).fetchone()))
+ # })
+ # else:
+ # message_formated_text.append({
+ # "role": "user",
+ # "content": str(*(cursor.execute("SELECT message_text FROM message_list WHERE message_id = ?", (message_id,)).fetchone()))
+ # })
+
+
+
+
+def openai_message_processing(message_id):
+ #проверяем на наличие сообщения в базе данных
+ if cursor.execute("SELECT message_text FROM message_list WHERE message_id = ?", (message_id,)).fetchone() is None:
+ return None
+ else:
+ # проверяем на то что сообщение влезает в max_token_count с учётом message_formated_text
+ #print((len(str(cursor.execute("SELECT message_text FROM message_list WHERE message_id")))))
+ #print(len(message_formated_text[0]['content']))
+ #print(max_token_count)
+ #print(max_token_count - len(message_formated_text[0]['content']))
+ message_formated_text = base_message_formated_text
+ if ((len(str(cursor.execute("SELECT message_text FROM message_list WHERE message_id")))) < (max_token_count - len(message_formated_text[0]['content']))):
+ message_formated_text = openai_collecting_message(message_id, message_formated_text)
+ response = openai_response(message_formated_text)
+ return response
+ else:
+ return f"Сообщение слишком длинное, максимальная длина сообщения \
+ {max_token_count - len(message_formated_text[0]['content'])} символов, укоротите его на \
+ {len(str(cursor.execute('SELECT message_text FROM message_list WHERE message_id'))) - max_token_count} символов"
\ No newline at end of file
diff --git a/src/TelegramBot/MessageHandler.py b/src/TelegramBot/MessageHandler.py
index 5311712..e6b8759 100644
--- a/src/TelegramBot/MessageHandler.py
+++ b/src/TelegramBot/MessageHandler.py
@@ -3,12 +3,6 @@ from aiogram import types
from src.TelegramBot.main import dp
+from main import cursor, config
-@dp.message_handler()
-async def send(message: types.Message):
- # Получение сообщений в чате, и запись их в базу данных
- # Проверка на то, что сообщение не пустое и не отправлено в чате содержащим ChatType = 1 в базе данных chatlist
- if (message.chat.type == "group" or message.chat.type == "supergroup") and \
- message.text != '' and message.text != ' ': return None
- else:
- # Проверка статуса ChatType в базе данных chatlist
+#импортировать функцию для обработки сообщений из OpenAI
diff --git a/src/TelegramBot/main.py b/src/TelegramBot/main.py
index 9c981b0..c304449 100644
--- a/src/TelegramBot/main.py
+++ b/src/TelegramBot/main.py
@@ -1,23 +1,29 @@
-# Файл с инициализацией всех процессов телеграмм бота и запуском API OpenAI
-
# Импорт библиотек
import os
+from contextlib import suppress
+
import openai
import configparser
import sqlite3
+import asyncio
from aiogram import Bot, Dispatcher, executor, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
+from aiogram.utils.exceptions import MessageCantBeDeleted, MessageToDeleteNotFound
-from MessageHandler import *
+mother_path = os.path.dirname(os.path.dirname(os.getcwd()))
# Импорт переменных из файла .ini
config = configparser.ConfigParser()
-config.read(os.path.join(os.path.dirname(__file__), 'config.ini'))
-
+config.read(os.path.join(mother_path, 'src/config.ini'))
TOKEN = config['Telegram']['token']
-OPENAI_API_KEY = config['OpenAI']['api_key']
+OPENAI_API_KEY = (config['Openai']['api_key'])
+bot_trigger_front = (config['Telegram']['bot_trigger_front']).split('|')
+bot_trigger_all = (config['Telegram']['bot_trigger_all']).split('|')
+# удаление лишних элементов массивов
+bot_trigger_front.remove('')
+bot_trigger_all.remove('')
# Инициализация бота
@@ -29,8 +35,100 @@ dp = Dispatcher(bot, storage=MemoryStorage())
openai.api_key = OPENAI_API_KEY
# Инициализация базы данных OCAB_DB в папке DataBase/OCAB_DB.db
-database = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'DataBase/OCAB_DB.db'))
+# Создаём базу данных sqlite3 по пути /home/armatik/PycharmProjects/OpenChatAiBot/DataBase/OCAB_DB.db
+database = sqlite3.connect(os.path.join(mother_path, 'DataBase/OCAB_DB.db'))
cursor = database.cursor()
+# Создаём таблицу chat_list
+cursor.execute("""CREATE TABLE IF NOT EXISTS chat_list (
+ chat_id INTEGER PRIMARY KEY,
+ chat_role INTEGER NOT NULL,
+ chat_stats INTEGER NOT NULL
+)""")
+# Создаём таблицу message_list
+cursor.execute("""CREATE TABLE IF NOT EXISTS message_list (
+ message_id INTEGER PRIMARY KEY,
+ message_text TEXT NOT NULL,
+ message_sender INTEGER NOT NULL,
+ answer_id INTEGER
+)""")
+# Создаём таблицу user_list
+cursor.execute("""CREATE TABLE IF NOT EXISTS user_list (
+ user_id INTEGER PRIMARY KEY,
+ user_role INTEGER,
+ user_stats INTEGER
+)""")
+
+#запись информации о чате в базу данных
+@dp.message_handler(commands=['start'])
+async def start(message: types.Message):
+ chat_id = message.chat.id
+ chat_role = 0
+ chat_stats = 1
+ cursor.execute("INSERT INTO chat_list VALUES (?, ?, ?)", (chat_id, chat_role, chat_stats))
+ database.commit()
+ await message.reply("Привет, я бот, который учится на основе модели GPT-3.5. "
+ "Я могу поговорить с тобой на любую тему, но пока что я не очень умный, поэтому не обижайся, "
+ "если я не пойму тебя. Чтобы начать общение со мной, напиши мне сообщение, начинающееся с "
+ "слова Арма, например: Арма, как дела?")
+
+from src.OpenAI.GPT35turbo.OA_processing import openai_message_processing
+
+
+async def delete_message(message: types.Message, sleep_time: int = 0):
+ await asyncio.sleep(sleep_time)
+ with suppress(MessageCantBeDeleted, MessageToDeleteNotFound):
+ await message.delete()
+
+@dp.message_handler()
+async def in_message(message: types.Message):
+ chat_id = message.chat.id
+ # Получение сообщений в чате, и запись их в базу данных
+ # Проверка на то, что сообщение не пустое и не отправлено в чате содержащим ChatType = 1 в базе данных chatlist
+ if (message.chat.type != "group" or message.chat.type != "supergroup") and \
+ message.text != '' and message.text != ' ' and \
+ (cursor.execute("SELECT chat_role FROM chat_list WHERE chat_id;") == 1): return None
+ else:
+ # Запись сообщения в базу данных
+ cursor.execute("INSERT INTO message_list VALUES (?, ?, ?, ?)",
+ (message.message_id, message.text, message.from_user.id, None))
+ if message.reply_to_message is not None:
+ # Запись ответа на сообщение в базу данных
+ cursor.execute("UPDATE message_list SET answer_id = ? WHERE message_id = ?",
+ (message.reply_to_message.message_id, message.message_id))
+ database.commit()
+ # Обработка сообщения OpenAI
+ send_answer = False
+ # импортируем массив триггеров из файла .ini
+ if message.reply_to_message and message.reply_to_message.from_user.id == (await bot.me).id:
+ send_answer = True
+ for trigger in bot_trigger_all:
+ if trigger.lower() in message.text.lower():
+ send_answer = True
+ for trigger in bot_trigger_front:
+ if message.text.lower().startswith(trigger.lower()):
+ send_answer = True
+
+ if send_answer:
+ your_id = message.from_id
+ your_name = message.from_user.username
+ temp_msg = await message.reply(
+ f"[{your_name}](tg://user?id={str(your_id)}), Подожди немного и я обязательно отвечу тебе!",
+ parse_mode="Markdown")
+ response = openai_message_processing(message.message_id)
+ if response is None:
+ bot_message_id = await message.reply("Я не понял тебя, попробуй перефразировать")
+ asyncio.create_task(delete_message(temp_msg, 0))
+ #заносим сообщение в базу данных в качестве message_id пишем id сообщения которое отправил бот
+ cursor.execute("INSERT INTO message_list VALUES (?, ?, ?, ?)",
+ (bot_message_id, "Я не понял тебя, попробуй перефразировать", 0, message.message_id))
+ else:
+ bot_message_id = await message.reply(response['choices'][0]['message']['content'], parse_mode="markdown")
+ asyncio.create_task(delete_message(temp_msg, 0))
+ #заносим сообщение в базу данных в качестве message_id мы пишем id сообщения в bot_message_id
+ cursor.execute("INSERT INTO message_list VALUES (?, ?, ?, ?)",
+ (bot_message_id.message_id, response['choices'][0]['message']['content'], 0, message.message_id))
+ database.commit()
+
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)
\ No newline at end of file
diff --git a/src/config.ini b/src/config.ini
index c2ac29c..4625b23 100644
--- a/src/config.ini
+++ b/src/config.ini
@@ -1,7 +1,24 @@
[Telegram]
-token="....."
-admin_password="Test_pass" # ONLY FOR ADDING CHAT TO ADMIN LIST!
+token=****
+admin_password="Test_pass"
+# Пока не используется
-[OpenAI]
-token="....."
-chat_model="....."
\ No newline at end of file
+# Массивы заполнять через запятую. Пример: test|test2 |test3,
+bot_trigger_front=
+# Живой пример: Арма |Армат |Арма, |
+bot_trigger_all=
+# Живой пример: @arma_ai_bot |помогите |
+
+[Openai]
+api_key=****
+chat_model=gpt-3.5-turbo
+story_model=
+# Тут должен быть текст истории бота, но я его не показываю)))
+max_token_count=4000
+# максимальное количество токенов в сообщении
+min_token_for_answer=800
+# минимальное количество токенов в сообщении ответа бота (чем больше, тем более длинный ответ ГАРАНТИРОВАН)
+
+[AI_Dungeon]
+use=openai
+# "openai" or "YaGPT" Пока не используется
\ No newline at end of file