Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
All /api/admin/email/* routes require an authenticated platform admin session (admin or superadmin role).
/api/cron/* and /api/webhooks/email/inbound use CRON_SECRET or WEBHOOK_EMAIL_SECRET — not user sessions.
GET /api/admin/email/threadsList conversation threads.
| Query | Type | Description |
|---|---|---|
status | string | Filter: new, ongoing, waiting, resolved, or omit for all |
Response: { threads: EmailThreadRecord[] }
PATCH /api/admin/email/threadsUpdate thread status.
Body: { "id": "<threadId>", "status": "resolved" }
GET /api/admin/email/threads/[id]Thread detail with messages, drafts, and open tasks.
Response: { thread, messages, drafts, tasks }
GET /api/admin/email/draftsPending drafts (status: pending), newest first.
POST /api/admin/email/drafts/[id]/approveApprove draft for sending. Uses session user id as reviewer.
POST /api/admin/email/drafts/[id]/rejectBody: { "reason": "optional string" }
POST /api/admin/email/drafts/[id]/sendSend approved draft via SMTP.
Body (optional): { "toEmail": "...", "subject": "..." } — defaults from thread.
Response: { "success": true, "messageId": "<smtp-message-id>" }
Persists outbound row in email_messages and updates thread status to waiting.
GET /api/admin/email/contacts| Query | Description |
|---|---|
email, name, company, type | Search filters |
POST /api/admin/email/contactsBody: { "email": "required", "name?", "company?", "type?" }
GET /api/admin/email/tasks| Query | Description |
|---|---|
status | open, in_progress, overdue, completed, etc. |
POST /api/admin/email/tasksBody: { "threadId", "title", "taskType", ... } — see TaskCreateInput in task-service.ts.
POST /api/admin/email/tasks/[id]/completeBody: { "completionNotes?": "string" }
GET /api/admin/email/analytics| Query | Values |
|---|---|
range | 7d (default), 30d, 90d |
Response: intent/sentiment distributions, costStats from email_api_usage, dailyStats, draft/task summaries.
POST or GET /api/cron/email-processorAuth: Authorization: Bearer $CRON_SECRET
Body or query action:
| Action | Behavior |
|---|---|
poll (default) | pollInboundBatch() — fetch UNSEEN, process, disconnect |
status | Processor + IMAP stats |
stop | Stop IDLE listener |
start | Start IDLE (requires EMAIL_PROCESSOR_ALLOW_HTTP_START=true) |
mark-overdue-tasks | Run EmailTaskService.processOverdueTasks() |
Example:
GET /api/cron/email-analyticsReturns 7-day dashboard snapshot (same shape as admin analytics). Cron-auth only.
POST /api/webhooks/email/inboundAuth: Authorization: Bearer $WEBHOOK_EMAIL_SECRET or HMAC-SHA256 hex in X-Email-Webhook-Signature over raw body.
Body (JSON):
Calls EmailProcessor.ingestEvent() with uid: 0 (no IMAP mark-seen).
All /api/admin/email/* routes require an authenticated platform admin session (admin or superadmin role).
/api/cron/* and /api/webhooks/email/inbound use CRON_SECRET or WEBHOOK_EMAIL_SECRET — not user sessions.
GET /api/admin/email/threadsList conversation threads.
| Query | Type | Description |
|---|---|---|
status | string | Filter: new, ongoing, waiting, resolved, or omit for all |
Response: { threads: EmailThreadRecord[] }
PATCH /api/admin/email/threadsUpdate thread status.
Body: { "id": "<threadId>", "status": "resolved" }
GET /api/admin/email/threads/[id]Thread detail with messages, drafts, and open tasks.
Response: { thread, messages, drafts, tasks }
GET /api/admin/email/draftsPending drafts (status: pending), newest first.
POST /api/admin/email/drafts/[id]/approveApprove draft for sending. Uses session user id as reviewer.
POST /api/admin/email/drafts/[id]/rejectBody: { "reason": "optional string" }
POST /api/admin/email/drafts/[id]/sendSend approved draft via SMTP.
Body (optional): { "toEmail": "...", "subject": "..." } — defaults from thread.
Response: { "success": true, "messageId": "<smtp-message-id>" }
Persists outbound row in email_messages and updates thread status to waiting.
GET /api/admin/email/contacts| Query | Description |
|---|---|
email, name, company, type | Search filters |
POST /api/admin/email/contactsBody: { "email": "required", "name?", "company?", "type?" }
GET /api/admin/email/tasks| Query | Description |
|---|---|
status | open, in_progress, overdue, completed, etc. |
POST /api/admin/email/tasksBody: { "threadId", "title", "taskType", ... } — see TaskCreateInput in task-service.ts.
POST /api/admin/email/tasks/[id]/completeBody: { "completionNotes?": "string" }
GET /api/admin/email/analytics| Query | Values |
|---|---|
range | 7d (default), 30d, 90d |
Response: intent/sentiment distributions, costStats from email_api_usage, dailyStats, draft/task summaries.
POST or GET /api/cron/email-processorAuth: Authorization: Bearer $CRON_SECRET
Body or query action:
| Action | Behavior |
|---|---|
poll (default) | pollInboundBatch() — fetch UNSEEN, process, disconnect |
status | Processor + IMAP stats |
stop | Stop IDLE listener |
start | Start IDLE (requires EMAIL_PROCESSOR_ALLOW_HTTP_START=true) |
mark-overdue-tasks | Run EmailTaskService.processOverdueTasks() |
Example:
GET /api/cron/email-analyticsReturns 7-day dashboard snapshot (same shape as admin analytics). Cron-auth only.
POST /api/webhooks/email/inboundAuth: Authorization: Bearer $WEBHOOK_EMAIL_SECRET or HMAC-SHA256 hex in X-Email-Webhook-Signature over raw body.
Body (JSON):
Calls EmailProcessor.ingestEvent() with uid: 0 (no IMAP mark-seen).
All /api/admin/email/* routes require an authenticated platform admin session (admin or superadmin role).
/api/cron/* and /api/webhooks/email/inbound use CRON_SECRET or WEBHOOK_EMAIL_SECRET — not user sessions.
GET /api/admin/email/threadsList conversation threads.
| Query | Type | Description |
|---|---|---|
status | string | Filter: new, ongoing, waiting, resolved, or omit for all |
Response: { threads: EmailThreadRecord[] }
PATCH /api/admin/email/threadsUpdate thread status.
Body: { "id": "<threadId>", "status": "resolved" }
GET /api/admin/email/threads/[id]Thread detail with messages, drafts, and open tasks.
Response: { thread, messages, drafts, tasks }
GET /api/admin/email/draftsPending drafts (status: pending), newest first.
POST /api/admin/email/drafts/[id]/approveApprove draft for sending. Uses session user id as reviewer.
POST /api/admin/email/drafts/[id]/rejectBody: { "reason": "optional string" }
POST /api/admin/email/drafts/[id]/sendSend approved draft via SMTP.
Body (optional): { "toEmail": "...", "subject": "..." } — defaults from thread.
Response: { "success": true, "messageId": "<smtp-message-id>" }
Persists outbound row in email_messages and updates thread status to waiting.
GET /api/admin/email/contacts| Query | Description |
|---|---|
email, name, company, type | Search filters |
POST /api/admin/email/contactsBody: { "email": "required", "name?", "company?", "type?" }
GET /api/admin/email/tasks| Query | Description |
|---|---|
status | open, in_progress, overdue, completed, etc. |
POST /api/admin/email/tasksBody: { "threadId", "title", "taskType", ... } — see TaskCreateInput in task-service.ts.
POST /api/admin/email/tasks/[id]/completeBody: { "completionNotes?": "string" }
GET /api/admin/email/analytics| Query | Values |
|---|---|
range | 7d (default), 30d, 90d |
Response: intent/sentiment distributions, costStats from email_api_usage, dailyStats, draft/task summaries.
POST or GET /api/cron/email-processorAuth: Authorization: Bearer $CRON_SECRET
Body or query action:
| Action | Behavior |
|---|---|
poll (default) | pollInboundBatch() — fetch UNSEEN, process, disconnect |
status | Processor + IMAP stats |
stop | Stop IDLE listener |
start | Start IDLE (requires EMAIL_PROCESSOR_ALLOW_HTTP_START=true) |
mark-overdue-tasks | Run EmailTaskService.processOverdueTasks() |
Example:
GET /api/cron/email-analyticsReturns 7-day dashboard snapshot (same shape as admin analytics). Cron-auth only.
POST /api/webhooks/email/inboundAuth: Authorization: Bearer $WEBHOOK_EMAIL_SECRET or HMAC-SHA256 hex in X-Email-Webhook-Signature over raw body.
Body (JSON):
Calls EmailProcessor.ingestEvent() with uid: 0 (no IMAP mark-seen).
curl -X POST "$BASE_URL/api/cron/email-processor" \
-H "Authorization: Bearer $CRON_SECRET" \
-H "Content-Type: application/json" \
-d '{"action":"poll"}'
{
"messageId": "<rfc5322-message-id>",
"from": "sender@example.com",
"fromName": "Optional Name",
"to": "info@example.com",
"subject": "Subject line",
"bodyText": "Plain text body",
"bodyHtml": "<div>optional</div>",
"date": "2026-06-10T12:00:00.000Z",
"inReplyTo": "<parent-message-id>",
"references": ["<ref1>", "<ref2>"]
}
curl -X POST "$BASE_URL/api/cron/email-processor" \
-H "Authorization: Bearer $CRON_SECRET" \
-H "Content-Type: application/json" \
-d '{"action":"poll"}'
{
"messageId": "<rfc5322-message-id>",
"from": "sender@example.com",
"fromName": "Optional Name",
"to": "info@example.com",
"subject": "Subject line",
"bodyText": "Plain text body",
"bodyHtml": "<div>optional</div>",
"date": "2026-06-10T12:00:00.000Z",
"inReplyTo": "<parent-message-id>",
"references": ["<ref1>", "<ref2>"]
}
curl -X POST "$BASE_URL/api/cron/email-processor" \
-H "Authorization: Bearer $CRON_SECRET" \
-H "Content-Type: application/json" \
-d '{"action":"poll"}'
{
"messageId": "<rfc5322-message-id>",
"from": "sender@example.com",
"fromName": "Optional Name",
"to": "info@example.com",
"subject": "Subject line",
"bodyText": "Plain text body",
"bodyHtml": "<div>optional</div>",
"date": "2026-06-10T12:00:00.000Z",
"inReplyTo": "<parent-message-id>",
"references": ["<ref1>", "<ref2>"]
}