Add a Blogger delivery channel with one-time OAuth setup

BloggerDeliverer posts each briefing (markdown -> HTML, H1 becomes the
post title with the report headline) via the Blogger API v3 using a
long-lived refresh token; `us2kr blogger-auth` runs the loopback OAuth
flow once and prints the BLOGGER_* lines for .env. Enabled only when
all four BLOGGER_* settings are present.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jsahn
2026-09-01 12:04:49 +09:00
co-authored by Claude Fable 5
parent fecc767a5c
commit 12d7b47f46
8 changed files with 521 additions and 4 deletions
+21 -3
View File
@@ -1,4 +1,4 @@
"""Delivery channels: local file archive (always) + Telegram (when configured)."""
"""Delivery channels: local file archive (always) + Telegram / Blogger (when configured)."""
from __future__ import annotations
@@ -6,19 +6,37 @@ import logging
from us2kr.config import Settings
from us2kr.deliver.base import Deliverer, DeliveryError
from us2kr.deliver.blogger import BloggerDeliverer
from us2kr.deliver.file import FileDeliverer
from us2kr.deliver.telegram import TelegramDeliverer
log = logging.getLogger(__name__)
__all__ = ["Deliverer", "DeliveryError", "FileDeliverer", "TelegramDeliverer", "build_deliverers"]
__all__ = [
"BloggerDeliverer",
"Deliverer",
"DeliveryError",
"FileDeliverer",
"TelegramDeliverer",
"build_deliverers",
]
def build_deliverers(settings: Settings) -> list[Deliverer]:
"""FileDeliverer always; TelegramDeliverer when both token and chat id are configured."""
"""FileDeliverer always; Telegram / Blogger when fully configured."""
deliverers: list[Deliverer] = [FileDeliverer(settings.reports_dir)]
if settings.telegram_enabled:
assert settings.telegram_bot_token and settings.telegram_chat_id # guaranteed by telegram_enabled
deliverers.append(TelegramDeliverer(settings.telegram_bot_token, settings.telegram_chat_id))
if settings.blogger_enabled:
deliverers.append(
BloggerDeliverer(
settings.blogger_client_id or "",
settings.blogger_client_secret or "",
settings.blogger_refresh_token or "",
settings.blogger_blog_id or "",
labels=settings.blogger_labels,
)
)
log.info("deliverers: %s", ", ".join(d.name for d in deliverers))
return deliverers