การย้ายจาก v1
คู่มือนี้จะจับคู่ทุกฟิลด์ของ /create*Message แบบดั้งเดิมกับฟิลด์ที่เทียบเท่าใน Messaging API v2 ใช้เป็นข้อมูลอ้างอิงขณะย้ายการผสานรวมที่มีอยู่
ความแตกต่างในระดับสูง
Anchor link to| แง่มุม | v1 | v2 |
|---|---|---|
| Endpoint ต่อช่องทาง | เมธอดแยกต่อช่องทาง (/createMessage, /createEmailMessage, /createSMSMessage, /createKakaoMessage, …) | endpoint เดียว — POST /messaging/v2/notify |
| Auth | ฟิลด์ auth ใน body ของ request | เฮดเดอร์ Authorization: Token <API_TOKEN> |
| การกำหนดเป้าหมาย | ผสม: filter + conditions + devices + users ใน request เดียวกัน | แบ่งชัดเจน: NotifySegment vs NotifyTransactional |
| เนื้อหา | content แบบแบน + บล็อกแพลตฟอร์มระดับเดียวกัน | payload.content.localized_content.{locale}.{platform} แบบซ้อน |
| Response | MessageCode[] | message_code + unknown_identifiers ที่เป็นทางเลือก |
จาก /createMessage
Anchor link toรายการ v1 notifications[*] จะกลายเป็น request ของ Notify แต่ละรายการ (หนึ่งข้อความต่อรายการ) หากการเรียก v1 มีหลายรายการ ให้ส่ง Notify หนึ่งครั้งต่อหนึ่งรายการ
การตัดสินใจเรื่องการกำหนดเป้าหมาย หากรายการ v1 ใช้ devices หรือ users (รายการที่ระบุชัดเจน) ให้จับคู่กับ transactional มิฉะนั้นให้จับคู่กับ segment
ฟิลด์ระดับ Request
Anchor link toapplication→segment.applicationหรือtransactional.application(รูปแบบ app-code เดียวกัน)applications_group: ไม่รองรับใน v2 ใช้ request หลายรายการต่อแอปauth: ย้ายไปที่เฮดเดอร์Authorizationไม่อยู่ใน body อีกต่อไป
การตั้งเวลา
Anchor link tosend_date("YYYY-MM-DD HH:mm"หรือ"now") →schedule.at(การประทับเวลา RFC 3339 UTC) หากต้องการทำซ้ำ"now"ของ v1 ให้ตั้งค่าschedule.atเป็นเวลาปัจจุบัน การประทับเวลาใดๆ ในอดีตจะถูกส่งทันทีignore_user_timezone→schedule.follow_user_timezoneกลับกัน:ignore_user_timezone: trueจะกลายเป็นfollow_user_timezone: falsetimezone: ไม่รองรับ v2 ใช้ UTC สำหรับatเสมอ แปลงฝั่งไคลเอ็นต์
การกำหนดเป้าหมาย
Anchor link tofilter(ชื่อ segment) →segment.codeconditions([[tag, op, value], ...]) →segment.expressionเขียนใหม่เป็นนิพจน์ seglang ใน seglang,*คือ AND แบบลอจิคัล และแท็กเฉพาะแอปจะถูกอ้างอิงเป็นTag("<application-code>", "<tag>", <op>, <value>)ตัวอย่าง:[["Country","EQ","BR"],["Language","EQ","pt"]]กับconditions_operator: AND→Tag("XXXXX-XXXXX", "Country", EQ, "br") * Tag("XXXXX-XXXXX", "Language", EQ, "pt")conditions_operator(AND/OR): รวมอยู่ในsegment.expressiondevices(hwids หรือ push tokens) →transactional.hwids.listหรือtransactional.push_tokens.listv2 แยกสองอย่างนี้: hwids ไปที่hwids, push tokens ดิบไปที่push_tokensusers→transactional.users.listplatforms(รหัสตัวเลข[1, 3, …]) →segment.platformsหรือtransactional.platforms(enums สตริง["IOS", "ANDROID", …]) ดูที่ Platform enum
เนื้อหา
Anchor link tocontent(สตริง) →payload.content.localized_content.default.{platform}.bodyใน v2 เนื้อหาจะเป็นแบบต่อภาษาและต่อแพลตฟอร์มเสมอ ใส่สตริง v1 ธรรมดาไว้ใต้คีย์พิเศษ"default"(การแปลแบบครอบคลุมทั้งหมด ดูที่ การเลือกภาษาสำหรับอุปกรณ์)content({locale: text}) →payload.content.localized_content.{locale}.{platform}.bodyทำซ้ำ body ในแต่ละบล็อกแพลตฟอร์มเป้าหมายpreset→payload.presetdata→payload.custom_datarich_media→payload.open_action.rich_media.codelink→payload.open_action.link.urlminimize_link(0หรือ2) →payload.open_action.link.shortener(NONEหรือBITLY)inbox_image→payload.content.localized_content.{locale}.{platform}.inbox.image_url(แต่ละบล็อกแพลตฟอร์มมีinboxของตัวเอง)inbox_date→payload.content.localized_content.{locale}.{platform}.inbox.expiration_dateinbox_days: ไม่รองรับ แปลงเป็นexpiration_dateแบบสมบูรณ์ฝั่งไคลเอ็นต์
การควบคุมการส่ง
Anchor link todynamic_content/dynamic_content_placeholders→dynamic_content_placeholdersบนsegmentหรือtransactionalcampaign→campaignบนsegmentหรือtransactionalcapping_days→frequency_capping.dayscapping_count→frequency_capping.countsend_rate(int) →send_rate.valueกับsend_rate.bucket: "1s"message_type("marketing"/"transactional") →message_type(MESSAGE_TYPE_MARKETING/MESSAGE_TYPE_TRANSACTIONAL)
ไม่รองรับใน v2
Anchor link totransactionId: ไม่มีตัวเทียบเท่าโดยตรง ติดตามความสัมพันธ์ฝั่งของคุณtemplate_bindings: การผูกเทมเพลต Liquid ไม่มีใน v2 ใช้ v1 ต่อไปหากคุณต้องใช้ฟีเจอร์นี้
บล็อกเฉพาะแพลตฟอร์ม
Anchor link tov1 ยอมรับพารามิเตอร์เฉพาะแพลตฟอร์มที่ระดับบนสุดของแต่ละรายการ notifications[*] (ios, android, safari, chrome, …) ใน v2 พารามิเตอร์เหล่านี้จะย้ายเข้าไปอยู่ใน locale:
// v1"notifications": [{ "content": "Hello", "ios": { "title": "Hi", "sound": "default.caf" }, "android": { "header": "Hi", "led": "#ff0000" }}]
// v2"payload": { "content": { "localized_content": { "en": { "ios": { "title": "Hi", "body": "Hello", "sound": "default.caf" }, "android": { "title": "Hi", "body": "Hello", "led_color": "#ff0000" } } } }}ชื่อฟิลด์ภายในบล็อกแพลตฟอร์มอาจแตกต่างกันในบางที่ ดู การอ้างอิง Payload สำหรับชื่อ v2 ที่ถูกต้อง
ตัวอย่าง: ก่อนและหลัง
Anchor link tov1 /createMessage (พุชไปยัง segment):
{ "request": { "application": "XXXXX-XXXXX", "auth": "YOUR_API_TOKEN", "notifications": [{ "send_date": "2026-05-01 12:00", "content": "Hello!", "platforms": [1, 3], "filter": "active_users", "campaign": "YYYYY-YYYYY", "capping_days": 7, "capping_count": 3, "message_type": "marketing" }] }}v2 /messaging/v2/notify:
{ "segment": { "application": "XXXXX-XXXXX", "platforms": ["IOS", "ANDROID"], "code": "active_users", "payload": { "content": { "localized_content": { "en": { "ios": { "body": "Hello!" }, "android": { "body": "Hello!" } } } } }, "schedule": { "at": "2026-05-01T12:00:00Z" }, "frequency_capping": { "days": 7, "count": 3 }, "campaign": "YYYYY-YYYYY", "message_type": "MESSAGE_TYPE_MARKETING" }}จาก /createTargetedMessage
Anchor link to/createTargetedMessage จับคู่กับ transactional ในกรณีส่วนใหญ่ หรือกับ segment หากคุณใช้เป็น devices_filter ข้ามแอปโดยไม่มีตัวระบุที่ชัดเจน
devices_filter→segment.expression(seglang) หรือsegment.filter_expression(structured)content→payload.content.localized_content.{locale}.{platform}.body- ฟิลด์อื่นๆ ทั้งหมด เหมือนกับ
/createMessageข้างต้น
จาก /createEmailMessage
Anchor link toย้ายไปที่ Notify ด้วย platforms: ["EMAIL"] และบล็อก email_payload การอ้างอิงฉบับเต็ม: การอ้างอิง Email payload
subject→email_payload.subject(map ที่ใช้ locale เป็นคีย์ ห่อค่าภาษาเดียวใน{"en": "..."})content(HTML) →email_payload.bodyemail_template→email_payload.email_templatefrom/from_name→email_payload.from({ "name": "...", "email": "..." })reply_to/reply_to_name→email_payload.reply_tolist_unsubscribe→email_payload.list_unsubscribeattachments→email_payload.attachments([{ "name": "...", "content": "<base64>" }])- การกำหนดเป้าหมาย, การตั้งเวลา, แคมเปญ, ฯลฯ เหมือนกับ
/createMessage
จาก /createSMSMessage
Anchor link toย้ายไปที่ Notify ด้วย platforms: ["SMS"] เนื้อหา SMS จะถูกส่งผ่านผู้ให้บริการ SMS ที่กำหนดค่าไว้ในแอป ใส่เนื้อหาใน payload.content.localized_content.{locale}.{platform}.body บนบล็อกแพลตฟอร์มใดๆ ที่กรอกข้อมูลไว้
ตัวเลือกผู้ให้บริการเฉพาะสำหรับ SMS (รหัสผู้ส่ง ฯลฯ) ยังคงมาจากการตั้งค่า SMS ของแอป แทนที่จะมาจาก body ของ request
จาก /createKakaoMessage
Anchor link toย้ายไปที่ Notify ด้วย platforms: ["KAKAO"] โดยใช้ payload.content.localized_content.{locale}.kakao:
template_id→kakao.templatecontent→kakao.contentvariables→kakao.content_variables(แปลงเป็นสตริง JSON)
จาก /createWhatsAppMessage
Anchor link toย้ายไปที่ Notify ด้วย platforms: ["WHATS_APP"] โดยใช้ payload.content.localized_content.{locale}.whatsapp:
content(ข้อความอิสระ) →whatsapp.contentส่งโดย Meta เฉพาะภายในกรอบเวลาบริการลูกค้า 24 ชั่วโมงcontent_id→whatsapp.content_idชื่อของเทมเพลต Meta ที่ได้รับการอนุมัติล่วงหน้าlanguage→whatsapp.languageภาษาของเทมเพลต Meta (เช่น"en_US") ไม่ขึ้นกับคีย์ภาษาของLocalizedContentภายนอกcontent_variables(อ็อบเจกต์ใน v1) →whatsapp.content_variables(อ็อบเจกต์ที่แปลงเป็นสตริง JSON) ตัวอย่าง v1{"1": "John"}จะกลายเป็น v2"{\"1\":\"John\"}"button_url_variables(อ็อบเจกต์) →whatsapp.button_url_variables(แปลงเป็นสตริง JSON)header_variables(อ็อบเจกต์) →whatsapp.header_variables(แปลงเป็นสตริง JSON)preset→payload.preset(preset ทั่วไปที่ระดับ payload)- การกำหนดเป้าหมาย: หมายเลขโทรศัพท์ WhatsApp ที่ใน v1 อยู่ใน
devices(เช่น"whatsapp:+1234567890") จะต้องลงทะเบียนผ่าน/registerDeviceกับผู้ใช้ ใน v2 กำหนดเป้าหมายผู้ใช้ผลลัพธ์ด้วยtransactional.users.list(หรือ hwid ผ่านtransactional.hwids.list) use_auto_registration: ไม่รองรับ ลงทะเบียนหมายเลข WhatsApp ก่อนส่ง
จาก /createLineMessage
Anchor link toย้ายไปที่ Notify ด้วย platforms: ["LINE"] โดยใช้ payload.content.localized_content.{locale}.line:
content(ข้อความธรรมดา) →line.contentpreset(รหัส preset ของ LINE) →line.templateฟิลด์ v2 จะเก็บรหัสที่อ้างอิงถึงเทมเพลต LINE ที่กำหนดค่าไว้ใน Pushwoosh Control Paneltemplateแบบอินไลน์ (โครงสร้างข้อความรูปภาพ, carousel หรือ flex ของ v1): ไม่รองรับโดยตรงใน v2 กำหนดค่า rich message ล่วงหน้าเป็น preset ของ LINE ใน Control Panel และอ้างอิงผ่านline.template- การกำหนดเป้าหมาย: รายการ
devicesของ v1 (LINE user IDs ที่ลงทะเบียนผ่าน SDK //registerDevice) จะกลายเป็นtransactional.users.list(หรือ hwid ผ่านtransactional.hwids.list) ใน v2
ความแตกต่างของ Response
Anchor link tov1 /createMessage ส่งคืน:
{ "status_code": 200, "status_message": "OK", "response": { "Messages": ["XXXXX-XXXXX-AAAAA"] }}v2 Notify ส่งคืน:
{ "result": { "message_code": "XXXXX-XXXXX-AAAAA", "unknown_identifiers": [] }}การตอบกลับที่ไม่ใช่ 200 จะเป็นไปตามรูปแบบข้อผิดพลาดมาตรฐานของ gRPC-Gateway ({ "code": ..., "message": ..., "details": [...] }) แทนที่จะเป็นคู่ status_code / status_message ของ v1