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, 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

Internal service:

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

→ เรียก 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
  • 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