diff --git a/main.py b/main.py index b5de6d4..3b8ca73 100644 --- a/main.py +++ b/main.py @@ -384,9 +384,11 @@ class TelegramClient: async def send_message(self, chat_id: int, text: str) -> None: if not self.base_url: + log_warn("[notify] TELEGRAM_BOT_TOKEN пустой, отправка пропущена.") return # По настройке можно отключить отправку уведомлений в выходные (МСК). - if msk_now().weekday() >= 5: + if not NOTIFY_ON_WEEKENDS and msk_now().weekday() >= 5: + log_info(f"[notify] Выходной день, отправка пропущена chat_id={chat_id}") return try: async with httpx.AsyncClient(timeout=20) as client: @@ -395,6 +397,7 @@ class TelegramClient: json={"chat_id": chat_id, "text": text}, ) response.raise_for_status() + log_info(f"[notify] Сообщение отправлено chat_id={chat_id}") except Exception as exc: # Не роняем обработку webhook, если Telegram API временно недоступен # или указан неверный токен/чат. @@ -778,6 +781,7 @@ async def handle_pr_opened(payload: dict[str, Any]) -> None: author_login = (pull_request.get("user") or {}).get("login") if not repo_full_name or not pr_number or not author_login: + log_warn("[assign] opened: нет repo/pr/author, событие пропущено.") return if author_login.lower() in AUTO_ASSIGN_EXCLUDED_AUTHORS: log_info( @@ -836,6 +840,10 @@ async def handle_pr_opened(payload: dict[str, Any]) -> None: ) await gitea_client.assign_reviewers(repo_full_name, int(pr_number), selected_logins) await gitea_client.add_label(repo_full_name, int(pr_number), AUTO_ASSIGNED_LABEL) + log_info( + f"[assign] Запрошено назначение в Gitea для {repo_full_name}#{pr_number}: {selected_logins}; " + f"label={AUTO_ASSIGNED_LABEL}" + ) for reviewer in selected_reviewers: storage.add_assignment( repo_full_name=repo_full_name, @@ -847,6 +855,9 @@ async def handle_pr_opened(payload: dict[str, Any]) -> None: reviewer.telegram_chat_id, f"Назначено новое ревью: {repo_full_name}#{pr_number} (автор: {author_login})", ) + log_info( + f"[notify] opened для {repo_full_name}#{pr_number}, получателей={len(selected_reviewers)}" + ) async def handle_pr_closed(payload: dict[str, Any]) -> None: @@ -856,6 +867,7 @@ async def handle_pr_closed(payload: dict[str, Any]) -> None: pr_number = pull_request.get("number") action = payload.get("action") if not repo_full_name or not pr_number: + log_warn("[notify] closed/merged: нет repo/pr, событие пропущено.") return participant_chat_ids = await get_pr_participant_chat_ids( repo_full_name, @@ -868,6 +880,10 @@ async def handle_pr_closed(payload: dict[str, Any]) -> None: status_label = "смержен" if is_merged else "закрыт" title = (pull_request.get("title") or "").strip() or f"#{pr_number}" msg = f"PR {repo_full_name}#{pr_number} {status_label}: {title}" + log_info( + f"[notify] pr_closed для {repo_full_name}#{pr_number}, " + f"status={status_label}, получателей={len(participant_chat_ids)}" + ) for chat_id in participant_chat_ids: await telegram_client.send_message(chat_id, msg) @@ -975,6 +991,7 @@ async def handle_pr_reviewed(payload: dict[str, Any]) -> None: repo_full_name = repository.get("full_name") pr_number = pull_request.get("number") if not repo_full_name or not pr_number: + log_warn("[notify] reviewed: нет repo/pr, событие пропущено.") return state = (review.get("state") or "").lower() reviewer_login = ( @@ -994,6 +1011,10 @@ async def handle_pr_reviewed(payload: dict[str, Any]) -> None: msg = f"PR {repo_full_name}#{pr_number}: ревью {status_text}." author_chat_id = await get_pr_author_chat_id(repo_full_name, int(pr_number), pull_request) if author_chat_id is not None: + log_info( + f"[notify] reviewed для {repo_full_name}#{pr_number}, " + f"state={state or 'unknown'}, reviewer={reviewer_login or '-'}, получателей=1" + ) await telegram_client.send_message(author_chat_id, msg) else: log_warn( @@ -1016,6 +1037,10 @@ async def handle_pr_reviewed(payload: dict[str, Any]) -> None: ) await telegram_client.send_message(author_chat_id, merge_msg) storage.set_kv(merge_ready_key, "1") + log_info( + f"[notify] merge_ready для {repo_full_name}#{pr_number}, " + f"approvals={approvals_count}, threshold={APPROVALS_REQUIRED_FOR_MERGE}" + ) else: if already_notified: storage.delete_kv(merge_ready_key)