diff --git a/gimme_job/runtime/notifier.py b/gimme_job/runtime/notifier.py
index 5cfccdf..6ae83c3 100644
--- a/gimme_job/runtime/notifier.py
+++ b/gimme_job/runtime/notifier.py
@@ -29,13 +29,12 @@ def build_listing_messages(postings: list["JobPosting"]) -> list[str]:
current = header
for site_id, site_postings in sorted(by_site.items()):
- site_block = f"\n── {site_id.upper()} ({len(site_postings)}) ──\n"
+ site_header = f"\n── {site_id.upper()} ({len(site_postings)}) ──\n"
+
for p in site_postings:
- # Title line
title = _escape_html(p.title)
line = f"• {title}"
- # Details line
details = []
if p.company:
details.append(_escape_html(p.company))
@@ -46,18 +45,24 @@ def build_listing_messages(postings: list["JobPosting"]) -> list[str]:
if details:
line += f"\n {' | '.join(details)}"
- # Link
if p.job_url:
- line += f'\n 링크'
+ safe_url = p.job_url.replace("&", "&")
+ line += f'\n 링크'
+
+ line += "\n"
- site_block += line + "\n"
+ # Add site header before the first card of each site
+ prefix = site_header if site_header else ""
+ candidate = current + prefix + line
+
+ if len(candidate) > _TELEGRAM_MAX_LEN:
+ # Flush current chunk and start new one
+ chunks.append(current.rstrip())
+ current = prefix + line
+ else:
+ current = candidate
- # Flush chunk if adding this site would exceed limit
- if len(current) + len(site_block) > _TELEGRAM_MAX_LEN:
- chunks.append(current.rstrip())
- current = site_block
- else:
- current += site_block
+ site_header = "" # Only prepend once per site
if current.strip():
chunks.append(current.rstrip())
diff --git a/gimme_job/runtime/orchestrator.py b/gimme_job/runtime/orchestrator.py
index c8a0f27..0dbc9c1 100644
--- a/gimme_job/runtime/orchestrator.py
+++ b/gimme_job/runtime/orchestrator.py
@@ -319,31 +319,26 @@ class RunOrchestrator:
def _summarize_and_notify(self, summary: RunSummary, run_date: date) -> None:
try:
from gimme_job.db.engine import db_session
- from gimme_job.db.repo import JobPostingRepo, SummaryRepo
+ from gimme_job.db.repo import JobPostingRepo
+ from gimme_job.runtime.notifier import NotificationDispatcher, build_listing_messages
+ from gimme_job.runtime.telegram import TelegramClient
with db_session() as session:
postings = JobPostingRepo().get_today_new(session, run_date)
+ if not postings:
+ return
+ chunks = build_listing_messages(postings)
- if not postings:
- return
-
- from gimme_job.runtime.summarizer import OllamaSummarizer
- summarizer = OllamaSummarizer(
- base_url=self.cfg.summarization.ollama_base_url,
- model=self.cfg.summarization.model,
- temperature=self.cfg.summarization.temperature,
- )
- text = summarizer.summarize(postings)
- summary.summary_text = text
-
- with db_session() as session:
- SummaryRepo().save_summary(session, run_date, text, self.cfg.summarization.model)
+ client = TelegramClient()
+ if client.is_configured():
+ for chunk in chunks:
+ client.send_message(chunk)
- from gimme_job.runtime.notifier import NotificationDispatcher
dispatcher = NotificationDispatcher(
global_config=self.cfg, session_factory=self.session_factory
)
- dispatcher.send(text, run_date)
+ full_text = "\n\n".join(chunks)
+ dispatcher.send_markdown_fallback(full_text, run_date)
except Exception as e:
logger.error(f"Summarize/notify failed: {e}")