Platform
Mail
Overview

Mail

Base URL: https://mail-api.pcampus.co

Overview

Mail คือ email delivery service ที่รับผิดชอบการส่ง email ทุกประเภทใน Pcampus ecosystem ทั้ง transactional email (ยืนยันการสมัคร, รีเซ็ต password, invoice) และ marketing email (newsletter, campaigns, promotions) ผ่าน provider เดียว

Notification service ใช้ Mail service สำหรับ email channel — ไม่มี service ใดส่ง SMTP ตรงๆ เอง

Who uses this

Personaใช้ทำอะไร
Internal serviceNotification, Billing, PIP เรียก API ส่ง transactional email อัตโนมัติ
Developer (ลูกค้า)ส่ง transactional email ถึง user ของตัวเอง (order confirmation, OTP, etc.)
Marketing Managerสร้างและส่ง email campaign / newsletter ถึง subscriber list
Adminดู delivery analytics, จัดการ domain settings, bounce handling

Key features

  • Transactional email — ส่งทันทีเมื่อ event เกิดขึ้น (user signup, payment, etc.)
  • Marketing campaigns — สร้าง campaign email พร้อม template editor, schedule, และ A/B testing
  • Template engine — HTML template พร้อม variable substitution ({{user.name}})
  • Domain authentication — SPF, DKIM, DMARC setup per organization
  • Deliverability tracking — delivered, opened, clicked, bounced, unsubscribed ต่อ email
  • Bounce & spam management — จัดการ hard/soft bounce, suppress unsubscribed
  • Subscriber lists — จัดการ list, tags, และ segments สำหรับ marketing campaigns

User stories

Billing service (internal):

"เมื่อ invoice ถูกสร้าง ต้องการส่ง PDF invoice ให้ org admin ทาง email"

→ Billing เรียก Notification → Notification เรียก POST /mail/send พร้อม templateId: invoice, attachment PDF

Developer (ลูกค้า):

"ผมต้องการส่ง OTP email ให้ user เมื่อ login ด้วย phone number"

→ Console → เพิ่ม domain → สร้าง template OTP → เรียก POST /mail/send

Marketing Manager:

"ผมต้องการส่ง newsletter ให้ subscriber list ทุกคน ทุกสัปดาห์"

→ สร้าง subscriber list → ออกแบบ template → schedule campaign → ดู open rate หลังส่ง

How it works

Data model

Integration

  • Notification — Mail ทำหน้าที่ email delivery layer ให้ Notification
  • Billing — Invoice, payment receipt ส่งตรงผ่าน Mail
  • PIP — Email verification, password reset ใช้ Mail

Domain setup

ทุก organization ต้องยืนยัน domain ก่อนส่ง email ด้วย from address ของตัวเอง

DNS Records required:
  TXT  @ "v=spf1 include:pcampus-mail.co ~all"
  TXT  pcampus._domainkey "v=DKIM1; k=rsa; p=..."
  TXT  _dmarc "v=DMARC1; p=quarantine;"

API overview

MethodEndpointDescription
POST/mail/sendSend single email
POST/mail/send-batchSend to multiple recipients
GET/mail/:id/statusGet delivery status
GET/templatesList email templates
POST/templatesCreate template
PATCH/templates/:idUpdate template
GET/subscribersList subscribers
POST/subscribersAdd subscriber
DELETE/subscribers/:emailUnsubscribe
GET/campaignsList campaigns
POST/campaignsCreate campaign
POST/campaigns/:id/sendSend campaign
GET/campaigns/:id/analyticsGet campaign analytics
GET/domainsList verified domains
POST/domainsAdd domain for verification

Send email payload

{
  "to": "user@example.com",
  "templateId": "tmpl_xxxx",
  "from": "noreply@yourdomain.com",
  "data": {
    "user": { "name": "Somchai" },
    "otp": "123456"
  }
}

Visual Email Block Builder

Mail มี block-based email builder ใน Console — แนวคิดเดียวกับ Flex Message builder แต่สำหรับ email แทน LINE

แทนที่จะเขียน HTML ตรงๆ ผู้ใช้ลาก block มาเรียงกัน ระบบ render เป็น responsive HTML อัตโนมัติ

Block types

BlockคำอธิบายProperties ที่ปรับได้
HeaderLogo + brand name บนสุดLogo URL, background color, alignment
Hero Imageรูปใหญ่คลิกได้Image URL, link URL, alt text
TextParagraph ข้อความFont size, color, alignment, variable slots
ButtonCTA buttonLabel, URL, style (filled/outline), color
Product Cardรูป + ชื่อ + ราคา + ปุ่มทุก field รองรับ {{variable}}
Dividerเส้นคั่นสี, margin
Columns2–3 column layoutสัดส่วน, เนื้อหาในแต่ละ column
Socialไอคอน social linksFacebook, LINE, Instagram, Website
FooterUnsubscribe link + copyrightข้อความ, links

ตัวอย่าง block structure (JSON)

{
  "templateId": "tmpl_winback",
  "name": "Win-back Campaign",
  "subject": "คิดถึงคุณ {{customerName}} ครับ",
  "blocks": [
    {
      "type": "header",
      "logo": "https://cdn.pcampus.co/pharmacy/logo.png",
      "backgroundColor": "#2563eb",
      "textColor": "#ffffff",
      "brandName": "Pharmacy App"
    },
    {
      "type": "hero_image",
      "imageUrl": "https://cdn.pcampus.co/pharmacy/winback-banner.jpg",
      "linkUrl": "{{shopUrl}}",
      "altText": "กลับมาซื้อยากับเราได้เลยครับ"
    },
    {
      "type": "text",
      "content": "สวัสดีครับ คุณ {{customerName}}\n\nเราสังเกตว่ายา {{lastProduct}} ของคุณน่าจะใกล้หมดแล้วนะครับ ไม่อยากให้ขาดยาครับ",
      "fontSize": "16px",
      "color": "#333333"
    },
    {
      "type": "button",
      "label": "สั่งยาซ้ำเลยครับ",
      "url": "{{reorderUrl}}",
      "style": "filled",
      "color": "#2563eb"
    },
    {
      "type": "text",
      "content": "ใช้โค้ด **{{couponCode}}** รับส่วนลด {{discountPercent}}% ครับ",
      "fontSize": "14px",
      "color": "#666666"
    },
    {
      "type": "divider"
    },
    {
      "type": "footer",
      "unsubscribeText": "ไม่ต้องการรับอีเมลนี้? {{unsubscribeLink}}",
      "copyright": "© 2026 Pharmacy App. สงวนลิขสิทธิ์"
    }
  ]
}

วิธีใช้ Builder ใน Console

  1. Console → Mail → Templates → New Template → Visual Builder
  2. เลือก layout preset — Newsletter, Promotion, Order Confirmation, Win-back, Receipt
  3. ลาก block จากแถบด้านซ้ายมาวางในพื้นที่ออกแบบ
  4. คลิก block เพื่อแก้ไขเนื้อหา — พิมพ์ {{ เพื่อ insert variable
  5. Preview — ดูผลทั้ง Desktop และ Mobile (320px) ตรวจ responsive
  6. Send test — ส่งไป email จริงก่อน publish

Builder ใช้ MJML เป็น rendering engine — HTML ที่ generate ออกมาใช้ table-based layout ที่ compatible กับ Gmail, Outlook, Apple Mail ครอบคลุม email client กว่า 90%

Variable substitution ใน blocks

Variable ใส่ในทุก field ที่เป็น text:

subject:  "คำสั่งซื้อ #{{orderId}} ได้รับแล้วครับ"
body:     "สวัสดีครับ {{customerName}}"
button:   label = "ดูคำสั่งซื้อ", url = "{{orderUrl}}"

สำหรับ block ที่มี list (เช่น order items) ใช้ loop:

{{#each items}}
  {{this.name}} — {{this.qty}} ชิ้น — {{this.price}}
{{/each}}

Render ผ่าน API

Builder saves block JSON ไว้ใน template ส่ง email ระบบ render เป็น HTML ณ เวลาส่ง:

POST https://mail-api.pcampus.co/v1/mail/send
{
  "to": "somchai@example.com",
  "templateId": "tmpl_winback",
  "variables": {
    "customerName": "สมชาย",
    "lastProduct": "Amlodipine 5mg",
    "couponCode": "WINBACK10",
    "discountPercent": "10",
    "reorderUrl": "https://pharmacy-app.co.th/reorder/cust_001",
    "shopUrl": "https://pharmacy-app.co.th"
  }
}

ดู Mail API → สำหรับ endpoint สำหรับจัดการ block templates ผ่านโค้ด


Subscription Digest Email

Digest email คือ email สรุปข้อมูลที่ระบบ generate เนื้อหาแบบรายบุคคล จาก Customer Story ใน PBCP — ไม่ใช่ blast template เดียวส่งทุกคน แต่เนื้อหาในแต่ละ email จะต่างกันตามข้อมูลของผู้รับแต่ละคน

Digest modes

Modeคำอธิบายตัวอย่าง
Personal digestเนื้อหา bind กับ Customer Story ของแต่ละคน"ยอดสะสม เดือนนี้ของคุณสมชาย", "รายการซื้อล่าสุด 30 วัน"
Group digestสรุปข้อมูล segment — ส่งถึง admin หรือ manager"รายงาน VIP customers ประจำสัปดาห์", "สรุปยอดขาย branch บางนา"
Activity digestเหตุการณ์ที่เกิดกับลูกค้าในช่วงเวลา"Orders ที่ pending นานกว่า 3 วัน", "ลูกค้าที่หมดอายุสมาชิกเดือนนี้"

Personal digest — bind กับ Customer Story

{
  "templateId": "tmpl_monthly_summary",
  "name": "Monthly Customer Digest",
  "type": "digest",
  "subject": "สรุปกิจกรรมของคุณ {{customerName}} — {{month}}",
  "digestConfig": {
    "dataSource": "customer_story",
    "personalized": true,
    "fields": [
      "totalSpend30d",
      "visitCount30d",
      "topProducts",
      "loyaltyPoints",
      "nextReward",
      "recommendations"
    ]
  },
  "blocks": [
    { "type": "header", "brandName": "Pharmacy App" },
    {
      "type": "text",
      "content": "สวัสดีครับ คุณ {{customerName}} นี่คือสรุปกิจกรรมของคุณในเดือน {{month}} ครับ"
    },
    {
      "type": "stat_row",
      "stats": [
        { "label": "ยอดซื้อรวม", "value": "{{totalSpend30d}}", "unit": "บาท" },
        { "label": "จำนวนครั้ง", "value": "{{visitCount30d}}", "unit": "ครั้ง" },
        { "label": "คะแนนสะสม", "value": "{{loyaltyPoints}}", "unit": "แต้ม" }
      ]
    },
    {
      "type": "product_list",
      "title": "สินค้าที่ซื้อบ่อย",
      "items": "{{topProducts}}"
    },
    {
      "type": "callout",
      "content": "อีก {{nextReward.pointsNeeded}} แต้ม คุณจะได้รับ {{nextReward.rewardName}} ครับ"
    },
    { "type": "footer" }
  ]
}

ข้อมูลที่ใส่ใน fields ดึงจาก Customer Story ของแต่ละ recipient โดยอัตโนมัติ — ไม่ต้องส่ง variables มาเองตอน send

Group digest — สรุปข้อมูล segment

{
  "templateId": "tmpl_vip_weekly",
  "name": "VIP Weekly Report",
  "type": "digest",
  "subject": "VIP Weekly Report — สัปดาห์ที่ {{weekNumber}}",
  "digestConfig": {
    "dataSource": "segment",
    "segmentId": "seg_vip",
    "aggregation": "weekly",
    "recipientType": "admin",
    "metrics": [
      "totalRevenue",
      "newVipCount",
      "churnRiskCount",
      "topSpenders"
    ]
  },
  "blocks": [
    { "type": "header", "brandName": "Pharmacy Admin" },
    {
      "type": "stat_row",
      "stats": [
        { "label": "รายได้จาก VIP", "value": "{{totalRevenue}}" },
        { "label": "VIP ใหม่", "value": "{{newVipCount}} คน" },
        { "label": "เสี่ยง Churn", "value": "{{churnRiskCount}} คน" }
      ]
    },
    { "type": "table", "title": "Top Spenders สัปดาห์นี้", "data": "{{topSpenders}}" },
    { "type": "footer" }
  ]
}

ตั้งค่า Digest ใน Console

Console → Mail → Digest → New Digest:

  1. เลือก Digest type — Personal / Group / Activity
  2. กำหนด Data source — Customer Story fields หรือ segment metrics
  3. ออกแบบ template — ใช้ block builder เหมือนกัน รองรับ block พิเศษ stat_row, product_list, table
  4. กำหนด Recipients — subscriber list หรือ segment จาก Intelligence
  5. ตั้ง Schedule — รายวัน / รายสัปดาห์ / รายเดือน ดูเพิ่มใน Scheduler
  6. Preview per-recipient — เลือก customer แล้วดูว่า email ของเขาจะออกมาหน้าตาอย่างไร

Broadcast Scheduler

Scheduler คือ calendar view ของ scheduled broadcasts ทั้งหมด — เห็นได้ว่าวันไหนจะส่งอะไร ถึงใคร ผ่านช่องทางอะไร สร้างและจัดการได้จากที่เดียว

หน้า Scheduler ใน Console

Console → Mail → Scheduler (สำหรับ email) หรือ Console → Notification → Scheduler (สำหรับ LINE / Push / SMS)

┌─────────────────────────────────────────────────────────┐
│  📅  Broadcast Scheduler — กรกฎาคม 2026                │
│  [+ New Broadcast]                  [List] [Calendar]   │
├────────┬────────┬────────┬────────┬────────┬────────────┤
│  จ 14  │  อ 15  │  พ 16  │  พฤ 17 │  ศ 18  │  ส 19      │
├────────┼────────┼────────┼────────┼────────┼────────────┤
│        │ 09:00  │        │ 10:00  │ 08:00  │            │
│        │ 📧 VIP │        │ 📱LINE │ 📧     │            │
│        │ Weekly │        │ Promo  │ Digest │            │
│        │ 2,341  │        │ 5,820  │ 1,204  │            │
│        │ คน     │        │ คน     │ คน     │            │
└────────┴────────┴────────┴────────┴────────┴────────────┘

แต่ละ block บน calendar คลิกได้เพื่อดู:

  • ชื่อ broadcast และ template ที่ใช้
  • จำนวน recipients (total / segment)
  • สถานะ: scheduled | sending | sent | failed
  • ปุ่ม Edit / Cancel / Duplicate

สร้าง Scheduled Broadcast

Console → Scheduler → + New Broadcast:

  1. เลือกช่องทาง — Email / LINE / Push / SMS
  2. เลือก template — เลือกจาก templates ที่สร้างไว้
  3. กำหนด recipients — subscriber list, segment จาก Intelligence, หรือ customer ID list
  4. ตั้งเวลาส่ง — วันที่ + เวลา (timezone: Asia/Bangkok) หรือตั้ง recurrence
  5. Preview — ดู email/message ตัวอย่างก่อน schedule
  6. Confirm — broadcast ปรากฎบน calendar ทันที

Recurrence

Patternตัวอย่าง
One-timeส่งครั้งเดียว 16 ก.ค. 09:00
Dailyทุกวัน 08:00 (digest รายวัน)
Weeklyทุกวันจันทร์ 09:00 (VIP weekly report)
Monthlyวันที่ 1 ของทุกเดือน 10:00 (monthly summary)
Custom cron0 9 * * 1 — ทุกวันจันทร์ 09:00

List view

นอกจาก calendar ยังมี list view ที่ filter/sort ได้:

FieldFilter options
ChannelEmail, LINE, Push, SMS
StatusScheduled, Sent, Failed, Cancelled
Date rangeวันที่กำหนดส่ง
Templateกรองตาม template ID
Recipient countน้อย–มาก

ดู Notification API → Scheduler และ Mail API → Scheduler สำหรับ REST endpoints

Mail

Base URL: https://mail-api.pcampus.co

Overview

Mail is the email delivery service responsible for sending every type of email in the Pcampus ecosystem — both transactional email (registration confirmation, password reset, invoice) and marketing email (newsletters, campaigns, promotions) — through a single provider.

The Notification service uses the Mail service for its email channel — no service sends SMTP directly on its own.

Who uses this

PersonaWhat They Do
Internal serviceNotification, Billing, PIP call the API to send transactional emails automatically
Developer (customer)Send transactional emails to their own users (order confirmation, OTP, etc.)
Marketing ManagerCreate and send email campaigns / newsletters to subscriber lists
AdminView delivery analytics, manage domain settings, handle bounces

Key features

  • Transactional email — Sent immediately when an event occurs (user signup, payment, etc.)
  • Marketing campaigns — Create campaign emails with a template editor, scheduling, and A/B testing
  • Template engine — HTML templates with variable substitution ({{user.name}})
  • Domain authentication — SPF, DKIM, DMARC setup per organization
  • Deliverability tracking — Tracks delivered, opened, clicked, bounced, and unsubscribed per email
  • Bounce & spam management — Handles hard/soft bounces, suppresses unsubscribed addresses
  • Subscriber lists — Manage lists, tags, and segments for marketing campaigns

User stories

Billing service (internal):

"When an invoice is created, we need to send a PDF invoice to the org admin via email"

→ Billing calls Notification → Notification calls POST /mail/send with templateId: invoice, PDF attachment

Developer (customer):

"I want to send an OTP email to users when they log in with a phone number"

→ Console → add domain → create OTP template → call POST /mail/send

Marketing Manager:

"I want to send a newsletter to all my subscribers every week"

→ Create subscriber list → design template → schedule campaign → view open rate after sending

How it works

Data model

Integration

  • Notification — Mail acts as the email delivery layer for Notification
  • Billing — Invoice and payment receipts are sent directly through Mail
  • PIP — Email verification and password reset use Mail

Domain setup

Every organization must verify their domain before sending email with their own from address.

DNS Records required:
  TXT  @ "v=spf1 include:pcampus-mail.co ~all"
  TXT  pcampus._domainkey "v=DKIM1; k=rsa; p=..."
  TXT  _dmarc "v=DMARC1; p=quarantine;"

API overview

MethodEndpointDescription
POST/mail/sendSend single email
POST/mail/send-batchSend to multiple recipients
GET/mail/:id/statusGet delivery status
GET/templatesList email templates
POST/templatesCreate template
PATCH/templates/:idUpdate template
GET/subscribersList subscribers
POST/subscribersAdd subscriber
DELETE/subscribers/:emailUnsubscribe
GET/campaignsList campaigns
POST/campaignsCreate campaign
POST/campaigns/:id/sendSend campaign
GET/campaigns/:id/analyticsGet campaign analytics
GET/domainsList verified domains
POST/domainsAdd domain for verification

Send email payload

{
  "to": "user@example.com",
  "templateId": "tmpl_xxxx",
  "from": "noreply@yourdomain.com",
  "data": {
    "user": { "name": "Somchai" },
    "otp": "123456"
  }
}

Visual Email Block Builder

Mail includes a block-based email builder in Console — the same concept as the Flex Message builder, but for email instead of LINE.

Instead of writing HTML directly, users drag blocks into place and the system automatically renders responsive HTML.

Block types

BlockDescriptionAdjustable Properties
HeaderLogo + brand name at the topLogo URL, background color, alignment
Hero ImageLarge clickable imageImage URL, link URL, alt text
TextText paragraphFont size, color, alignment, variable slots
ButtonCTA buttonLabel, URL, style (filled/outline), color
Product CardImage + name + price + buttonAll fields support {{variable}}
DividerSeparator lineColor, margin
Columns2–3 column layoutProportions, content in each column
SocialSocial link iconsFacebook, LINE, Instagram, Website
FooterUnsubscribe link + copyrightText, links

Block Structure Example (JSON)

{
  "templateId": "tmpl_winback",
  "name": "Win-back Campaign",
  "subject": "คิดถึงคุณ {{customerName}} ครับ",
  "blocks": [
    {
      "type": "header",
      "logo": "https://cdn.pcampus.co/pharmacy/logo.png",
      "backgroundColor": "#2563eb",
      "textColor": "#ffffff",
      "brandName": "Pharmacy App"
    },
    {
      "type": "hero_image",
      "imageUrl": "https://cdn.pcampus.co/pharmacy/winback-banner.jpg",
      "linkUrl": "{{shopUrl}}",
      "altText": "กลับมาซื้อยากับเราได้เลยครับ"
    },
    {
      "type": "text",
      "content": "สวัสดีครับ คุณ {{customerName}}\n\nเราสังเกตว่ายา {{lastProduct}} ของคุณน่าจะใกล้หมดแล้วนะครับ ไม่อยากให้ขาดยาครับ",
      "fontSize": "16px",
      "color": "#333333"
    },
    {
      "type": "button",
      "label": "สั่งยาซ้ำเลยครับ",
      "url": "{{reorderUrl}}",
      "style": "filled",
      "color": "#2563eb"
    },
    {
      "type": "text",
      "content": "ใช้โค้ด **{{couponCode}}** รับส่วนลด {{discountPercent}}% ครับ",
      "fontSize": "14px",
      "color": "#666666"
    },
    {
      "type": "divider"
    },
    {
      "type": "footer",
      "unsubscribeText": "ไม่ต้องการรับอีเมลนี้? {{unsubscribeLink}}",
      "copyright": "© 2026 Pharmacy App. สงวนลิขสิทธิ์"
    }
  ]
}

How to Use the Builder in Console

  1. Console → Mail → Templates → New Template → Visual Builder
  2. Choose a layout preset — Newsletter, Promotion, Order Confirmation, Win-back, Receipt
  3. Drag blocks from the left panel into the design area
  4. Click a block to edit content — type {{ to insert a variable
  5. Preview — view results on both Desktop and Mobile (320px) to verify responsive behavior
  6. Send test — send to a real email address before publishing

The Builder uses MJML as its rendering engine — the generated HTML uses a table-based layout compatible with Gmail, Outlook, and Apple Mail, covering more than 90% of email clients.

Variable Substitution in Blocks

Variables can be used in any text field:

subject:  "คำสั่งซื้อ #{{orderId}} ได้รับแล้วครับ"
body:     "สวัสดีครับ {{customerName}}"
button:   label = "ดูคำสั่งซื้อ", url = "{{orderUrl}}"

For blocks with lists (e.g., order items), use a loop:

{{#each items}}
  {{this.name}} — {{this.qty}} ชิ้น — {{this.price}}
{{/each}}

Rendering via API

The Builder saves block JSON in the template; the system renders it to HTML at send time:

POST https://mail-api.pcampus.co/v1/mail/send
{
  "to": "somchai@example.com",
  "templateId": "tmpl_winback",
  "variables": {
    "customerName": "สมชาย",
    "lastProduct": "Amlodipine 5mg",
    "couponCode": "WINBACK10",
    "discountPercent": "10",
    "reorderUrl": "https://pharmacy-app.co.th/reorder/cust_001",
    "shopUrl": "https://pharmacy-app.co.th"
  }
}

See Mail API → for endpoints for managing block templates via code.


Subscription Digest Email

Digest email is a summary email that the system generates with personalized content from each recipient's Customer Story in PBCP — it is not a single blast template sent to everyone; the content in each email differs based on the individual recipient's data.

Digest modes

ModeDescriptionExample
Personal digestContent bound to each person's Customer Story"Your monthly balance, Somchai", "Purchases in the last 30 days"
Group digestSegment summary — sent to admin or manager"Weekly VIP customer report", "Bang Na branch sales summary"
Activity digestEvents that occurred with customers over a period"Orders pending more than 3 days", "Customers whose membership expires this month"

Personal Digest — Bound to Customer Story

{
  "templateId": "tmpl_monthly_summary",
  "name": "Monthly Customer Digest",
  "type": "digest",
  "subject": "สรุปกิจกรรมของคุณ {{customerName}} — {{month}}",
  "digestConfig": {
    "dataSource": "customer_story",
    "personalized": true,
    "fields": [
      "totalSpend30d",
      "visitCount30d",
      "topProducts",
      "loyaltyPoints",
      "nextReward",
      "recommendations"
    ]
  },
  "blocks": [
    { "type": "header", "brandName": "Pharmacy App" },
    {
      "type": "text",
      "content": "สวัสดีครับ คุณ {{customerName}} นี่คือสรุปกิจกรรมของคุณในเดือน {{month}} ครับ"
    },
    {
      "type": "stat_row",
      "stats": [
        { "label": "ยอดซื้อรวม", "value": "{{totalSpend30d}}", "unit": "บาท" },
        { "label": "จำนวนครั้ง", "value": "{{visitCount30d}}", "unit": "ครั้ง" },
        { "label": "คะแนนสะสม", "value": "{{loyaltyPoints}}", "unit": "แต้ม" }
      ]
    },
    {
      "type": "product_list",
      "title": "สินค้าที่ซื้อบ่อย",
      "items": "{{topProducts}}"
    },
    {
      "type": "callout",
      "content": "อีก {{nextReward.pointsNeeded}} แต้ม คุณจะได้รับ {{nextReward.rewardName}} ครับ"
    },
    { "type": "footer" }
  ]
}

Data in the fields is automatically fetched from each recipient's Customer Story — no need to supply variables at send time.

Group Digest — Segment Summary

{
  "templateId": "tmpl_vip_weekly",
  "name": "VIP Weekly Report",
  "type": "digest",
  "subject": "VIP Weekly Report — สัปดาห์ที่ {{weekNumber}}",
  "digestConfig": {
    "dataSource": "segment",
    "segmentId": "seg_vip",
    "aggregation": "weekly",
    "recipientType": "admin",
    "metrics": [
      "totalRevenue",
      "newVipCount",
      "churnRiskCount",
      "topSpenders"
    ]
  },
  "blocks": [
    { "type": "header", "brandName": "Pharmacy Admin" },
    {
      "type": "stat_row",
      "stats": [
        { "label": "รายได้จาก VIP", "value": "{{totalRevenue}}" },
        { "label": "VIP ใหม่", "value": "{{newVipCount}} คน" },
        { "label": "เสี่ยง Churn", "value": "{{churnRiskCount}} คน" }
      ]
    },
    { "type": "table", "title": "Top Spenders สัปดาห์นี้", "data": "{{topSpenders}}" },
    { "type": "footer" }
  ]
}

Configure Digest in Console

Console → Mail → Digest → New Digest:

  1. Choose Digest type — Personal / Group / Activity
  2. Define Data source — Customer Story fields or segment metrics
  3. Design the template — same block builder, with extra blocks: stat_row, product_list, table
  4. Define Recipients — subscriber list or segment from Intelligence
  5. Set Schedule — daily / weekly / monthly — see also Scheduler
  6. Preview per-recipient — select a customer to see exactly what their email will look like

Broadcast Scheduler

The Scheduler is the calendar view of all scheduled broadcasts — you can see what will be sent on each day, to whom, and through which channel, all creatable and manageable from one place.

Scheduler Page in Console

Console → Mail → Scheduler (for email) or Console → Notification → Scheduler (for LINE / Push / SMS)

┌─────────────────────────────────────────────────────────┐
│  📅  Broadcast Scheduler — กรกฎาคม 2026                │
│  [+ New Broadcast]                  [List] [Calendar]   │
├────────┬────────┬────────┬────────┬────────┬────────────┤
│  จ 14  │  อ 15  │  พ 16  │  พฤ 17 │  ศ 18  │  ส 19      │
├────────┼────────┼────────┼────────┼────────┼────────────┤
│        │ 09:00  │        │ 10:00  │ 08:00  │            │
│        │ 📧 VIP │        │ 📱LINE │ 📧     │            │
│        │ Weekly │        │ Promo  │ Digest │            │
│        │ 2,341  │        │ 5,820  │ 1,204  │            │
│        │ คน     │        │ คน     │ คน     │            │
└────────┴────────┴────────┴────────┴────────┴────────────┘

Each block on the calendar is clickable to view:

  • Broadcast name and template used
  • Number of recipients (total / segment)
  • Status: scheduled | sending | sent | failed
  • Edit / Cancel / Duplicate buttons

Create a Scheduled Broadcast

Console → Scheduler → + New Broadcast:

  1. Choose channel — Email / LINE / Push / SMS
  2. Choose template — select from templates already created
  3. Define recipients — subscriber list, segment from Intelligence, or customer ID list
  4. Set send time — date + time (timezone: Asia/Bangkok) or set recurrence
  5. Preview — view a sample email/message before scheduling
  6. Confirm — broadcast appears on the calendar immediately

Recurrence

PatternExample
One-timeSend once on 16 Jul 09:00
DailyEvery day at 08:00 (daily digest)
WeeklyEvery Monday 09:00 (VIP weekly report)
Monthly1st of every month at 10:00 (monthly summary)
Custom cron0 9 * * 1 — every Monday 09:00

List view

In addition to the calendar, there is a filterable/sortable list view:

FieldFilter options
ChannelEmail, LINE, Push, SMS
StatusScheduled, Sent, Failed, Cancelled
Date rangeScheduled send date
TemplateFilter by template ID
Recipient countLow to high

See Notification API → Scheduler and Mail API → Scheduler for REST endpoints