From 3fe870024d26e8e2956b34a8550a0e0f7b41124a Mon Sep 17 00:00:00 2001 From: hexdev Date: Fri, 17 Jul 2026 12:21:53 +0700 Subject: [PATCH] feat: ai letter + disabled fl --- .env.example | 5 + app/ai.py | 80 ++ app/config.py | 10 + app/models.py | 29 + app/service.py | 7 +- app/sources/__init__.py | 5 +- app/state.py | 43 + app/telegram.py | 13 +- data/published_offers.json | 1226 +++++++++++++++++++++++++ data/sent_offers.json | 57 +- docker-compose.yml | 9 + main.py | 103 ++- prompts/offer_reply_system_prompt.txt | 47 + 13 files changed, 1610 insertions(+), 24 deletions(-) create mode 100644 app/ai.py create mode 100644 data/published_offers.json create mode 100644 docker-compose.yml create mode 100644 prompts/offer_reply_system_prompt.txt diff --git a/.env.example b/.env.example index 4dc95f7..276b645 100644 --- a/.env.example +++ b/.env.example @@ -9,3 +9,8 @@ KEYWORDS_EXCLUDE=wordpress,figma MIN_PRICE_AMOUNT= REQUESTS_TIMEOUT_SECONDS=20 STATE_FILE=data/sent_offers.json +PUBLISHED_OFFERS_FILE=data/published_offers.json +OPENAI_API_BASE_URL=https://api.openai.com/v1 +OPENAI_API_KEY=your_api_key +OPENAI_MODEL=gpt-4o-mini +OPENAI_SYSTEM_PROMPT_FILE=/app/prompts/offer_reply_system_prompt.txt diff --git a/app/ai.py b/app/ai.py new file mode 100644 index 0000000..1747b0c --- /dev/null +++ b/app/ai.py @@ -0,0 +1,80 @@ +from __future__ import annotations + +import asyncio +from pathlib import Path + +import requests + +from app.models import Offer + + +class OfferReplyGenerator: + def __init__( + self, + api_base_url: str, + api_key: str, + model: str, + system_prompt_file: Path, + timeout_seconds: int, + ) -> None: + self._api_base_url = api_base_url.rstrip("/") + self._api_key = api_key + self._model = model + self._system_prompt = system_prompt_file.read_text(encoding="utf-8").strip() + self._timeout_seconds = timeout_seconds + + async def generate_reply(self, offer: Offer) -> str: + return await asyncio.to_thread(self._generate_reply_sync, offer) + + def _generate_reply_sync(self, offer: Offer) -> str: + response = requests.post( + f"{self._api_base_url}/chat/completions", + headers={ + "Authorization": f"Bearer {self._api_key}", + "Content-Type": "application/json", + }, + json={ + "model": self._model, + "messages": [ + {"role": "system", "content": self._system_prompt}, + {"role": "user", "content": _build_offer_prompt(offer)}, + ], + }, + timeout=self._timeout_seconds, + ) + response.raise_for_status() + payload = response.json() + choices = payload.get("choices") or [] + if not choices: + raise ValueError("OpenAI-compatible API returned no choices") + + message = choices[0].get("message") or {} + content = message.get("content") + if isinstance(content, str) and content.strip(): + return content.strip() + + if isinstance(content, list): + text_parts = [item.get("text", "") for item in content if isinstance(item, dict)] + text = "\n".join(part.strip() for part in text_parts if part and part.strip()).strip() + if text: + return text + + raise ValueError("OpenAI-compatible API returned empty content") + + +def _build_offer_prompt(offer: Offer) -> str: + seller_line = f"Исполнитель: @{offer.seller_username}\n" if offer.seller_username else "" + price_amount_line = f"Числовой бюджет: {offer.price_amount}\n" if offer.price_amount is not None else "" + return ( + f"Подготовь сообщение для отклика на этот оффер.\n" + f"Источник: {offer.source}\n" + f"ID: {offer.external_id}\n" + f"Заголовок: {offer.title}\n" + f"Категория: {offer.category_id}\n" + f"Бюджет: {offer.price}\n" + f"{price_amount_line}" + f"Опубликовано: {offer.published_at}\n" + f"{seller_line}" + f"Описание:\n{offer.description}\n\n" + f"Ссылка: {offer.url}" + ) diff --git a/app/config.py b/app/config.py index a998c9a..f6f1fc2 100644 --- a/app/config.py +++ b/app/config.py @@ -20,6 +20,11 @@ class Settings: min_price_amount: int | None requests_timeout_seconds: int state_file: Path + published_offers_file: Path + openai_api_base_url: str + openai_api_key: str + openai_model: str + openai_system_prompt_file: Path def load_settings() -> Settings: @@ -40,6 +45,11 @@ def load_settings() -> Settings: min_price_amount=_parse_optional_int(os.getenv("MIN_PRICE_AMOUNT", "")), requests_timeout_seconds=int(os.getenv("REQUESTS_TIMEOUT_SECONDS", "20")), state_file=Path(os.getenv("STATE_FILE", "data/sent_offers.json")), + published_offers_file=Path(os.getenv("PUBLISHED_OFFERS_FILE", "data/published_offers.json")), + openai_api_base_url=_require_env("OPENAI_API_BASE_URL"), + openai_api_key=_require_env("OPENAI_API_KEY"), + openai_model=_require_env("OPENAI_MODEL"), + openai_system_prompt_file=Path(_require_env("OPENAI_SYSTEM_PROMPT_FILE")), ) diff --git a/app/models.py b/app/models.py index ae34806..af5cf2f 100644 --- a/app/models.py +++ b/app/models.py @@ -19,3 +19,32 @@ class Offer: @property def dedup_key(self) -> str: return f"{self.source}:{self.external_id}" + + def to_dict(self) -> dict[str, str | int | None]: + return { + "source": self.source, + "external_id": self.external_id, + "title": self.title, + "description": self.description, + "price": self.price, + "price_amount": self.price_amount, + "url": self.url, + "category_id": self.category_id, + "published_at": self.published_at, + "seller_username": self.seller_username, + } + + @classmethod + def from_dict(cls, data: dict[str, str | int | None]) -> "Offer": + return cls( + source=str(data["source"]), + external_id=str(data["external_id"]), + title=str(data["title"]), + description=str(data["description"]), + price=str(data["price"]), + price_amount=int(data["price_amount"]) if data["price_amount"] is not None else None, + url=str(data["url"]), + category_id=int(data["category_id"]), + published_at=str(data["published_at"]), + seller_username=str(data["seller_username"]) if data["seller_username"] is not None else None, + ) diff --git a/app/service.py b/app/service.py index 7dc3df6..51f7f73 100644 --- a/app/service.py +++ b/app/service.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging from app.filters import get_offer_skip_reason -from app.state import SentOffersStore +from app.state import PublishedOffersStore, SentOffersStore from app.telegram import TelegramPublisher from app.sources.base import OfferSource @@ -17,6 +17,7 @@ class OfferProcessingService: sources: list[OfferSource], publisher: TelegramPublisher, sent_offers_store: SentOffersStore, + published_offers_store: PublishedOffersStore, include_keywords: list[str], exclude_keywords: list[str], min_price_amount: int | None, @@ -24,6 +25,7 @@ class OfferProcessingService: self._sources = sources self._publisher = publisher self._sent_offers_store = sent_offers_store + self._published_offers_store = published_offers_store self._include_keywords = include_keywords self._exclude_keywords = exclude_keywords self._min_price_amount = min_price_amount @@ -66,12 +68,13 @@ class OfferProcessingService: continue try: - await self._publisher.publish_offer(offer) + message = await self._publisher.publish_offer(offer) except Exception: logger.exception("Failed to publish offer %s", offer.dedup_key) continue self._sent_offers_store.add(offer.dedup_key) + self._published_offers_store.add(message.chat.id, message.message_id, offer) published_count += 1 logger.info("Published offer %s", offer.dedup_key) diff --git a/app/sources/__init__.py b/app/sources/__init__.py index 9af86cd..b4999af 100644 --- a/app/sources/__init__.py +++ b/app/sources/__init__.py @@ -1,5 +1,6 @@ from app.sources.base import OfferSource -from app.sources.fl import FlSource +# from app.sources.fl import FlSource from app.sources.kwork import KworkSource -__all__ = ["OfferSource", "FlSource", "KworkSource"] +__all__ = ["OfferSource", "KworkSource"] +# __all__ = ["OfferSource", "FlSource", "KworkSource"] diff --git a/app/state.py b/app/state.py index 5578f37..138c401 100644 --- a/app/state.py +++ b/app/state.py @@ -3,6 +3,8 @@ from __future__ import annotations import json from pathlib import Path +from app.models import Offer + class SentOffersStore: def __init__(self, file_path: Path) -> None: @@ -29,3 +31,44 @@ class SentOffersStore: def _persist(self) -> None: with self._file_path.open("w", encoding="utf-8") as file: json.dump(sorted(self._sent_keys), file, ensure_ascii=False, indent=2) + + +class PublishedOffersStore: + def __init__(self, file_path: Path) -> None: + self._file_path = file_path + self._file_path.parent.mkdir(parents=True, exist_ok=True) + self._offers_by_message_key = self._load() + + def add(self, chat_id: int, message_id: int, offer: Offer) -> None: + self._offers_by_message_key[self._message_key(chat_id, message_id)] = offer.to_dict() + self._persist() + + def get(self, chat_id: int, message_id: int) -> Offer | None: + data = self._offers_by_message_key.get(self._message_key(chat_id, message_id)) + if data is None: + return None + return Offer.from_dict(data) + + def remove(self, chat_id: int, message_id: int) -> None: + removed = self._offers_by_message_key.pop(self._message_key(chat_id, message_id), None) + if removed is not None: + self._persist() + + def _load(self) -> dict[str, dict[str, str | int | None]]: + if not self._file_path.exists(): + return {} + + with self._file_path.open("r", encoding="utf-8") as file: + data = json.load(file) + + if not isinstance(data, dict): + return {} + return data + + def _persist(self) -> None: + with self._file_path.open("w", encoding="utf-8") as file: + json.dump(self._offers_by_message_key, file, ensure_ascii=False, indent=2) + + @staticmethod + def _message_key(chat_id: int, message_id: int) -> str: + return f"{chat_id}:{message_id}" diff --git a/app/telegram.py b/app/telegram.py index 536e250..e71be76 100644 --- a/app/telegram.py +++ b/app/telegram.py @@ -1,7 +1,7 @@ from __future__ import annotations from aiogram import Bot -from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup +from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message from app.models import Offer @@ -11,12 +11,12 @@ class TelegramPublisher: self._bot = bot self._channel_id = channel_id - async def publish_offer(self, offer: Offer) -> None: - await self._bot.send_message( + async def publish_offer(self, offer: Offer) -> Message: + return await self._bot.send_message( chat_id=self._channel_id, text=_format_offer_message(offer), disable_web_page_preview=True, - reply_markup=_build_delete_markup(), + reply_markup=_build_offer_markup(), ) @@ -39,9 +39,10 @@ def _format_offer_message(offer: Offer) -> str: ) -def _build_delete_markup() -> InlineKeyboardMarkup: +def _build_offer_markup() -> InlineKeyboardMarkup: return InlineKeyboardMarkup( inline_keyboard=[ - [InlineKeyboardButton(text="❌", callback_data="delete_post")] + [InlineKeyboardButton(text="Принять", callback_data="accept_offer")], + [InlineKeyboardButton(text="❌", callback_data="delete_post")], ] ) diff --git a/data/published_offers.json b/data/published_offers.json new file mode 100644 index 0000000..a01ef53 --- /dev/null +++ b/data/published_offers.json @@ -0,0 +1,1226 @@ +{ + "-1004358794176:214": { + "source": "kwork", + "external_id": "3218756", + "title": "Скрипт для автоперевода страниц сайта через API", + "description": "Нужен скрипт на питоне для перевода страниц сайта. Суть такая: скрипт парсит статические html страницы, вытасквиает весь текст, переводит его через апи яндекса или гугла и сохраняет новые файлы с переводом, сохраняя всю верстку и теги. Готов обсудить детали в переписке, пишите кто делал подобное", + "price": "115000.00 RUB", + "price_amount": 115000, + "url": "https://kwork.ru/projects/3218756/view", + "category_id": 41, + "published_at": "17 июля", + "seller_username": "sapostes" + }, + "-1004358794176:215": { + "source": "kwork", + "external_id": "3218440", + "title": "Создание и разработка telegram bot", + "description": "Мне нужно создать телеграмм бота, который будет использоваться для продажи ускорителя интернета, основную базу я дам. ", + "price": "4000.00 RUB", + "price_amount": 4000, + "url": "https://kwork.ru/projects/3218440/view", + "category_id": 41, + "published_at": "16 июля", + "seller_username": "rostikponomarev299" + }, + "-1004358794176:216": { + "source": "kwork", + "external_id": "3218180", + "title": "Бот парсер", + "description": "Требуется бот парсер с каналов тг и сайтов на различные темы (ЗОЖ, Рэп, налоги, крипта)\r\nЕсть бот в тг - далее выбираем кластер (привязанную Гугл таблицу с каналами, топ и стоп словами) - далее кидаем туда ссылку на тг канал или сайт - далее...\r\nТз пропишу в личку", + "price": "8000.00 RUB", + "price_amount": 8000, + "url": "https://kwork.ru/projects/3218180/view", + "category_id": 41, + "published_at": "16 июля", + "seller_username": "guschinak96" + }, + "-1004358794176:217": { + "source": "kwork", + "external_id": "3218016", + "title": "Настроить связку amoCRM + Telegram + Google Sheets", + "description": "Нужно автоматизировать воронку продаж. При смене статуса в amoCRM скрипт должен дергать данные из Google Таблиц, генерировать персональный PDF-документ и отправлять его клиенту в Telegram-бота.\r\nМожно реализовать через n8n, Make или написать кастомный скрипт на Python. Жду от вас краткого описания, как бы вы реализовали эту логику.", + "price": "75000.00 RUB", + "price_amount": 75000, + "url": "https://kwork.ru/projects/3218016/view", + "category_id": 41, + "published_at": "16 июля", + "seller_username": "cjeyevmisha" + }, + "-1004358794176:218": { + "source": "kwork", + "external_id": "3218028", + "title": "Игровой бот", + "description": "Старый бот был написан криво, постоянно падал от спама команд и ложился из-за блокировок базы.\r\nФункционал нового бота:\r\nСистема уровней (начисление XP за осмысленные сообщения, алгоритм анти-флуда).\r\nЭкономика: внутренняя виртуальная валюта, которую можно фармить и передавать другим юзерам.\r\nМагазин ролей и инвентарь (покупка кастомных плашек рядом с ником).\r\nКлановая система (создание кланов, рейтинг по XP клана).\r\nБазовая модерация (удаление ссылок от новичков, мут за мат).", + "price": "65000.00 RUB", + "price_amount": 65000, + "url": "https://kwork.ru/projects/3218028/view", + "category_id": 41, + "published_at": "16 июля", + "seller_username": "cjeyevmisha" + }, + "-1004358794176:219": { + "source": "fl", + "external_id": "5514112", + "title": "Нужно сделать кнопку \"ПОБЕДА\" (Бюджет: 45 000 ₽)", + "description": "Нужно сделать кнопку \"ПОБЕДА\", которая нажимается сама, но только если пользователь ни разу не моргнул за сессию (определяем по веб-камере)\n— Подключение к камере через...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514112/nujno-sdelat-knopku-pobeda.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 16:49:20 GMT", + "seller_username": null + }, + "-1004358794176:220": { + "source": "fl", + "external_id": "5514096", + "title": "Скачать Мод на Криминальную Россию, и редактор для карты", + "description": "У меня уже есть готовый сервер на open.mp. Нужно, чтобы на этом сервере отображалась карта \"Криминальная Россия\" и был встроен редактор карт Texture Studio, чтобы я мог...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514096/skachat-mod-na-kriminalnuyu-rossiyu-i-redaktor-dlya-kartyi.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 15:22:22 GMT", + "seller_username": null + }, + "-1004358794176:221": { + "source": "fl", + "external_id": "5514093", + "title": "Разработка криптовалютного DCA-бота с подключением опционной страховки", + "description": "Необходимо разработать собственного торгового бота для криптовалютных бирж.\n\nОсновная задача — создать отдельную программную инфраструктуру, которая сможет подключаться через...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514093/razrabotka-kriptovalyutnogo-dca-bota-s-podklyucheniem-optsionnoy-strahovki.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 15:11:41 GMT", + "seller_username": null + }, + "-1004358794176:222": { + "source": "fl", + "external_id": "5514084", + "title": "Реализовать ботов", + "description": "ТЗ (Сориентируйте пожалуйста по цене каждого такого бота)\n\n1. Телеграм бот авто рассылки по риелторским чатам + группам соц.сети пользователь регистрируеться оплачивает...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514084/realizovat-botov.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 14:24:25 GMT", + "seller_username": null + }, + "-1004358794176:223": { + "source": "fl", + "external_id": "5514041", + "title": "Переход с 1с на другую 1с", + "description": "нужно сделать переход из 1сКа с кучей кастомных решений ред 1.1 в 1с Унф ред 3.0\nнужно дать оценку в часах\nстоимость часа\nпри разработке надо давать оценку, с учетом...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514041/perehod-s-1s-na-druguyu-1s.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 10:41:32 GMT", + "seller_username": null + }, + "-1004358794176:224": { + "source": "fl", + "external_id": "5514025", + "title": "1С разработчик. Проект: Разработка программы лояльности", + "description": "Интеграция программы лояльности с 1С", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514025/1s-razrabotchik-proekt-razrabotka-programmyi-loyalnosti-.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 09:08:41 GMT", + "seller_username": null + }, + "-1004358794176:225": { + "source": "fl", + "external_id": "5514018", + "title": "Готовый проект КРМП по готовым исходникам с ГитХаба.", + "description": "Требуется разработчик для создания готового RP-проекта (аналог Малиновки) с картой \"Криминальная Россия\" (Арзамас, Южный, посёлки, дороги). В проекте должны быть реализованы...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514018/gotovyiy-proekt-krmp-po-gotovyim-ishodnikam-s-githaba-.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 08:35:32 GMT", + "seller_username": null + }, + "-1004358794176:226": { + "source": "fl", + "external_id": "5514016", + "title": "ML-специалист для прогнозирования футбольных матчей (лайв-статистика + коэффициенты)", + "description": "Есть данные:\n\nминимум 10 000 футбольных матчей в JSON.\n\nСтатистика по таймам (весь матч, 1-й тайм, 2-й тайм): удары, владение, xG, пасы, угловые, фолы и т.д. — около 20+...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514016/ml-spetsialist-dlya-prognozirovaniya-futbolnyih-matchey-layv-statistika--koeffitsientyi.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 08:35:14 GMT", + "seller_username": null + }, + "-1004358794176:227": { + "source": "fl", + "external_id": "5514010", + "title": "DevOps-инженер для аудита и настройки сервера", + "description": "Ищем опытного DevOps-инженера для разовой задачи.\n\nЧто нужно сделать:\n\n– провести аудит текущего сервера и инфраструктуры;\n– найти слабые места и возможные проблемы с...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514010/devops-injener-dlya-audita-i-nastroyki-servera.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 08:10:57 GMT", + "seller_username": null + }, + "-1004358794176:228": { + "source": "fl", + "external_id": "5513981", + "title": "Создать бота для раздачи ключей + админ панель", + "description": "Разработать Telegram-бота, который автоматически выдает ключи (доступы) пользователям после успешной оплаты.\nБот должен иметь закрытую админ-панель (внутри Telegram или...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513981/sozdat-bota-dlya-razdachi-klyuchey--admin-panel.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 05:23:25 GMT", + "seller_username": null + }, + "-1004358794176:229": { + "source": "fl", + "external_id": "5513973", + "title": "Требуется аудита SaaS-проекта от Senior Node.js / PostgreSQL разработчика", + "description": "Ищу опытного Senior Backend Engineer для технического аудита работающего SaaS-проекта.\n\nПроект уже работает в production. Первая версия была разработана с активным...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513973/trebuetsya-audita-saas-proekta-ot-senior-nodejs---postgresql-razrabotchika.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 05:20:09 GMT", + "seller_username": null + }, + "-1004358794176:230": { + "source": "fl", + "external_id": "5513964", + "title": "Создать прототип JARVIS на пк", + "description": "ТЕХНИЧЕСКОЕ ЗАДАНИЕ (ТЗ) НА РАЗРАБОТКУ ГОЛОСОВОГО ПОМОЩНИКА «ДЖАРВИС»\n1. ЦЕЛЬ ПРОЕКТА\nРазработать десктопное приложение (голосовой помощник «Джарвис») для Windows 10/11....", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513964/sozdat-prototip-jarvis-na-pk.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 05:18:50 GMT", + "seller_username": null + }, + "-1004358794176:231": { + "source": "fl", + "external_id": "5513913", + "title": "Помочь настроить сервер для простейших текстовых ботов", + "description": "Есть боты Телеграмм и Макс. Они находятся в папках, как текстовые документы в блокноте. Делались с Python. Для их работы нужен постоянный включённый ПК, но такой возможности...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513913/pomoch-nastroit-server-dlya-prosteyshih-tekstovyih-botov.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 13:35:08 GMT", + "seller_username": null + }, + "-1004358794176:232": { + "source": "fl", + "external_id": "5513897", + "title": "Миграция крупного портала на актуальное ядро Symfony + Programmatic SEO", + "description": "Требуется опытный бэкенд-разработчик / архитектор (Symfony, PHP) для переработки действующего контентного проекта. Основная задача - миграция существующей кодовой базы...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513897/migratsiya-krupnogo-portala-na-aktualnoe-yadro-symfony--programmatic-seo.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 12:28:17 GMT", + "seller_username": null + }, + "-1004358794176:233": { + "source": "fl", + "external_id": "5513894", + "title": "системный интегратор CRM (KeyCRM / SalesDrive) — сквозные процессы (продажи, логистика, закупки", + "description": "системный интегратор CRM (KeyCRM / SalesDrive) — сквозные процессы (продажи, логистика, закупки, фи\n1. О проекте и бизнес-контексте\nМы — компания с небольшим, но активным...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513894/sistemnyiy-integrator-crm-keycrm---salesdrive--skvoznyie-protsessyi-prodaji-logistika-zakupki.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 12:03:32 GMT", + "seller_username": null + }, + "-1004358794176:234": { + "source": "kwork", + "external_id": "3218763", + "title": "Сделать телеграм бота для опросов и статистики", + "description": "Нужно сделать телеграм бота на питоне, чтоб опрашивал сотрудников по графику и собирал статистику. Сами вопросы и варианты ответов я скину в экселе, их надо будет в базу залить. Главное чтоб ответы автоматом улетали в гугл таблицу и рисовались простые отчеты раз в неделю. Пишите, все детали обсудим, готов пообщаться", + "price": "140000.00 RUB", + "price_amount": 140000, + "url": "https://kwork.ru/projects/3218763/view", + "category_id": 41, + "published_at": "17 июля", + "seller_username": "dolphibweb3" + }, + "-1004358794176:235": { + "source": "fl", + "external_id": "5513872", + "title": "Информационная система “Электронный журнал” (Бюджет: 500 000 ₽)", + "description": "Доработка информационной системы “Электронный журнал” 44 ФЗ", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513872/informatsionnaya-sistema-elektronnyiy-jurnal.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 10:22:07 GMT", + "seller_username": null + }, + "-1004358794176:236": { + "source": "fl", + "external_id": "5513871", + "title": "1С задача", + "description": "По аудиту: независимый технический разбор инцидента при автоматической загрузке прайса поставщика [название] в 1С [конфигурация, релиз, платформа 8.3.x].\nКонтекст:\n•...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513871/1s-zadacha.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 10:21:33 GMT", + "seller_username": null + }, + "-1004358794176:237": { + "source": "fl", + "external_id": "5513842", + "title": "Подключение весов штрих-PC200 и розница 2.3", + "description": "Подключение весов штрих-PC200 и розница 2.3\nТз следующее. Нужно настроить обмен между весами и розницей. могу скинуть базу, вы проверите у себя, назовёте цену. Я передам...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513842/podklyuchenie-vesov-shtrih-pc200-i-roznitsa-23.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 07:18:51 GMT", + "seller_username": null + }, + "-1004358794176:238": { + "source": "fl", + "external_id": "5513833", + "title": "1C УПП Инвентаризация товара", + "description": "Требуется в 1С УПП в документе Инвентаризация товара при заполнение поля документа по кнопке Заполнить по остаткам на складе рег.учет (или сделать доп меню кнопки) цена должна...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513833/1c-upp-inventarizatsiya-tovara.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 06:24:51 GMT", + "seller_username": null + }, + "-1004358794176:239": { + "source": "fl", + "external_id": "5513823", + "title": "Нужна помощь OSINT-специалиста или аналитика по поиску местоположения.", + "description": "Суть задачи: Имеется серия фотографий, сделанных в Калужской области в период с апреля по июнь 2026 года. На фото запечатлен человек, а также интерьеры и экстерьеры учреждения...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513823/nujna-pomosch-osint-spetsialista-ili-analitika-po-poisku-mestopolojeniya.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 05:24:03 GMT", + "seller_username": null + }, + "-1004358794176:240": { + "source": "fl", + "external_id": "5513784", + "title": "Настроить сервер и базу данных для Python‑бота: Ubuntu, PostgreSQL+pgvector, Redis, Docker", + "description": "Развернуть VPS на Ubuntu 22.04 (2 vCPU, 4 ГБ RAM, 30 ГБ SSD).\nУстановить PostgreSQL 15+ и включить расширение pgvector.\nУстановить Redis 7+.\nУстановить Docker и Docker...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513784/nastroit-server-i-bazu-dannyih-dlya-pythonbota-ubuntu-postgresqlpgvector-redis-docker.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 05:17:40 GMT", + "seller_username": null + }, + "-1004358794176:241": { + "source": "fl", + "external_id": "5513763", + "title": "Нужно сделать иконки для блока премущества", + "description": "Нужно сделать иконки для блока премущества, сайт скину", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513763/nujno-sdelat-ikonki-dlya-bloka-premuschestva.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 15:12:27 GMT", + "seller_username": null + }, + "-1004358794176:242": { + "source": "fl", + "external_id": "5513743", + "title": "Внедрить мастер-прайс 1С и настроить 1С срочно", + "description": "По аудиту: независимый технический разбор инцидента при автоматической загрузке прайса поставщика [название] в 1С [конфигурация, релиз, платформа 8.3.x].\nКонтекст:\n•...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513743/vnedrit-master-prays-1s-i-nastroit-1s--srochno.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 13:53:47 GMT", + "seller_username": null + }, + "-1004358794176:243": { + "source": "fl", + "external_id": "5513738", + "title": "нужен верстальщик", + "description": "на сайте настроена интеграция с амо срм через апи. После изменения пароля в аккаунте амосрм - перестали попадать заказы в СРМ с сайта. Нужно помочь возобновить интеграцию.", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513738/nujen-verstalschik.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 13:36:05 GMT", + "seller_username": null + }, + "-1004358794176:244": { + "source": "fl", + "external_id": "5513732", + "title": "Добавить элементы для сайта на Opencart - изображение в меню и ссылку на товар в вариациях", + "description": "Добавить элементы для сайта на Opencart - изображение в меню и ссылку на товар в вариациях\n\nИнтернет-магазин Opencart Version 3.0.3.2 (trs-3)\n\n1. Для добавления изображения...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513732/dobavit-elementyi-dlya-sayta-na-opencart---izobrajenie-v-menyu-i-ssyilku-na-tovar-v-variatsiyah.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 13:15:54 GMT", + "seller_username": null + }, + "-1004358794176:245": { + "source": "fl", + "external_id": "5513716", + "title": "Организовать обзвон роботом по клиентской базе", + "description": "На ваших ресурсах настроить возможность звонков автоинформатора по предложенной базе.", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513716/organizovat-obzvon-robotom-po-klientskoy-baze.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 12:16:18 GMT", + "seller_username": null + }, + "-1004358794176:246": { + "source": "fl", + "external_id": "5513694", + "title": "Развернуть Битрикс24 коробку", + "description": "Нужно с нуля поднять битркис24 коробку, мы сами интеграторы Б24 но ранее только работали с облаком. Поэтому нужно настроить все что нужно под капотом коробке, что бы мы уже как...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513694/razvernut-bitriks24-korobku.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 10:46:54 GMT", + "seller_username": null + }, + "-1004358794176:247": { + "source": "fl", + "external_id": "5513681", + "title": "Задачи по доработкам Битрикс Аспро корп 3.0 (Бюджет: 15 000 ₽)", + "description": "Добрый день.\nОсновная задача - четко знать и разбираться в Битриксе и в шаблонах Аспро, чтобы не сломать и не тратить лишнее время на копания в архитектуре. \nЕсть тех задание,...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513681/zadachi-po-dorabotkam-bitriks-aspro-korp-30.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 10:18:56 GMT", + "seller_username": null + }, + "-1004358794176:248": { + "source": "fl", + "external_id": "5513674", + "title": "Разработка защищённого корпоративного мессенджера", + "description": "Основные возможности:\nличные и групповые чаты по клиентам, вакансиям и направлениям;\nотправка сообщений, резюме, документов, изображений и голосовых сообщений;\nсоздание...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513674/razrabotka-zaschischnnogo-korporativnogo-messendjera.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 09:45:01 GMT", + "seller_username": null + }, + "-1004358794176:249": { + "source": "fl", + "external_id": "5513659", + "title": "Специалист по React\\React native", + "description": "Необходимо доработать веб платформу и мобильное приложение на React\\React native.\nНужен хороший специалист на два и более проекта.\nВ основном исправления и корректировки исходя...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513659/spetsialist-po-reactreact-native.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 08:33:49 GMT", + "seller_username": null + }, + "-1004358794176:250": { + "source": "fl", + "external_id": "5513646", + "title": "Настройка стандартного обмена 1С:УНФ ↔ Битрикс24", + "description": "Требуется настроить типовой двусторонний обмен между 1С:УНФ (ред. 3.0 проф) и Битрикс24 средствами штатного модуля «Коннектор 1С» \nОбъекты обмена в рамках штатной...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513646/nastroyka-standartnogo-obmena-1sunf--bitriks24.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 07:24:50 GMT", + "seller_username": null + }, + "-1004358794176:251": { + "source": "fl", + "external_id": "5513636", + "title": "Доработка web приложения", + "description": "Требуется добавить в web приложение довольно большую новую функцию.\nИмеющееся приложение (далее \"инфозона\") представляет собой информационную зону для сенсорных экранов в...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513636/dorabotka-web-prilojeniya.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 06:19:57 GMT", + "seller_username": null + }, + "-1004358794176:252": { + "source": "fl", + "external_id": "5513591", + "title": "Веб-приложение: генерация Word-документов, распознавание сканов (OCR), импорт выписки в Google Sheet", + "description": "Нужно веб-приложение для небольшой команды (2–5 человек). Доступ из браузера с ПК (Windows/Mac) и телефона, вход по логину/паролю, роли администратор/сотрудник. Хостинг — VPS в...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513591/veb-prilojenie-generatsiya-word-dokumentov-raspoznavanie-skanov-ocr-import-vyipiski-v-google-sheet.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 15:46:50 GMT", + "seller_username": null + }, + "-1004358794176:253": { + "source": "fl", + "external_id": "5513582", + "title": "Интересует создание PBN и восстановление дропов", + "description": "создание PBN и восстановление дропов\n\n1) Есть перехваченные дропы на gname/godaddy хотелось бы восстановить их на WP c подключением по MCP к Claude для наполнения/обновления...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513582/interesuet-sozdanie-pbn-i-vosstanovlenie-dropov.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 14:32:30 GMT", + "seller_username": null + }, + "-1004358794176:254": { + "source": "fl", + "external_id": "5513570", + "title": "Ищем Python/OpenCV-разработчика для системы web видеоуправления играми на Unity.", + "description": "Необходимо создать модуль, который через обычную USB-веб-камеру распознает цветные маркеры в руках пользователей, определяет их координаты и передает данные в Unity в реальном...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513570/ischem-python-opencv-razrabotchika-dlya-sistemyi-web-videoupravleniya-igrami-na-unity.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 13:46:10 GMT", + "seller_username": null + }, + "-1004358794176:255": { + "source": "kwork", + "external_id": "3218781", + "title": "Скрипт на питоне для распознавания договоров", + "description": "Нужно сделать скрипт на питоне, которыый будет разбирать входящие сканы и пдф догворов и вытаскивать оттуда ключевые данные. Надо распознавать дату, номер, сумму, реквизиты сторон и предмет договора\r\nДля распознавания текста думали использовать что-то готовое типа tesseract или готовое апи от яндекса, а потом скармливать это чатгпт через апишку, чтобы он структурировал данные в json. Либо предложите свой вариант, как это лучше реализовать, чтоб работало без косяков\r\nНа выходе должен получаться готовый джейсон файл по шаблону. Все исходники доков для тестов я скину", + "price": "15000.00 RUB", + "price_amount": 15000, + "url": "https://kwork.ru/projects/3218781/view", + "category_id": 41, + "published_at": "17 июля", + "seller_username": "msccrew" + }, + "-1004358794176:256": { + "source": "fl", + "external_id": "5513551", + "title": "Скорректировать настройки сервера под управлением Ubuntu 24.04 для сайта на 1С Битрикс", + "description": "Добрый день!\n\nСайт под управление 1С-Битрикс был перенесен с обычного хостинга в Рег.ру на VPS под управлением Ubuntu 24.04. Настройку сервера и перенос осуществляли поддержка...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513551/skorrektirovat-nastroyki-servera-pod-upravleniem-ubuntu-2404-dlya-sayta-na-1s-bitriks.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 11:42:38 GMT", + "seller_username": null + }, + "-1004358794176:257": { + "source": "fl", + "external_id": "5513539", + "title": "Доработка мобильных приложений, сайтов", + "description": "Нужна доработка мобильных приложений, сайтов и др. Пишите сразу в личку обсудим подробности", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513539/dorabotka-mobilnyih-prilojeniy-saytov-.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 10:50:35 GMT", + "seller_username": null + }, + "-1004358794176:258": { + "source": "fl", + "external_id": "5513486", + "title": "Обечение сети YOLO для решения капчи", + "description": "Работал раньше код решения капчи, капчи поменялись, надо натренировать новую модель для yolo.\nПримеры капч по ссылке https://disk.yandex.ru/d/WwBZtZYMs-WXvA\nКод который работал...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513486/obechenie-seti-yolo-dlya-resheniya-kapchi.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 07:11:27 GMT", + "seller_username": null + }, + "-1004358794176:259": { + "source": "fl", + "external_id": "5513401", + "title": "Программист PHP/Python на постоянку: поддержка и развитие обменника", + "description": "Ищем программиста на постоянную основу для поддержки и развития уже работающего обменника валют/криптовалют.\n\nПроект действующий, большая часть функционала уже реализована....", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513401/programmist-php-python-na-postoyanku-podderjka-i-razvitie-obmennika.html", + "category_id": 5, + "published_at": "Sun, 12 Jul 2026 11:35:19 GMT", + "seller_username": null + }, + "-1004358794176:260": { + "source": "fl", + "external_id": "5513372", + "title": "Разработка Chrome-расширений", + "description": "Нужно разработать MVP Chrome-расширения под Manifest V3.\nМожно откликаться на одно из трёх направлений или предложить реализацию нескольких.\n\nОбщие требования:\n- Chrome...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513372/razrabotka-chrome-rasshireniy.html", + "category_id": 5, + "published_at": "Sun, 12 Jul 2026 06:27:26 GMT", + "seller_username": null + }, + "-1004358794176:261": { + "source": "fl", + "external_id": "5513258", + "title": "вывести Hello world через калькулятор с помощью кодов (для всех)", + "description": "ввывести код надо пж пж", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513258/vyivesti-hello-world-cherez-kalkulyator-s-pomoschyu-kodov.html", + "category_id": 5, + "published_at": "Sun, 12 Jul 2026 06:27:19 GMT", + "seller_username": null + }, + "-1004358794176:262": { + "source": "fl", + "external_id": "5513369", + "title": "сделать робота для покупок товара на бирже Санкт Петербургской", + "description": "нужен тот кто уже делал то кого робота там алгоритмы меняются", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513369/sdelat-robota-dlya-pokupok-tovara-na-birje-sankt-peterburgskoy.html", + "category_id": 5, + "published_at": "Sun, 12 Jul 2026 06:02:50 GMT", + "seller_username": null + }, + "-1004358794176:263": { + "source": "kwork", + "external_id": "3218781", + "title": "Скрипт на питоне для распознавания договоров", + "description": "Нужно сделать скрипт на питоне, которыый будет разбирать входящие сканы и пдф догворов и вытаскивать оттуда ключевые данные. Надо распознавать дату, номер, сумму, реквизиты сторон и предмет договора\r\nДля распознавания текста думали использовать что-то готовое типа tesseract или готовое апи от яндекса, а потом скармливать это чатгпт через апишку, чтобы он структурировал данные в json. Либо предложите свой вариант, как это лучше реализовать, чтоб работало без косяков\r\nНа выходе должен получаться готовый джейсон файл по шаблону. Все исходники доков для тестов я скину", + "price": "15000.00 RUB", + "price_amount": 15000, + "url": "https://kwork.ru/projects/3218781/view", + "category_id": 41, + "published_at": "17 июля", + "seller_username": "msccrew" + }, + "-1004358794176:265": { + "source": "kwork", + "external_id": "3218756", + "title": "Скрипт для автоперевода страниц сайта через API", + "description": "Нужен скрипт на питоне для перевода страниц сайта. Суть такая: скрипт парсит статические html страницы, вытасквиает весь текст, переводит его через апи яндекса или гугла и сохраняет новые файлы с переводом, сохраняя всю верстку и теги. Готов обсудить детали в переписке, пишите кто делал подобное", + "price": "115000.00 RUB", + "price_amount": 115000, + "url": "https://kwork.ru/projects/3218756/view", + "category_id": 41, + "published_at": "17 июля", + "seller_username": "sapostes" + }, + "-1004358794176:266": { + "source": "kwork", + "external_id": "3218440", + "title": "Создание и разработка telegram bot", + "description": "Мне нужно создать телеграмм бота, который будет использоваться для продажи ускорителя интернета, основную базу я дам. ", + "price": "4000.00 RUB", + "price_amount": 4000, + "url": "https://kwork.ru/projects/3218440/view", + "category_id": 41, + "published_at": "16 июля", + "seller_username": "rostikponomarev299" + }, + "-1004358794176:267": { + "source": "kwork", + "external_id": "3218180", + "title": "Бот парсер", + "description": "Требуется бот парсер с каналов тг и сайтов на различные темы (ЗОЖ, Рэп, налоги, крипта)\r\nЕсть бот в тг - далее выбираем кластер (привязанную Гугл таблицу с каналами, топ и стоп словами) - далее кидаем туда ссылку на тг канал или сайт - далее...\r\nТз пропишу в личку", + "price": "8000.00 RUB", + "price_amount": 8000, + "url": "https://kwork.ru/projects/3218180/view", + "category_id": 41, + "published_at": "16 июля", + "seller_username": "guschinak96" + }, + "-1004358794176:268": { + "source": "kwork", + "external_id": "3218016", + "title": "Настроить связку amoCRM + Telegram + Google Sheets", + "description": "Нужно автоматизировать воронку продаж. При смене статуса в amoCRM скрипт должен дергать данные из Google Таблиц, генерировать персональный PDF-документ и отправлять его клиенту в Telegram-бота.\r\nМожно реализовать через n8n, Make или написать кастомный скрипт на Python. Жду от вас краткого описания, как бы вы реализовали эту логику.", + "price": "75000.00 RUB", + "price_amount": 75000, + "url": "https://kwork.ru/projects/3218016/view", + "category_id": 41, + "published_at": "16 июля", + "seller_username": "cjeyevmisha" + }, + "-1004358794176:269": { + "source": "kwork", + "external_id": "3218028", + "title": "Игровой бот", + "description": "Старый бот был написан криво, постоянно падал от спама команд и ложился из-за блокировок базы.\r\nФункционал нового бота:\r\nСистема уровней (начисление XP за осмысленные сообщения, алгоритм анти-флуда).\r\nЭкономика: внутренняя виртуальная валюта, которую можно фармить и передавать другим юзерам.\r\nМагазин ролей и инвентарь (покупка кастомных плашек рядом с ником).\r\nКлановая система (создание кланов, рейтинг по XP клана).\r\nБазовая модерация (удаление ссылок от новичков, мут за мат).", + "price": "65000.00 RUB", + "price_amount": 65000, + "url": "https://kwork.ru/projects/3218028/view", + "category_id": 41, + "published_at": "16 июля", + "seller_username": "cjeyevmisha" + }, + "-1004358794176:270": { + "source": "fl", + "external_id": "5514112", + "title": "Нужно сделать кнопку \"ПОБЕДА\" (Бюджет: 45 000 ₽)", + "description": "Нужно сделать кнопку \"ПОБЕДА\", которая нажимается сама, но только если пользователь ни разу не моргнул за сессию (определяем по веб-камере)\n— Подключение к камере через...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514112/nujno-sdelat-knopku-pobeda.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 16:49:20 GMT", + "seller_username": null + }, + "-1004358794176:271": { + "source": "fl", + "external_id": "5514096", + "title": "Скачать Мод на Криминальную Россию, и редактор для карты", + "description": "У меня уже есть готовый сервер на open.mp. Нужно, чтобы на этом сервере отображалась карта \"Криминальная Россия\" и был встроен редактор карт Texture Studio, чтобы я мог...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514096/skachat-mod-na-kriminalnuyu-rossiyu-i-redaktor-dlya-kartyi.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 15:22:22 GMT", + "seller_username": null + }, + "-1004358794176:272": { + "source": "fl", + "external_id": "5514093", + "title": "Разработка криптовалютного DCA-бота с подключением опционной страховки", + "description": "Необходимо разработать собственного торгового бота для криптовалютных бирж.\n\nОсновная задача — создать отдельную программную инфраструктуру, которая сможет подключаться через...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514093/razrabotka-kriptovalyutnogo-dca-bota-s-podklyucheniem-optsionnoy-strahovki.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 15:11:41 GMT", + "seller_username": null + }, + "-1004358794176:273": { + "source": "fl", + "external_id": "5514084", + "title": "Реализовать ботов", + "description": "ТЗ (Сориентируйте пожалуйста по цене каждого такого бота)\n\n1. Телеграм бот авто рассылки по риелторским чатам + группам соц.сети пользователь регистрируеться оплачивает...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514084/realizovat-botov.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 14:24:25 GMT", + "seller_username": null + }, + "-1004358794176:274": { + "source": "fl", + "external_id": "5514041", + "title": "Переход с 1с на другую 1с", + "description": "нужно сделать переход из 1сКа с кучей кастомных решений ред 1.1 в 1с Унф ред 3.0\nнужно дать оценку в часах\nстоимость часа\nпри разработке надо давать оценку, с учетом...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514041/perehod-s-1s-na-druguyu-1s.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 10:41:32 GMT", + "seller_username": null + }, + "-1004358794176:275": { + "source": "fl", + "external_id": "5514025", + "title": "1С разработчик. Проект: Разработка программы лояльности", + "description": "Интеграция программы лояльности с 1С", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514025/1s-razrabotchik-proekt-razrabotka-programmyi-loyalnosti-.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 09:08:41 GMT", + "seller_username": null + }, + "-1004358794176:276": { + "source": "fl", + "external_id": "5514018", + "title": "Готовый проект КРМП по готовым исходникам с ГитХаба.", + "description": "Требуется разработчик для создания готового RP-проекта (аналог Малиновки) с картой \"Криминальная Россия\" (Арзамас, Южный, посёлки, дороги). В проекте должны быть реализованы...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514018/gotovyiy-proekt-krmp-po-gotovyim-ishodnikam-s-githaba-.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 08:35:32 GMT", + "seller_username": null + }, + "-1004358794176:277": { + "source": "fl", + "external_id": "5514016", + "title": "ML-специалист для прогнозирования футбольных матчей (лайв-статистика + коэффициенты)", + "description": "Есть данные:\n\nминимум 10 000 футбольных матчей в JSON.\n\nСтатистика по таймам (весь матч, 1-й тайм, 2-й тайм): удары, владение, xG, пасы, угловые, фолы и т.д. — около 20+...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514016/ml-spetsialist-dlya-prognozirovaniya-futbolnyih-matchey-layv-statistika--koeffitsientyi.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 08:35:14 GMT", + "seller_username": null + }, + "-1004358794176:278": { + "source": "fl", + "external_id": "5514010", + "title": "DevOps-инженер для аудита и настройки сервера", + "description": "Ищем опытного DevOps-инженера для разовой задачи.\n\nЧто нужно сделать:\n\n– провести аудит текущего сервера и инфраструктуры;\n– найти слабые места и возможные проблемы с...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514010/devops-injener-dlya-audita-i-nastroyki-servera.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 08:10:57 GMT", + "seller_username": null + }, + "-1004358794176:279": { + "source": "fl", + "external_id": "5513981", + "title": "Создать бота для раздачи ключей + админ панель", + "description": "Разработать Telegram-бота, который автоматически выдает ключи (доступы) пользователям после успешной оплаты.\nБот должен иметь закрытую админ-панель (внутри Telegram или...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513981/sozdat-bota-dlya-razdachi-klyuchey--admin-panel.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 05:23:25 GMT", + "seller_username": null + }, + "-1004358794176:280": { + "source": "fl", + "external_id": "5513973", + "title": "Требуется аудита SaaS-проекта от Senior Node.js / PostgreSQL разработчика", + "description": "Ищу опытного Senior Backend Engineer для технического аудита работающего SaaS-проекта.\n\nПроект уже работает в production. Первая версия была разработана с активным...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513973/trebuetsya-audita-saas-proekta-ot-senior-nodejs---postgresql-razrabotchika.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 05:20:09 GMT", + "seller_username": null + }, + "-1004358794176:281": { + "source": "fl", + "external_id": "5513964", + "title": "Создать прототип JARVIS на пк", + "description": "ТЕХНИЧЕСКОЕ ЗАДАНИЕ (ТЗ) НА РАЗРАБОТКУ ГОЛОСОВОГО ПОМОЩНИКА «ДЖАРВИС»\n1. ЦЕЛЬ ПРОЕКТА\nРазработать десктопное приложение (голосовой помощник «Джарвис») для Windows 10/11....", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513964/sozdat-prototip-jarvis-na-pk.html", + "category_id": 5, + "published_at": "Thu, 16 Jul 2026 05:18:50 GMT", + "seller_username": null + }, + "-1004358794176:282": { + "source": "fl", + "external_id": "5513913", + "title": "Помочь настроить сервер для простейших текстовых ботов", + "description": "Есть боты Телеграмм и Макс. Они находятся в папках, как текстовые документы в блокноте. Делались с Python. Для их работы нужен постоянный включённый ПК, но такой возможности...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513913/pomoch-nastroit-server-dlya-prosteyshih-tekstovyih-botov.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 13:35:08 GMT", + "seller_username": null + }, + "-1004358794176:283": { + "source": "fl", + "external_id": "5513897", + "title": "Миграция крупного портала на актуальное ядро Symfony + Programmatic SEO", + "description": "Требуется опытный бэкенд-разработчик / архитектор (Symfony, PHP) для переработки действующего контентного проекта. Основная задача - миграция существующей кодовой базы...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513897/migratsiya-krupnogo-portala-na-aktualnoe-yadro-symfony--programmatic-seo.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 12:28:17 GMT", + "seller_username": null + }, + "-1004358794176:284": { + "source": "kwork", + "external_id": "3218812", + "title": "Скрипт автопостинга из телеграм в вк и дзен", + "description": "Надо написать скрипт на питоне для автопостинга. Смысл таой: бот берет посты из определенного канала в телеге и перекидывает их в группу в вк и на канал в дзене. Нужно чтобы переносились текст и картинки. Бывают посты с несколькими фотками, их тоже надо нормально пачками переносить. Скрипт должен работать по крону или просто крутиться на сервере постоянно. Апи для вк и дзена я уже зарегистрировал, токенами поделюсь. Настройки каналов можно сделать в обычном файлике конфига или прямо в коде. Рассмотрю разные варианты выполнения", + "price": "130000.00 RUB", + "price_amount": 130000, + "url": "https://kwork.ru/projects/3218812/view", + "category_id": 41, + "published_at": "17 июля", + "seller_username": "msccrew" + }, + "-1004358794176:285": { + "source": "fl", + "external_id": "5513894", + "title": "системный интегратор CRM (KeyCRM / SalesDrive) — сквозные процессы (продажи, логистика, закупки", + "description": "системный интегратор CRM (KeyCRM / SalesDrive) — сквозные процессы (продажи, логистика, закупки, фи\n1. О проекте и бизнес-контексте\nМы — компания с небольшим, но активным...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513894/sistemnyiy-integrator-crm-keycrm---salesdrive--skvoznyie-protsessyi-prodaji-logistika-zakupki.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 12:03:32 GMT", + "seller_username": null + }, + "-1004358794176:286": { + "source": "fl", + "external_id": "5513872", + "title": "Информационная система “Электронный журнал” (Бюджет: 500 000 ₽)", + "description": "Доработка информационной системы “Электронный журнал” 44 ФЗ", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513872/informatsionnaya-sistema-elektronnyiy-jurnal.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 10:22:07 GMT", + "seller_username": null + }, + "-1004358794176:287": { + "source": "fl", + "external_id": "5513871", + "title": "1С задача", + "description": "По аудиту: независимый технический разбор инцидента при автоматической загрузке прайса поставщика [название] в 1С [конфигурация, релиз, платформа 8.3.x].\nКонтекст:\n•...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513871/1s-zadacha.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 10:21:33 GMT", + "seller_username": null + }, + "-1004358794176:288": { + "source": "fl", + "external_id": "5513842", + "title": "Подключение весов штрих-PC200 и розница 2.3", + "description": "Подключение весов штрих-PC200 и розница 2.3\nТз следующее. Нужно настроить обмен между весами и розницей. могу скинуть базу, вы проверите у себя, назовёте цену. Я передам...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513842/podklyuchenie-vesov-shtrih-pc200-i-roznitsa-23.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 07:18:51 GMT", + "seller_username": null + }, + "-1004358794176:289": { + "source": "fl", + "external_id": "5513833", + "title": "1C УПП Инвентаризация товара", + "description": "Требуется в 1С УПП в документе Инвентаризация товара при заполнение поля документа по кнопке Заполнить по остаткам на складе рег.учет (или сделать доп меню кнопки) цена должна...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513833/1c-upp-inventarizatsiya-tovara.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 06:24:51 GMT", + "seller_username": null + }, + "-1004358794176:290": { + "source": "fl", + "external_id": "5513823", + "title": "Нужна помощь OSINT-специалиста или аналитика по поиску местоположения.", + "description": "Суть задачи: Имеется серия фотографий, сделанных в Калужской области в период с апреля по июнь 2026 года. На фото запечатлен человек, а также интерьеры и экстерьеры учреждения...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513823/nujna-pomosch-osint-spetsialista-ili-analitika-po-poisku-mestopolojeniya.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 05:24:03 GMT", + "seller_username": null + }, + "-1004358794176:291": { + "source": "fl", + "external_id": "5513784", + "title": "Настроить сервер и базу данных для Python‑бота: Ubuntu, PostgreSQL+pgvector, Redis, Docker", + "description": "Развернуть VPS на Ubuntu 22.04 (2 vCPU, 4 ГБ RAM, 30 ГБ SSD).\nУстановить PostgreSQL 15+ и включить расширение pgvector.\nУстановить Redis 7+.\nУстановить Docker и Docker...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513784/nastroit-server-i-bazu-dannyih-dlya-pythonbota-ubuntu-postgresqlpgvector-redis-docker.html", + "category_id": 5, + "published_at": "Wed, 15 Jul 2026 05:17:40 GMT", + "seller_username": null + }, + "-1004358794176:292": { + "source": "fl", + "external_id": "5513763", + "title": "Нужно сделать иконки для блока премущества", + "description": "Нужно сделать иконки для блока премущества, сайт скину", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513763/nujno-sdelat-ikonki-dlya-bloka-premuschestva.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 15:12:27 GMT", + "seller_username": null + }, + "-1004358794176:293": { + "source": "fl", + "external_id": "5513743", + "title": "Внедрить мастер-прайс 1С и настроить 1С срочно", + "description": "По аудиту: независимый технический разбор инцидента при автоматической загрузке прайса поставщика [название] в 1С [конфигурация, релиз, платформа 8.3.x].\nКонтекст:\n•...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513743/vnedrit-master-prays-1s-i-nastroit-1s--srochno.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 13:53:47 GMT", + "seller_username": null + }, + "-1004358794176:294": { + "source": "fl", + "external_id": "5513738", + "title": "нужен верстальщик", + "description": "на сайте настроена интеграция с амо срм через апи. После изменения пароля в аккаунте амосрм - перестали попадать заказы в СРМ с сайта. Нужно помочь возобновить интеграцию.", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513738/nujen-verstalschik.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 13:36:05 GMT", + "seller_username": null + }, + "-1004358794176:295": { + "source": "fl", + "external_id": "5513732", + "title": "Добавить элементы для сайта на Opencart - изображение в меню и ссылку на товар в вариациях", + "description": "Добавить элементы для сайта на Opencart - изображение в меню и ссылку на товар в вариациях\n\nИнтернет-магазин Opencart Version 3.0.3.2 (trs-3)\n\n1. Для добавления изображения...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513732/dobavit-elementyi-dlya-sayta-na-opencart---izobrajenie-v-menyu-i-ssyilku-na-tovar-v-variatsiyah.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 13:15:54 GMT", + "seller_username": null + }, + "-1004358794176:296": { + "source": "fl", + "external_id": "5513716", + "title": "Организовать обзвон роботом по клиентской базе", + "description": "На ваших ресурсах настроить возможность звонков автоинформатора по предложенной базе.", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513716/organizovat-obzvon-robotom-po-klientskoy-baze.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 12:16:18 GMT", + "seller_username": null + }, + "-1004358794176:297": { + "source": "fl", + "external_id": "5513694", + "title": "Развернуть Битрикс24 коробку", + "description": "Нужно с нуля поднять битркис24 коробку, мы сами интеграторы Б24 но ранее только работали с облаком. Поэтому нужно настроить все что нужно под капотом коробке, что бы мы уже как...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513694/razvernut-bitriks24-korobku.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 10:46:54 GMT", + "seller_username": null + }, + "-1004358794176:298": { + "source": "fl", + "external_id": "5513681", + "title": "Задачи по доработкам Битрикс Аспро корп 3.0 (Бюджет: 15 000 ₽)", + "description": "Добрый день.\nОсновная задача - четко знать и разбираться в Битриксе и в шаблонах Аспро, чтобы не сломать и не тратить лишнее время на копания в архитектуре. \nЕсть тех задание,...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513681/zadachi-po-dorabotkam-bitriks-aspro-korp-30.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 10:18:56 GMT", + "seller_username": null + }, + "-1004358794176:299": { + "source": "fl", + "external_id": "5513674", + "title": "Разработка защищённого корпоративного мессенджера", + "description": "Основные возможности:\nличные и групповые чаты по клиентам, вакансиям и направлениям;\nотправка сообщений, резюме, документов, изображений и голосовых сообщений;\nсоздание...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513674/razrabotka-zaschischnnogo-korporativnogo-messendjera.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 09:45:01 GMT", + "seller_username": null + }, + "-1004358794176:300": { + "source": "fl", + "external_id": "5513659", + "title": "Специалист по React\\React native", + "description": "Необходимо доработать веб платформу и мобильное приложение на React\\React native.\nНужен хороший специалист на два и более проекта.\nВ основном исправления и корректировки исходя...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513659/spetsialist-po-reactreact-native.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 08:33:49 GMT", + "seller_username": null + }, + "-1004358794176:301": { + "source": "fl", + "external_id": "5513646", + "title": "Настройка стандартного обмена 1С:УНФ ↔ Битрикс24", + "description": "Требуется настроить типовой двусторонний обмен между 1С:УНФ (ред. 3.0 проф) и Битрикс24 средствами штатного модуля «Коннектор 1С» \nОбъекты обмена в рамках штатной...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513646/nastroyka-standartnogo-obmena-1sunf--bitriks24.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 07:24:50 GMT", + "seller_username": null + }, + "-1004358794176:302": { + "source": "fl", + "external_id": "5513636", + "title": "Доработка web приложения", + "description": "Требуется добавить в web приложение довольно большую новую функцию.\nИмеющееся приложение (далее \"инфозона\") представляет собой информационную зону для сенсорных экранов в...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513636/dorabotka-web-prilojeniya.html", + "category_id": 5, + "published_at": "Tue, 14 Jul 2026 06:19:57 GMT", + "seller_username": null + }, + "-1004358794176:303": { + "source": "fl", + "external_id": "5513591", + "title": "Веб-приложение: генерация Word-документов, распознавание сканов (OCR), импорт выписки в Google Sheet", + "description": "Нужно веб-приложение для небольшой команды (2–5 человек). Доступ из браузера с ПК (Windows/Mac) и телефона, вход по логину/паролю, роли администратор/сотрудник. Хостинг — VPS в...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513591/veb-prilojenie-generatsiya-word-dokumentov-raspoznavanie-skanov-ocr-import-vyipiski-v-google-sheet.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 15:46:50 GMT", + "seller_username": null + }, + "-1004358794176:304": { + "source": "fl", + "external_id": "5513582", + "title": "Интересует создание PBN и восстановление дропов", + "description": "создание PBN и восстановление дропов\n\n1) Есть перехваченные дропы на gname/godaddy хотелось бы восстановить их на WP c подключением по MCP к Claude для наполнения/обновления...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513582/interesuet-sozdanie-pbn-i-vosstanovlenie-dropov.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 14:32:30 GMT", + "seller_username": null + }, + "-1004358794176:305": { + "source": "fl", + "external_id": "5513570", + "title": "Ищем Python/OpenCV-разработчика для системы web видеоуправления играми на Unity.", + "description": "Необходимо создать модуль, который через обычную USB-веб-камеру распознает цветные маркеры в руках пользователей, определяет их координаты и передает данные в Unity в реальном...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513570/ischem-python-opencv-razrabotchika-dlya-sistemyi-web-videoupravleniya-igrami-na-unity.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 13:46:10 GMT", + "seller_username": null + }, + "-1004358794176:306": { + "source": "fl", + "external_id": "5513551", + "title": "Скорректировать настройки сервера под управлением Ubuntu 24.04 для сайта на 1С Битрикс", + "description": "Добрый день!\n\nСайт под управление 1С-Битрикс был перенесен с обычного хостинга в Рег.ру на VPS под управлением Ubuntu 24.04. Настройку сервера и перенос осуществляли поддержка...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513551/skorrektirovat-nastroyki-servera-pod-upravleniem-ubuntu-2404-dlya-sayta-na-1s-bitriks.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 11:42:38 GMT", + "seller_username": null + }, + "-1004358794176:307": { + "source": "fl", + "external_id": "5513539", + "title": "Доработка мобильных приложений, сайтов", + "description": "Нужна доработка мобильных приложений, сайтов и др. Пишите сразу в личку обсудим подробности", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513539/dorabotka-mobilnyih-prilojeniy-saytov-.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 10:50:35 GMT", + "seller_username": null + }, + "-1004358794176:308": { + "source": "fl", + "external_id": "5513486", + "title": "Обечение сети YOLO для решения капчи", + "description": "Работал раньше код решения капчи, капчи поменялись, надо натренировать новую модель для yolo.\nПримеры капч по ссылке https://disk.yandex.ru/d/WwBZtZYMs-WXvA\nКод который работал...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513486/obechenie-seti-yolo-dlya-resheniya-kapchi.html", + "category_id": 5, + "published_at": "Mon, 13 Jul 2026 07:11:27 GMT", + "seller_username": null + }, + "-1004358794176:309": { + "source": "fl", + "external_id": "5513401", + "title": "Программист PHP/Python на постоянку: поддержка и развитие обменника", + "description": "Ищем программиста на постоянную основу для поддержки и развития уже работающего обменника валют/криптовалют.\n\nПроект действующий, большая часть функционала уже реализована....", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513401/programmist-php-python-na-postoyanku-podderjka-i-razvitie-obmennika.html", + "category_id": 5, + "published_at": "Sun, 12 Jul 2026 11:35:19 GMT", + "seller_username": null + }, + "-1004358794176:310": { + "source": "fl", + "external_id": "5513372", + "title": "Разработка Chrome-расширений", + "description": "Нужно разработать MVP Chrome-расширения под Manifest V3.\nМожно откликаться на одно из трёх направлений или предложить реализацию нескольких.\n\nОбщие требования:\n- Chrome...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513372/razrabotka-chrome-rasshireniy.html", + "category_id": 5, + "published_at": "Sun, 12 Jul 2026 06:27:26 GMT", + "seller_username": null + }, + "-1004358794176:311": { + "source": "fl", + "external_id": "5513258", + "title": "вывести Hello world через калькулятор с помощью кодов (для всех)", + "description": "ввывести код надо пж пж", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513258/vyivesti-hello-world-cherez-kalkulyator-s-pomoschyu-kodov.html", + "category_id": 5, + "published_at": "Sun, 12 Jul 2026 06:27:19 GMT", + "seller_username": null + }, + "-1004358794176:312": { + "source": "fl", + "external_id": "5513369", + "title": "сделать робота для покупок товара на бирже Санкт Петербургской", + "description": "нужен тот кто уже делал то кого робота там алгоритмы меняются", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513369/sdelat-robota-dlya-pokupok-tovara-na-birje-sankt-peterburgskoy.html", + "category_id": 5, + "published_at": "Sun, 12 Jul 2026 06:02:50 GMT", + "seller_username": null + }, + "-1004358794176:313": { + "source": "fl", + "external_id": "5513359", + "title": "Доработка бота: защита от повторной выдачи товара по одному заказу (Бюджет: 2 000 ₽)", + "description": "Есть бот для  funpay для продажи игр Стим, который автоматически выдает цифровой товар после оплаты заказа.\n\nСейчас существует проблема: если покупатель открывает арбитраж,...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5513359/dorabotka-bota-zaschita-ot-povtornoy-vyidachi-tovara-po-odnomu-zakazu.html", + "category_id": 5, + "published_at": "Sun, 12 Jul 2026 01:58:10 GMT", + "seller_username": null + }, + "-1004358794176:314": { + "source": "kwork", + "external_id": "3218824", + "title": "Написать скрипт для автоперевода страниц сайта", + "description": "нужен скрипт на питоне для автоперевода файлов сайта. У меня есть выгрузка страниц в html формате, надо чтобы скрипт брал этот html, находил там текст, переводил его через api deepl или яндекс переводчик и вставлял обратно. Главне чтобы веерстка и все теги оставались на мете, переводить нужно только сам текст. Языки перевода английский и испанский. Настройки апи ключа и языков вынести в отдельный конфиг файл. Желательно сделать обработку ошибок чтобы если апи отвалится, скрипт не падал а продолжал со следующего файла. Жду ваших предложений, рассмотрю всех", + "price": "80000.00 RUB", + "price_amount": 80000, + "url": "https://kwork.ru/projects/3218824/view", + "category_id": 41, + "published_at": "17 июля", + "seller_username": "dopasstaw" + }, + "-1004358794176:315": { + "source": "fl", + "external_id": "5514122", + "title": "финансовый дашборд для селлера", + "description": "Нужно разработать кастомный инструмент который будет работать с сразу с API трех маркетплейсов: Ozon, WB и ЯМ.\n\nВижу так: впс+админка+подключенные мои апишки.\n-KPI-карточки:...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514122/finansovyiy-dashbord-dlya-sellera.html", + "category_id": 5, + "published_at": "Fri, 17 Jul 2026 05:16:02 GMT", + "seller_username": null + }, + "-1004358794176:316": { + "source": "fl", + "external_id": "5514130", + "title": "DevOps: продакшн-развёртывание бэкенда (FastAPI + PostgreSQL/PostGIS)", + "description": "DevOps: продакшн-развёртывание бэкенда (FastAPI + PostgreSQL/PostGIS)\nИщем DevOps-инженера для вывода в production бэкенда мобильного приложения (REST API).\nСтек:\n- Python...", + "price": "Не указан", + "price_amount": null, + "url": "https://www.fl.ru/projects/5514130/devops-prodakshn-razvrtyivanie-bekenda-fastapi--postgresql-postgis.html", + "category_id": 5, + "published_at": "Fri, 17 Jul 2026 05:15:36 GMT", + "seller_username": null + } +} \ No newline at end of file diff --git a/data/sent_offers.json b/data/sent_offers.json index 0967ef4..9838994 100644 --- a/data/sent_offers.json +++ b/data/sent_offers.json @@ -1 +1,56 @@ -{} +[ + "fl:5513258", + "fl:5513359", + "fl:5513369", + "fl:5513372", + "fl:5513401", + "fl:5513486", + "fl:5513539", + "fl:5513551", + "fl:5513570", + "fl:5513582", + "fl:5513591", + "fl:5513636", + "fl:5513646", + "fl:5513659", + "fl:5513674", + "fl:5513681", + "fl:5513694", + "fl:5513716", + "fl:5513732", + "fl:5513738", + "fl:5513743", + "fl:5513763", + "fl:5513784", + "fl:5513823", + "fl:5513833", + "fl:5513842", + "fl:5513871", + "fl:5513872", + "fl:5513894", + "fl:5513897", + "fl:5513913", + "fl:5513964", + "fl:5513973", + "fl:5513981", + "fl:5514010", + "fl:5514016", + "fl:5514018", + "fl:5514025", + "fl:5514041", + "fl:5514084", + "fl:5514093", + "fl:5514096", + "fl:5514112", + "fl:5514122", + "fl:5514130", + "kwork:3218016", + "kwork:3218028", + "kwork:3218180", + "kwork:3218440", + "kwork:3218756", + "kwork:3218763", + "kwork:3218781", + "kwork:3218812", + "kwork:3218824" +] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7060331 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +services: + parser: + build: . + container_name: my-parser + restart: unless-stopped + env_file: .env + volumes: + - ./data:/app/data + - ./prompts:/app/prompts:ro diff --git a/main.py b/main.py index 4122420..7fcb071 100644 --- a/main.py +++ b/main.py @@ -4,14 +4,16 @@ import asyncio import logging from aiogram import Bot, Dispatcher, Router -from aiogram.types import CallbackQuery +from aiogram.types import CallbackQuery, Message from aiogram.client.session.aiohttp import AiohttpSession from apscheduler.schedulers.asyncio import AsyncIOScheduler +from app.ai import OfferReplyGenerator from app.config import load_settings from app.service import OfferProcessingService -from app.sources import FlSource, KworkSource -from app.state import SentOffersStore +from app.sources import KworkSource +# from app.sources import FlSource +from app.state import PublishedOffersStore, SentOffersStore from app.telegram import TelegramPublisher @@ -22,10 +24,75 @@ logging.basicConfig( logger = logging.getLogger(__name__) +def _build_direct_message_text(message: Message, offer_url: str, reply_text: str) -> str: + message_link = _build_message_link(message) + if message_link: + return f"Пост: {message_link}\nОффер: {offer_url}\n\n{reply_text}" + return f"Оффер: {offer_url}\n\n{reply_text}" -def build_dispatcher() -> Dispatcher: + +def _build_message_link(message: Message) -> str | None: + if message.chat.username: + return f"https://t.me/{message.chat.username}/{message.message_id}" + + chat_id = str(message.chat.id) + if not chat_id.startswith("-100"): + return None + + internal_chat_id = chat_id[4:] + if not internal_chat_id: + return None + + return f"https://t.me/c/{internal_chat_id}/{message.message_id}" + + +def build_dispatcher( + reply_generator: OfferReplyGenerator, + published_offers_store: PublishedOffersStore, +) -> Dispatcher: router = Router() + @router.callback_query(lambda callback: callback.data == "accept_offer") + async def accept_offer_callback(callback: CallbackQuery, bot: Bot) -> None: + if callback.message is None: + await callback.answer() + return + + offer = published_offers_store.get(callback.message.chat.id, callback.message.message_id) + if offer is None: + await callback.answer("Не удалось найти оффер", show_alert=True) + return + + await callback.answer("Готовлю сообщение") + + try: + reply_text = await reply_generator.generate_reply(offer) + await bot.send_message( + chat_id=callback.from_user.id, + text=_build_direct_message_text(callback.message, offer.url, reply_text), + disable_web_page_preview=True, + ) + logger.info( + "Generated DM for user_id=%s from chat_id=%s message_id=%s", + callback.from_user.id, + callback.message.chat.id, + callback.message.message_id, + ) + except Exception: + logger.exception( + "Failed to generate or send DM for user_id=%s chat_id=%s message_id=%s", + callback.from_user.id, + callback.message.chat.id, + callback.message.message_id, + ) + try: + await bot.send_message( + chat_id=callback.from_user.id, + text="Не удалось подготовить сообщение. Убедитесь, что вы начали диалог с ботом, и попробуйте снова.", + ) + except Exception: + logger.exception("Failed to send fallback DM to user_id=%s", callback.from_user.id) + @router.callback_query(lambda callback: callback.data == "delete_post") async def delete_post_callback(callback: CallbackQuery) -> None: if callback.message is None: @@ -34,6 +101,7 @@ def build_dispatcher() -> Dispatcher: try: await callback.message.delete() + published_offers_store.remove(callback.message.chat.id, callback.message.message_id) logger.info( "Deleted Telegram message chat_id=%s message_id=%s by user_id=%s", callback.message.chat.id, @@ -56,12 +124,20 @@ def build_dispatcher() -> Dispatcher: async def main() -> None: settings = load_settings() - dispatcher = build_dispatcher() session = AiohttpSession(proxy=settings.telegram_proxy_url) if settings.telegram_proxy_url else None bot = Bot(token=settings.telegram_bot_token, session=session) publisher = TelegramPublisher(bot=bot, channel_id=settings.telegram_channel_id) store = SentOffersStore(settings.state_file) + published_offers_store = PublishedOffersStore(settings.published_offers_file) + reply_generator = OfferReplyGenerator( + api_base_url=settings.openai_api_base_url, + api_key=settings.openai_api_key, + model=settings.openai_model, + system_prompt_file=settings.openai_system_prompt_file, + timeout_seconds=settings.requests_timeout_seconds, + ) + dispatcher = build_dispatcher(reply_generator, published_offers_store) sources = [ KworkSource( @@ -69,18 +145,19 @@ async def main() -> None: timeout_seconds=settings.requests_timeout_seconds, ) ] - if settings.fl_rss_url: - sources.append( - FlSource( - rss_url=settings.fl_rss_url, - timeout_seconds=settings.requests_timeout_seconds, - ) - ) + # if settings.fl_rss_url: + # sources.append( + # FlSource( + # rss_url=settings.fl_rss_url, + # timeout_seconds=settings.requests_timeout_seconds, + # ) + # ) service = OfferProcessingService( sources=sources, publisher=publisher, sent_offers_store=store, + published_offers_store=published_offers_store, include_keywords=settings.keywords_include, exclude_keywords=settings.keywords_exclude, min_price_amount=settings.min_price_amount, @@ -100,4 +177,4 @@ async def main() -> None: if __name__ == "__main__": - asyncio.run(main()) + asyncio.run(main()) \ No newline at end of file diff --git a/prompts/offer_reply_system_prompt.txt b/prompts/offer_reply_system_prompt.txt new file mode 100644 index 0000000..9860c68 --- /dev/null +++ b/prompts/offer_reply_system_prompt.txt @@ -0,0 +1,47 @@ +## Роль и личность +Ты -- помощник фрилансера, отвечающий за бюрократическую работу +Твоя миссия: помогать обрабатывать заявки и офферы + +## Ключевые принципы +1. В ответ ты указываешь **ТОЛЬКО** текст. Никакой markdown разметки, чистый текст. +2. Говори ВСЕГДА от первого лица. Ты и есть фрилансер, и от твоих слов зависит то, возьмут ли его на этот оффер. +3. Структурируем каждый ответ. +4. Мы не бегаем за заказчиками. Ты уверен в себе и своих возможностях, спокоен. +5. Ответ не более 2000 символов. Минимум 150. +6. Ты **НЕ ДАЁШЬ** сторонних контактов -- это против правил площадки. +7. Не используй стандартные клише вроде "не только, но и". + +## Структура +Твой отклик должен следовать структуре: + +1. Быстрый старт. +Начинаем сразу с сути -- кто мы такие, почему наша кандидатура, опыт и прочее. Максимум 1-2 предложения чтобы зацепить глаз и уверить в том, что мы -- подходящий компетентный кандидат. + +2. Основная часть. +Наша задача -- ответить на главную боль заказчика. Подмечай в оффере слабости и безжалостно проходись по ним. +Плохая база от прошлого заказа? Перепроектируем с фокусом на долгосрочное использование. +Список до 6 пунктов по тому, какой стек будем использовать + +3. Заключение +Важно сделать call to action -- `готов обсудить детали`, уточни какую-то важную мысль. Максимум 3 предложения. + +## Данные о назначеном фрилансере. + +Тебе предоставлена карточка работника. +``` +**Специализация:** Backend / DevOps Engineer (Python) + +**Формат работы:** Удаленно (Фриланс / Part-time) + +**Контакты:** https://t.me/agonyecho | https://hexdev.lol | agonyecho@proton.me + +## Профессиональный профиль + +Backend-разработчик со специализацией на Python-автоматизации, веб-парсинге и управлении инфраструктурой. Имею глубокий практический опыт работы с Linux-системами (Arch Linux как основная ОС) и контейнеризацией (Docker/Compose). Сфокусирован на создании отказоустойчивой серверной логики, проектировании баз данных и развертывании приложений в production-ready окружении. Достигаю высокой автономности в работе — от написания кода до его деплоя на VPS. + +## Технический стек +- Языки программирования: Python (requests, BeautifulSoup4, lxml, aiogram, pytest, sqlalchemy orm) +- Инфраструктура и DevOps: Docker, Docker Compose, Linux CLI/Bash, Caddy, Nginx (reverse proxy, SSL) +- Базы данных: PostgreSQL (проектирование схем, базовый CRUD, оптимизация) +- Инструменты контроля: Git, Gitea +```