Add button to force send next vacancy
All checks were successful
release / docker (push) Successful in 55s
All checks were successful
release / docker (push) Successful in 55s
This commit is contained in:
parent
d0131ab2a1
commit
ffffa973a6
@ -1,14 +1,14 @@
|
|||||||
import os
|
import os
|
||||||
import io
|
import io
|
||||||
import traceback
|
import traceback
|
||||||
from telegram import Update
|
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ReplyKeyboardMarkup, KeyboardButton
|
||||||
from telegram.ext import filters, ApplicationBuilder, MessageHandler, CommandHandler, ContextTypes
|
from telegram.ext import filters, ApplicationBuilder, MessageHandler, CommandHandler, ContextTypes
|
||||||
from pypdf import PdfReader
|
from pypdf import PdfReader
|
||||||
from vacancies.main.models import Customer, CustomerCV
|
from vacancies.main.models import Customer, CustomerCV
|
||||||
from langchain.agents import create_agent
|
from langchain.agents import create_agent
|
||||||
from langchain_openai import ChatOpenAI
|
from langchain_openai import ChatOpenAI
|
||||||
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
|
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
|
||||||
from vacancies.main.vector_store import add_vectors, extract_features
|
from vacancies.main.vector_store import add_vectors, extract_features, get_next_vacancy
|
||||||
from vacancies.conf.settings import DB_URI
|
from vacancies.conf.settings import DB_URI
|
||||||
|
|
||||||
SYSTEM_PROMPT = """
|
SYSTEM_PROMPT = """
|
||||||
@ -34,8 +34,36 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||||||
chat_id=update.effective_chat.id,
|
chat_id=update.effective_chat.id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
keyboard = [[KeyboardButton("Получить следующую вакансию")]]
|
||||||
|
reply_markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True, one_time_keyboard=False)
|
||||||
text = "Привет! Я карьерный копилот: помогу с работой, интервью и расскажу новости по рынку, специально для тебя. С чего начнем?"
|
text = "Привет! Я карьерный копилот: помогу с работой, интервью и расскажу новости по рынку, специально для тебя. С чего начнем?"
|
||||||
await context.bot.send_message(chat_id=update.effective_chat.id, text=text)
|
await context.bot.send_message(chat_id=update.effective_chat.id, text=text, reply_markup=reply_markup)
|
||||||
|
|
||||||
|
|
||||||
|
async def next_vacancy(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
await context.bot.send_message(update.effective_chat.id, "📝 Обрабатываю твой запрос. Пожалуйста, подождите...")
|
||||||
|
|
||||||
|
customer_cv = await CustomerCV.objects.filter(customer__telegram_id=update.effective_user.id).afirst()
|
||||||
|
if not customer_cv:
|
||||||
|
message = "Пришлите мне свое резюме, чтобы я мог подобрать вам вакансии!"
|
||||||
|
await context.bot.send_message(chat_id=update.effective_chat.id, text=message)
|
||||||
|
return
|
||||||
|
|
||||||
|
result = get_next_vacancy(customer_cv)
|
||||||
|
if not result:
|
||||||
|
message = "Вакансии закончились, возвращайтесь позже!"
|
||||||
|
await context.bot.send_message(chat_id=update.effective_chat.id, text=message)
|
||||||
|
return
|
||||||
|
|
||||||
|
recommendation, vacancy_content, link = result
|
||||||
|
|
||||||
|
await context.bot.send_message(
|
||||||
|
chat_id=update.effective_chat.id,
|
||||||
|
text=vacancy_content,
|
||||||
|
reply_markup=InlineKeyboardMarkup([[
|
||||||
|
InlineKeyboardButton("Откликнуться", url=link),
|
||||||
|
]]),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def prompt(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
async def prompt(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
@ -92,6 +120,7 @@ async def handle_document(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|||||||
|
|
||||||
application = ApplicationBuilder().token(os.environ["BOT_TOKEN"]).concurrent_updates(True).build()
|
application = ApplicationBuilder().token(os.environ["BOT_TOKEN"]).concurrent_updates(True).build()
|
||||||
application.add_handler(CommandHandler('start', start, block=False))
|
application.add_handler(CommandHandler('start', start, block=False))
|
||||||
|
application.add_handler(MessageHandler(filters.Text("Получить следующую вакансию"), next_vacancy, block=False))
|
||||||
application.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), prompt, block=False))
|
application.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), prompt, block=False))
|
||||||
application.add_handler(MessageHandler((filters.Document.ALL | filters.PHOTO) & (~filters.COMMAND), handle_document, block=False))
|
application.add_handler(MessageHandler((filters.Document.ALL | filters.PHOTO) & (~filters.COMMAND), handle_document, block=False))
|
||||||
application.add_error_handler(error_handler)
|
application.add_error_handler(error_handler)
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from django.core.management import BaseCommand
|
from django.core.management import BaseCommand
|
||||||
from vacancies.main.vector_store import search_similarities
|
from vacancies.main.models import CustomerCV
|
||||||
from vacancies.main.models import CustomerCV, RecommendedVacancy
|
|
||||||
from vacancies.main.bot import application
|
from vacancies.main.bot import application
|
||||||
|
from vacancies.main.vector_store import get_next_vacancy
|
||||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
|
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
|
||||||
from qdrant_client.models import Filter, HasIdCondition
|
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
@ -15,24 +14,12 @@ class Command(BaseCommand):
|
|||||||
asyncio.run(self.ahandle(*args, **options))
|
asyncio.run(self.ahandle(*args, **options))
|
||||||
|
|
||||||
async def ahandle(self, *args, **options):
|
async def ahandle(self, *args, **options):
|
||||||
customer_cvs = CustomerCV.objects.all()
|
for customer_cv in CustomerCV.objects.all():
|
||||||
|
result = get_next_vacancy(customer_cv)
|
||||||
for customer_cv in customer_cvs:
|
|
||||||
recommended_vacancy_ids = RecommendedVacancy.objects.filter(
|
|
||||||
customer=customer_cv.customer,
|
|
||||||
).values_list('vacancy_id', flat=True)
|
|
||||||
|
|
||||||
query_filter = Filter(must_not=[HasIdCondition(has_id=recommended_vacancy_ids)])
|
|
||||||
result = search_similarities(query_filter, customer_cv.id)
|
|
||||||
if not result:
|
if not result:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
search_result_id, vacancy_content, link = result
|
recommendation, vacancy_content, link = result
|
||||||
|
|
||||||
recommendation = RecommendedVacancy.objects.create(
|
|
||||||
customer=customer_cv.customer,
|
|
||||||
vacancy_id=search_result_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
await application.bot.send_message(
|
await application.bot.send_message(
|
||||||
chat_id=recommendation.customer.chat_id,
|
chat_id=recommendation.customer.chat_id,
|
||||||
|
|||||||
@ -5,6 +5,8 @@ from qdrant_client import QdrantClient
|
|||||||
from qdrant_client.models import Filter
|
from qdrant_client.models import Filter
|
||||||
from vacancies.main.models import VacancyFeatures
|
from vacancies.main.models import VacancyFeatures
|
||||||
from vacancies.conf.settings import QDRANT_URL
|
from vacancies.conf.settings import QDRANT_URL
|
||||||
|
from vacancies.main.models import CustomerCV, RecommendedVacancy
|
||||||
|
from qdrant_client.models import Filter, HasIdCondition
|
||||||
|
|
||||||
qdrant_client = QdrantClient(url=QDRANT_URL)
|
qdrant_client = QdrantClient(url=QDRANT_URL)
|
||||||
|
|
||||||
@ -184,3 +186,23 @@ def extract_features(content: str) -> VacancyFeatures:
|
|||||||
structured_llm = openai_client.with_structured_output(VacancyFeatures)
|
structured_llm = openai_client.with_structured_output(VacancyFeatures)
|
||||||
response = structured_llm.invoke(prompt)
|
response = structured_llm.invoke(prompt)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def get_next_vacancy(customer_cv):
|
||||||
|
recommended_vacancy_ids = RecommendedVacancy.objects.filter(
|
||||||
|
customer=customer_cv.customer,
|
||||||
|
).values_list('vacancy_id', flat=True)
|
||||||
|
|
||||||
|
query_filter = Filter(must_not=[HasIdCondition(has_id=recommended_vacancy_ids)])
|
||||||
|
result = search_similarities(query_filter, customer_cv.id)
|
||||||
|
if not result:
|
||||||
|
return None
|
||||||
|
|
||||||
|
search_result_id, vacancy_content, link = result
|
||||||
|
|
||||||
|
recommendation = RecommendedVacancy.objects.create(
|
||||||
|
customer=customer_cv.customer,
|
||||||
|
vacancy_id=search_result_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
return recommendation, vacancy_content, link
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user