Digest Distribution & Scheduling
Demo: Digest Scheduling & Category Settings
This recording shows configuring digest scheduling for a category — setting the frequency, day, and time, viewing the category statistics, and saving the configuration.
Features Demonstrated
- Category Settings Modal — Configure digest scheduling with frequency, day, and time controls
- Digest Frequency Options — Weekly, Biweekly, Monthly, or Quarterly
- Category Statistics — Subscriber count, knowledge items, pending items, last/next digest dates
- Quick Action Shortcuts — Generate or distribute a digest directly from the settings modal
- Automated Scheduling — A cron command checks all categories and triggers digests for those due
Digests are YapHub's knowledge distribution mechanism. They collect knowledge items for a category over a time period, generate AI summaries, and deliver formatted reports to subscribers via Slack DM.
Digest Generation
Users trigger digest generation from the App Home:
- Select a category
- Choose a date mode:
- Last N days — e.g., "7 days", "14 days", "30 days"
- Date range — Specific start and end dates
- All time — All knowledge items in the category
- Optionally set an item limit
- Submit to generate
The 7-Step Pipeline
Step 1 — Resolve Category: Look up the target category by ID.
Step 2 — Parse Date Range: DateRangeParser converts user input into concrete start/end dates. Supports Dutch input like "laatste week" and English like "7 days".
Step 3 — Query Knowledge: Fetch knowledge items matching the category and date range via KnowledgeRepository::findByCategoryAndDateRange().
Step 4 — Generate AI Highlights: For each knowledge item, KnowledgeHighlightGenerator produces a 2–3 sentence Dutch summary. Items with existing highlights are skipped (lazy generation).
Step 5 — Format Markdown: DigestContentFormatter builds a Dutch-language Markdown document:
# DevOps & Infrastructure Kennisdigest
Periode: 01/05/2026 - 08/05/2026 | Gegenereerd op 08/05/2026
5 items in deze digest
---
### [Kubernetes Best Practices](https://notion.so/...) (3 minuten)
Deze handleiding bespreekt de belangrijkste patronen voor productieklare
Kubernetes clusters, inclusief resource limits en health checks...
`DevOps` `Kubernetes` `Infrastructure`
---Step 6 — Create Entity: DigestCreationService creates a Digest entity with:
- Auto-generated title: "Digest: {Category} ({dateRange})"
- Full Markdown content
- Statistics: highlight count, day count
- JSON snapshot of all highlights (immutable record)
- ManyToMany link to source knowledge items
Step 7 — Persist & Sync: Save to SQLite and sync to Notion via NotionSyncService::syncDigestToNotion().
Digest Distribution
After generation, digests can be distributed to category subscribers:
- User clicks "Digest Delen" (Share Digest) or uses the category overflow menu
- Selects the target category
- Picks from a list of generated digests (each showing title, highlight count, date range, status)
- Confirms distribution — a confirmation modal shows subscriber count
Distribution Flow
Delivery Tracking
Each delivery is tracked in a DigestDelivery entity:
| Field | Description |
|---|---|
| User ID | Recipient's Slack user ID |
| Channel | Delivery method (slack, notion, or email) |
| Status | pending, sent, or failed |
| Retry Count | Number of retry attempts (max 3) |
| Error Message | Failure details if delivery failed |
| Sent At | Timestamp of successful delivery |
Failed deliveries can be retried via POST /api/digests/{id}/retry-failed. Each delivery tracks up to 3 retry attempts.
Scheduled Digests
Categories with digest settings enabled can generate digests automatically:
Category Settings Modal
Click "Lijst Instellingen" (Category Settings) from the App Home quick actions, or select "Instellingen" from any category's overflow menu.
Digest Planning Section
| Setting | Options | Description |
|---|---|---|
| Ingeschakeld (Enabled) | Ja / Nee | Toggle automated digests on or off |
| Frequentie (Frequency) | Wekelijks / Tweewekelijks / Maandelijks / Kwartaallijks | How often digests are generated |
| Dag (Day) | Day of week (for weekly/biweekly) or Day of month 1-28 (for monthly/quarterly) | Which day to generate |
| Tijd (Time) | 07:00 through 18:00 (hourly slots) | What time to generate and distribute |
The Day field adapts based on frequency selection:
- Weekly / Biweekly — Shows days of the week (Maandag, Dinsdag, etc.)
- Monthly / Quarterly — Shows day of month (1 through 28) to avoid months with fewer days
Statistics Section
Below the settings form, the modal shows live statistics for the selected category:
| Statistic | Description |
|---|---|
| Abonnees (Subscribers) | Count with Slack user mentions of who is subscribed |
| Kennisitems (Knowledge Items) | Total count, with pending vs. total breakdown |
| Digests | Total number of digests generated for this category |
| Laatste Digest (Last Digest) | Date of the most recent digest, or "Nog geen" (None yet) |
| Volgende Gepland (Next Scheduled) | Calculated next digest date based on current schedule settings |
Quick Action Buttons
The settings modal includes two shortcut buttons:
- "Maak Digest" (Generate Digest) — Opens the digest generation modal pre-filled for this category
- "Deel Digest" (Distribute Digest) — Opens the distribution modal pre-filled for this category
Automated Execution
DigestSchedulerService::processScheduledDigests()checks all digest-enabled categories- For each category, it calculates whether a digest is due based on:
lastDigestAt+ frequency interval- Configured day of week and time
- If due, it triggers the full digest generation pipeline and distributes to all subscribers via Slack DM
- Uses file-based locking to prevent concurrent runs
Frequency Options
| Frequency | Dutch Label | Days Between |
|---|---|---|
| Weekly | Wekelijks | 7 |
| Biweekly | Tweewekelijks | 14 |
| Monthly | Maandelijks | 30 |
| Quarterly | Kwartaallijks | 90 |
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/digests/generate | Generate a new digest |
| POST | /api/digests/{id}/distribute | Distribute to subscribers |
| GET | /api/digests/{id}/delivery-status | Check delivery status |
| POST | /api/digests/{id}/retry-failed | Retry failed deliveries |
| GET | /api/digests/category/{categoryId} | List digests for a category |
| GET | /api/categories/{id}/settings/digest | Get digest settings |
| PUT | /api/categories/{id}/settings/digest | Update digest settings |