Technical Reference
Configuration
Section titled “Configuration”| Setting | Description | Default |
|---|---|---|
Email:Enabled | Enable/disable email monitoring | - |
Email:Provider | Email provider (graph or imap) | - |
Email:Mailbox | Bot’s email address | - |
Email:PollIntervalMinutes | Email mailbox check frequency | ~5 min |
Email:RecurrenceHorizonDays | Recurring meeting expansion horizon | 7 days |
JoinLeadTime | Lead time before joining | 15 sec |
DedupTolerance | Meeting deduplication tolerance | 5 min |
FallbackMeetingDuration | Assumed duration if unknown | 4 hours |
MaxWaitMinutes | Maximum wait time in empty meeting | Configurable |
Invitation Detection
Section titled “Invitation Detection”The system processes up to 25 unread messages per polling cycle. For each message, invitation detection follows this priority order:
- ICS attachments in the email
- ICS embedded in MIME content
- Graph API EventMessage (when ICS is not found)
Extracted Data
Section titled “Extracted Data”- Meeting URL: patterns
/l/meetup-join/(legacy) and/meet/(current) - Occurrence times
- Meeting duration
- Recurrence information (RRULE)
- Meeting ID and Passcode (extracted from email body as fallback)
If no time is found, the meeting is scheduled immediately (with a 10-second delay).
Webhook Resolution
Section titled “Webhook Resolution”Two possible paths to resolve the transcription destination:
Explicit Webhook
Section titled “Explicit Webhook”The {{webhook:https://...}} pattern in the email body is detected and used directly. Does not require sender registration in Prodgy.
Automatic Lookup (via Prodgy API)
Section titled “Automatic Lookup (via Prodgy API)”-
Identify the sender
- In forwarded emails: tries
FromAddressfirst, falls back toSenderAddress
- In forwarded emails: tries
-
Verify Prodgy registration
- User not found → rejects
-
Resolve the workspace
- One product → uses automatically
- Multiple workspaces → looks for
[ProductName]notation in the meeting title - Notation not found with multiple workspaces → rejects
-
Validate the agent
- Agent not installed → rejects
- No active version → rejects
- No webhook trigger configured → rejects
-
Return data
webhookUrl,userId,orgId,productId,agentBaseId
Deduplication and Scheduling
Section titled “Deduplication and Scheduling”Before scheduling, the system applies these validations in sequence:
- Meeting already ended? — Checks if
time + duration < now(fallback duration: 4 hours) - Occurrence cancelled? — Checks the cancellation list (URL + timestamp, 5-minute tolerance)
- Already scheduled? — Same URL + time within 5-minute tolerance → merges the new target
- Bot already in active call? — Adds target to active call without new scheduling
- All validations pass — Creates
ScheduledMeeting, persists to Redis, postsmeeting_scheduled
Automatic Invite Acceptance
Section titled “Automatic Invite Acceptance”After scheduling, the bot attempts to accept the calendar invitation via the email provider. Asynchronous execution — failures do not block scheduling.
Recurring Meetings
Section titled “Recurring Meetings”- Detects recurrence via RRULE (ICS) or PatternedRecurrence (Graph API)
- Expands future occurrences within the configured horizon (
RecurrenceHorizonDays) - Automatic re-expansion: every 12 hours, recalculates upcoming occurrences
- Multi-user: merges targets when multiple users forward the same recurring invitation
Retry Policy — Meeting Join
Section titled “Retry Policy — Meeting Join”| Attempt | Wait |
|---|---|
| 1st failure | 10 seconds |
| 2nd failure | 30 seconds |
| 3rd failure | 60 seconds |
After 3 consecutive failures, the system posts a meeting_error event.
Before each attempt, the bot re-validates all targets. Users deactivated since scheduling are removed. If no valid targets remain, the join is cancelled.
Retry Policy — Webhook Delivery
Section titled “Retry Policy — Webhook Delivery”| Attempt | Wait |
|---|---|
| 1st failure | 5 seconds |
| 2nd failure | 15 seconds |
| 3rd failure | 45 seconds |
- Each target is delivered independently — failure in one does not block the others
- If 0 segments and 0 participants: webhook is not sent
- Local backup saved to
logs/transcripts/before delivery - Backup file removed after successful delivery
Persistence and Recovery (Redis)
Section titled “Persistence and Recovery (Redis)”The system persists all state to Redis:
| Data | Description |
|---|---|
| Pending meetings | Scheduled meetings awaiting join |
| Recurrence patterns | Recurring meeting expansion rules |
| Cancelled occurrences | List of detected cancellations |
| Call-to-meeting mapping | Link between call_id and session |
Restart Behavior
Section titled “Restart Behavior”- Loads cancelled occurrences
- Loads recurrence patterns
- Resets orphaned meetings (status
joined→pending) - Restores pending meetings and recreates timers
- Cleans up stale past meetings
Event History — API
Section titled “Event History — API”GET /api/meeting-events
| Parameter | Type | Description |
|---|---|---|
organization_id | required | Filter by organization |
event_type | optional | Event type (e.g., meeting_joined) |
status | optional | Status (completed, failed) |
start_date | optional | Start date (ISO 8601) |
end_date | optional | End date (ISO 8601) |
limit | optional | Result limit (default: 200) |
offset | optional | Offset for pagination |
Results ordered by creation date (most recent first).
Real-Time Streaming (SSE)
Section titled “Real-Time Streaming (SSE)”GET /api/meetings/history/stream
- Each new event triggers a notification via Server-Sent Events
- No polling needed
Recording Resilience
Section titled “Recording Resilience”Event recording uses fire-and-forget semantics: recording failures never block the meeting flow.