Добавить поддержку Яндекс Маркета (goods-feedback API)

- app/services/ym.py: клиент Partner API — getGoodsFeedbacks с пагинацией и
  фильтром по дате, updateGoodsFeedbackComment (ответ), deleteGoodsFeedbackComment
  (удаление), обработка новых отзывов по аналогии с WB/Ozon
- воркер ym_worker, включается при заданных YM_API_KEY и YM_BUSINESS_ID
- кнопки отправки/удаления ответа, платформа в сообщении и в таблице,
  статистика /stat и /allstat
- переменные YM_API_KEY, YM_BUSINESS_ID, YM_CHECK_INTERVAL, PRODUCTS_YM_SHEET_LINK
- README и .env.example

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 20:13:38 +03:00
co-authored by Claude Fable 5.1
parent 1098ff4991
commit 4534ab2683
10 changed files with 481 additions and 24 deletions
+56 -1
View File
@@ -10,7 +10,7 @@ from tortoise.exceptions import DoesNotExist
from app import config
from app.models import Review, Settings
from app.services import GPTClient, OzonClient, WildberriesClient
from app.services import GPTClient, OzonClient, WildberriesClient, YandexMarketClient
logger = logging.getLogger(__name__)
router = Router()
@@ -147,6 +147,33 @@ async def callback_wb_delete(call: CallbackQuery) -> None:
)
@router.callback_query(F.data.startswith("ym_delete:"))
async def callback_ym_delete(call: CallbackQuery) -> None:
comment_id = call.data.split(":", 1)[1]
ym_client = YandexMarketClient()
result = await ym_client.delete_comment(comment_id)
if "error" not in result:
try:
review = await Review.filter(response_id=comment_id, platform="ym").first()
if review:
review.response_text = None
review.response_id = None
review.responded_at = None
await review.save()
except Exception as e:
logger.error(f"Error updating review after comment deletion: {e}")
await call.answer("Комментарий успешно удалён на Яндекс Маркете.")
await call.message.reply("🗑 Ответ успешно удален с Яндекс Маркета")
else:
await call.answer("Не удалось удалить комментарий.")
await call.message.reply(
f"❌ Ошибка удаления комментария: {result.get('error')}"
)
@router.callback_query(F.data.startswith("generate_answer:"))
async def callback_generate_answer(call: CallbackQuery) -> None:
review_id = call.data.split(":", 1)[1]
@@ -344,6 +371,34 @@ async def callback_send_answer(call: CallbackQuery) -> None:
f"❌ Ошибка отправки ответа на Wildberries: {result.get('error')}"
)
elif review.platform == "ym":
ym_client = YandexMarketClient()
result = await ym_client.post_comment(
review.external_id, review.response_text
)
if "comment_id" in result:
review.response_id = result["comment_id"]
await review.save()
markup = InlineKeyboardBuilder()
markup.add(
InlineKeyboardButton(
text="Удалить",
callback_data=f"ym_delete:{result['comment_id']}",
)
)
await call.message.answer(
f"✅ Ответ на #review{review_id} успешно отправлен на Яндекс Маркет",
reply_to_message_id=review.message_id,
reply_markup=markup.as_markup(),
)
else:
await call.message.reply(
f"❌ Ошибка отправки ответа на Яндекс Маркет: {result.get('error')}"
)
await call.answer("Ответ отправлен")
review.responded_at = datetime.now()
await review.save()