กลับไปยังคู่มือ

คู่มือ Push API (Sender Token)

ภาพรวม

ใช้ Sender Token เพื่อส่งการแจ้งเตือนผ่าน API ของระบบหลังบ้าน (ควรใช้ฝั่งเซิร์ฟเวอร์เท่านั้น และเก็บโทเค็นนี้เป็นความลับ)

อัปเดต 11 กันยายน 2569: คู่มือนี้ครอบคลุม Plain, Targeted, Markdown และ Interactive Action ตามสัญญา API ปัจจุบัน

Endpoint

POST https://notipush.app/api/send-push

รายละเอียด Payload

Key ความหมาย
sender_token
String (Required)
Sender Token ที่ได้จากแอป (เก็บเป็นความลับ); ระบบเก่ายังส่งชื่อ receiver_token ได้ แต่ควรใช้ชื่อนี้
title
String (Required)
หัวข้อของการแจ้งเตือน
body
String (Required)
ข้อความสำรองแบบ Plain ที่ต้องส่งเสมอ แม้ใช้ Markdown เพื่อให้ Receiver รุ่นเก่าแสดงผลได้
content_type
String (Optional)
ชนิดเนื้อหา: plain (ค่าเริ่มต้น) หรือ markdown ห้ามใช้ HTML
body_markdown
String (Conditional)
Markdown ที่จะแสดงบน Receiver เมื่อ content_type=markdown; ต้องไม่ว่าง และไม่รองรับ HTML, WebView หรือ JavaScript
actions
Array (Conditional)
ปุ่มตอบกลับไม่เกิน 3 ปุ่ม ดูกติกาในหัวข้อ Interactive Action; ถ้าไม่ต้องการปุ่มให้ละ field นี้
request_id
String (Conditional)
รหัสคำขอของระบบคุณ ต้องมีเมื่อส่ง actions และห้ามซ้ำภายใน Sender เดียวกัน
expires_at
ISO-8601 (Conditional)
เวลาหมดอายุของ action ต้องอยู่ในอนาคตและไม่เกิน 24 ชั่วโมงจากเวลาที่รับคำขอ
target_id
String (Optional)
Target เดียวแบบเดิม ใช้ได้กับ Push ทั่วไป และต้องใช้ field นี้ (ไม่ใช่ target_ids) เมื่อมี Interactive Action
target_ids
Array (Optional)
ระบุ Target หลายค่าในรูปแบบ array; ถ้าไม่ใส่จะเป็น Broadcast และห้ามใช้ร่วมกับ Interactive Action
data.custom_tag
String (Optional)
แท็กที่กำหนดเองสำหรับให้ Receiver แยกการ์ดหรือกรองข้อความ เช่น attendance, billing, homework
data.*
Object (Optional)
ข้อมูลเพิ่มเติมของระบบคุณ ทุกค่าจะถูกแปลงเป็น String; หลีกเลี่ยงชื่อที่ขึ้นต้นด้วย _ ซึ่งสงวนไว้สำหรับ metadata ของ NotiPush

ตัวอย่าง


        

การตอบกลับ

ตัวอย่าง Response เมื่อ Firebase พร้อมใช้งาน

{
  "ok": true,
  "successCount": 1,
  "failureCount": 0
}
ถ้าไม่มี Receiver ที่ตรง Target ระบบจะตอบ sent=0; ถ้า Firebase ยังไม่พร้อมแต่มี Receiver ระบบจะตอบ simulated=true พร้อมจำนวนอุปกรณ์ใน sent. ข้อความ Markdown/Interactive จะมี message_id ทั้งสองกรณี
{
  "ok": true,
  "simulated": true,
  "sent": 1,
  "message_id": "message-uuid-for-rich-message"
}

สำหรับข้อความ Rich ในโหมด Firebase ค่า message_id จะอยู่ใน metadata ของ FCM เพื่อให้ Receiver ดึงรายละเอียดจาก Backend; ผู้เรียก API ควรใช้ค่า success/failure เป็นผลการส่งหลัก

การตอบกลับกรณีเกิดข้อผิดพลาด

รหัสสถานะ ความหมาย รายละเอียดเพิ่มเติม
400 คำขอไม่ถูกต้อง ขาด sender_token, title หรือ body; หรือ field ของ Markdown/Action ไม่ถูกต้อง
403 ถูกปฏิเสธ sender_token ไม่ถูกต้อง, plan หมดอายุ, ใช้โควตารายวันครบ, demo ถูกปิด หรือเนื้อหาถูกบล็อก
409 ขัดแย้ง request_id ซ้ำภายใน Sender เดิม (duplicate_request_id)
413 Payload ใหญ่เกินไป ระบบลดขนาดแล้วแต่ยังเกินขีดจำกัด FCM 4096 bytes (payload_too_large)
422 ข้อมูลไม่สมบูรณ์ พบข้อความซ้ำภายใน 5 วินาที (duplicate_message)
429 ส่งคำขอบ่อยเกินไป เกิน limit ต่อวินาทีของแผน (too_many_requests)
500 ข้อผิดพลาดเซิร์ฟเวอร์ ฐานข้อมูล, Firebase หรือระบบภายในผิดพลาด (fcm_error หรือ server_error)

Markdown และ Interactive Action

ข้อความ Markdown ใช้ได้กับ Sender ทุก policy โดยต้องส่ง body แบบ Plain เป็น fallback เสมอ ส่วนปุ่ม Interactive ใช้ได้เฉพาะ Sender ที่ตั้งเป็น verified_target และต้องยืนยัน Target ก่อน

ตัวอย่าง Interactive Push

curl -X POST "https://notipush.app/api/send-push" \
     -H "Content-Type: application/json" \
     -d '{
           "sender_token": "YOUR_SENDER_TOKEN",
           "title": "ยืนยันรายการ",
           "body": "กรุณาเปิดแอปเพื่อยืนยันรายการ",
           "content_type": "markdown",
           "body_markdown": "**รายละเอียดรายการ**\n\nยอดรวม: **1,000 บาท**",
           "target_id": "TARGET_ID",
           "request_id": "REQUEST_ID",
           "expires_at": "EXPIRY_ISO8601_WITHIN_24_HOURS",
           "actions": [
             { "id": "approve", "label": "อนุมัติ", "style": "primary" },
             { "id": "deny", "label": "ปฏิเสธ", "style": "danger" }
           ],
           "data": { "custom_tag": "billing" }
         }'
กติกา รายละเอียด
content_type ใช้ plain (ค่าเริ่มต้น) หรือ markdown; ไม่รองรับ html, WebView หรือ JavaScript
actions มีได้ไม่เกิน 3 รายการ และแต่ละรายการต้องมี id (A-Z, a-z, 0-9, underscore หรือ hyphen), label 1–80 ตัวอักษร และ style เป็น primary, secondary, success หรือ danger
target_id Interactive ต้องใช้ Target เดียวผ่าน field นี้เท่านั้น; ใช้ target_ids หรือค่าที่มี comma จะถูกปฏิเสธ
request_id ต้องมีเมื่อมี action และต้องไม่ซ้ำภายใน Sender เดิม; ซ้ำแล้วตอบ 409 duplicate_request_id โดยไม่ส่งซ้ำ
expires_at ต้องมีเมื่อมี action เป็นเวลา ISO-8601 ที่อยู่ในอนาคตและไม่เกิน 24 ชั่วโมง; เมื่อหมดอายุ Receiver จะกด action ไม่ได้
Backend ส่งเฉพาะ metadata ขนาดเล็กผ่าน FCM ส่วน Markdown และ actions จะถูกดึงจาก Backend เมื่อ Receiver มี binding ที่ถูกต้อง จึงไม่ควรใส่ข้อมูลลับใน body, body_markdown หรือ data
การดึงรายละเอียด Rich และการส่ง Action จัดการโดยแอป NotiPush Receiver อัตโนมัติ ผู้ใช้ API ภายนอกไม่ต้องเรียกหรือสร้าง Receiver เอง

Verified Target และ Webhook

หากใช้ actions ระบบ Sender ต้องตั้งค่า verification URL, action webhook URL และ secret ผ่านหน้า Sender Integration ก่อนเปิดใช้ verified_target โดย URL ต้องเป็น HTTPS port 443 และห้ามมี redirect ไปยัง private address

Verification callback

เมื่อ Receiver ลงทะเบียน Target แบบ protected ระบบจะส่ง signed POST ไปยัง verification URL ของคุณ ให้ตอบ JSON นี้เมื่อรหัสถูกต้องและ Target ผูกกับผู้ใช้ของคุณแล้ว

POST https://YOUR_INTEGRATION_HOST/notipush/verify
X-NotiPush-Event-ID: EVENT_UUID
X-NotiPush-Timestamp: UNIX_TIMESTAMP
X-NotiPush-Signature: v1=HMAC_SHA256_HEX

{
  "event_id": "EVENT_UUID",
  "type": "subscription.verify",
  "sender_id": "SENDER_UUID",
  "notify_token": "NOTIFY_TOKEN_UUID",
  "target_id": "TARGET_ID",
  "verification_code": "ONE_TIME_CODE",
  "receiver_install_id": "INSTALL_UUID",
  "platform": "android",
  "timestamp": "2026-09-11T00:00:00.000Z"
}

HTTP 200
{ "verified": true, "external_subject_id": "EXTERNAL_SUBJECT_ID" }

Action webhook

เมื่อ Receiver กด action ระบบจะบันทึก event ก่อน แล้วส่ง signed POST ไปยัง action webhook แบบ asynchronous; endpoint ของคุณต้องใช้ event_id ทำ idempotency

POST https://YOUR_INTEGRATION_HOST/notipush/action
X-NotiPush-Event-ID: EVENT_UUID
X-NotiPush-Timestamp: UNIX_TIMESTAMP
X-NotiPush-Signature: v1=HMAC_SHA256_HEX

{
  "event_id": "EVENT_UUID",
  "type": "notification.action",
  "sender_id": "SENDER_UUID",
  "message_id": "MESSAGE_UUID",
  "request_id": "REQUEST_ID",
  "action_id": "approve",
  "target_id": "TARGET_ID",
  "external_subject_id": "EXTERNAL_SUBJECT_ID",
  "receiver_install_id": "INSTALL_UUID",
  "responded_at": "2026-09-11T00:00:00.000Z"
}

ตรวจลายเซ็นด้วย HMAC-SHA256 บนค่า UNIX_TIMESTAMP + '.' + raw JSON body และยอมรับเฉพาะ timestamp ที่อยู่ในหน้าต่างเวลาที่ระบบของคุณกำหนด

Retry ของ action webhook: 5 วินาที, 30 วินาที, 2 นาที, 10 นาที และ 30 นาที; ทุกครั้งใช้ event_id เดิม 2xx ถือว่าสำเร็จ ส่วน 4xx ที่ไม่ใช่ 408/425/429 จะจบเป็น failed

ถอนสิทธิ์ Target ผ่าน API

ใช้ endpoint นี้จากระบบของคุณเมื่อ Target ไม่ควรรับแจ้งเตือนอีกต่อไป เช่น เปลี่ยนผู้ใช้หรือยกเลิกสิทธิ์ ระบบจะ revoke เฉพาะ verified subscription ของ Target นั้น และไม่ลบประวัติ

POST https://notipush.app/api/sender/targets/revoke
curl -X POST "https://notipush.app/api/sender/targets/revoke" \
     -H "Content-Type: application/json" \
     -d '{
           "sender_token": "YOUR_SENDER_TOKEN",
           "target_id": "TARGET_ID"
         }'
{ "ok": true, "revoked_count": 1 }

ต้องส่ง Target เดียวเท่านั้น (ห้าม comma หรือ array) และ endpoint นี้ใช้ Sender Token จึงควรเรียกจาก server ของคุณเท่านั้น

สร้าง QR Code จากลิงก์

นำลิงก์ที่สร้างด้านบนไปสร้าง QR Code ด้วยเว็บไซต์ หรือ Library ในภาษาโปรแกรมของคุณ ไม่มี endpoint สำหรับสร้าง QR Code บนเซิร์ฟเวอร์ ผู้รับสแกน QR Code แล้วจะเปิดแอป Receiver พร้อมลงทะเบียนอัตโนมัติ

ตัวอย่าง: สร้าง QR Code ด้วย Python

import qrcode

notify_token = "YOUR_NOTIFY_TOKEN"
target_id = "room-101"  # Optional

url = f"https://notipush.app/r/?t={notify_token}&tg={target_id}"
img = qrcode.make(url)
img.save("notipush_qr.png")
print(f"QR Code saved: {url}")

ตัวอย่าง: สร้าง QR Code ด้วย JavaScript (Node.js)

const QRCode = require('qrcode');

const notifyToken = "YOUR_NOTIFY_TOKEN";
const targetId = "room-101"; // Optional

const url = `https://notipush.app/r/?t=${notifyToken}&tg=${targetId}`;
QRCode.toFile('notipush_qr.png', url, (err) => {
  if (err) throw err;
  console.log(`QR Code saved: ${url}`);
});
คุณสามารถสร้าง QR Code แบบ Dynamic ได้ — เช่น พิมพ์ QR คนละใบสำหรับลูกค้าแต่ละราย หรือวางไว้ตามห้องต่างๆ ในอาคาร โดยเปลี่ยน Target ID ให้แตกต่างกัน

การใช้ Target ID (ส่งเจาะจงอุปกรณ์/กลุ่ม)

Target ID คือค่าที่ระบบของคุณ (Sender) เป็นคนกำหนดขึ้นมา ฝังไว้ในลิงก์หรือ QR Code ตอนที่ผู้รับลงทะเบียน เมื่อจำเป็นต้องส่งแจ้งเตือนเจาะจง คุณระบุ target_id ใน API call แล้วเฉพาะอุปกรณ์ที่ลงทะเบียนด้วย ID นั้นเท่านั้นที่จะได้รับ

Push ทั่วไปหรือ Markdown ที่ไม่มีปุ่มใช้ target_id สำหรับ Target เดียว หรือ target_ids สำหรับหลาย Target; ไม่ใส่ทั้งสอง field คือ Broadcast. Interactive Action ต้องใช้ target_id เดียวเท่านั้น

ขั้นตอนการใช้งาน

1
Sender กำหนด Target ID

ออกแบบ Target ID ตามโครงสร้างของระบบคุณ เช่น รหัสลูกค้า, ชื่อห้อง, แผนก, สาขา เป็นต้น

2
สร้าง Link / QR Code พร้อม Target ID

ใส่ Target ID ลงในลิงก์ แล้วสร้าง QR Code หรือส่งลิงก์ให้ผู้รับ

3
ผู้รับสแกน QR / กดลิงก์

แอป Receiver จะลงทะเบียนพร้อมผูก Target ID ไว้กับอุปกรณ์โดยอัตโนมัติ

4
ส่ง Push เจาะจงด้วย target_id

เรียก API พร้อมใส่ target_id จะส่งเฉพาะอุปกรณ์ที่ลงทะเบียนด้วย ID นั้น ถ้าไม่ใส่จะส่งหาทุกคน (Broadcast)

ตัวอย่างการใช้งานจริง

สถานการณ์ Target ID ลิงก์ตัวอย่าง
🏨 แจ้งเตือนเฉพาะห้อง room-101 .../r/?t=TOKEN&tg=room-101
👤 แจ้งเตือนลูกค้ารายบุคคล cust-5678 .../r/?t=TOKEN&tg=cust-5678
🏢 แจ้งเตือนเฉพาะแผนก dept-sales .../r/?t=TOKEN&tg=dept-sales
🏪 แจ้งเตือนเฉพาะสาขา branch-bkk01 .../r/?t=TOKEN&tg=branch-bkk01
📢 ส่งทุกคน (Broadcast) ไม่ต้องใส่ .../r/?t=TOKEN

ตัวอย่าง API: ส่งหาเป้าหมายเดียว

curl -X POST "https://notipush.app/api/send-push" \
     -H "Content-Type: application/json" \
     -d '{
           "sender_token": "YOUR_SENDER_TOKEN",
           "title": "ห้อง 101 — อาหารพร้อมเสิร์ฟ",
           "body": "กรุณามารับที่เคาน์เตอร์ชั้น 1",
           "target_ids": ["room-101"]
         }'

ตัวอย่าง API: ส่งหาหลายเป้าหมาย

curl -X POST "https://notipush.app/api/send-push" \
     -H "Content-Type: application/json" \
     -d '{
           "sender_token": "YOUR_SENDER_TOKEN",
           "title": "แจ้งเตือนฉุกเฉิน",
           "body": "กรุณาอพยพออกจากอาคารทันที",
           "target_ids": ["floor-1", "floor-2", "emergency"]
         }'

💡 ไม่ใส่ target_ids = ส่งหาทุกคนที่ติดตามช่องนี้ (Broadcast)  |  ใส่ target_ids = ส่งหาอุปกรณ์ที่ลงทะเบียนด้วย ID ใดๆ ในรายการ (array มีค่าเดียวก็ได้สำหรับเป้าหมายเดียว)

สิ่งที่ระบบของ Sender ต้องเตรียม:
1. กำหนดรูปแบบ Target ID ให้ชัดเจน (เช่น room-{หมายเลข}, cust-{รหัส})
2. สร้าง Link/QR Code โดยใส่ tg=TARGET_ID ที่แตกต่างกันสำหรับแต่ละอุปกรณ์หรือกลุ่ม
3. บันทึก Mapping ของ Target ID ↔ ลูกค้า/ห้อง/กลุ่ม ไว้ในระบบของคุณ
4. เมื่อต้องการส่ง Push ให้ระบุ target_ids ใน API call ตาม Mapping ที่เก็บไว้