การย้ายจาก v1
คู่มือนี้จะจับคู่ทุกฟิลด์ของ /create*Message แบบดั้งเดิมกับฟิลด์ที่เทียบเท่าใน Messaging API v2 ใช้เป็นข้อมูลอ้างอิงขณะย้ายการผสานรวมที่มีอยู่
ความแตกต่างในระดับสูง
Anchor link to| แง่มุม | v1 | v2 |
|---|---|---|
| Endpoint ต่อช่องทาง | เมธอดแยกตามช่องทาง (/createMessage, /createEmailMessage, /createSMSMessage, /createKakaoMessage, …) | endpoint เดียว — POST /messaging/v2/notify |
| การยืนยันตัวตน | ฟิลด์ auth ในส่วนเนื้อหาของคำขอ | เฮดเดอร์ Authorization: Token <API_TOKEN> |
| การกำหนดเป้าหมาย | ผสมกัน: filter + conditions + devices + users ในคำขอเดียวกัน | แบ่งชัดเจน: NotifySegment เทียบกับ NotifyTransactional |
| เนื้อหา | content แบบแบน + บล็อกแพลตฟอร์มระดับเดียวกัน | payload.content.localized_content.{locale}.{platform} แบบซ้อนกัน |
| การตอบกลับ | MessageCode[] | message_code + unknown_identifiers ที่เป็นตัวเลือก |
จาก /createMessage
Anchor link toรายการ notifications[*] ของ v1 จะกลายเป็นคำขอ Notify แต่ละรายการ (หนึ่งข้อความต่อรายการ) หากการเรียก v1 มีหลายรายการ ให้ส่งคำขอ Notify หนึ่งรายการต่อหนึ่งรายการ
การตัดสินใจเรื่องการกำหนดเป้าหมาย หากรายการ v1 ใช้ devices หรือ users (รายการที่ระบุชัดเจน) ให้จับคู่กับ transactional มิฉะนั้นให้จับคู่กับ segment
ฟิลด์ระดับคำขอ
Anchor link toapplication→segment.applicationหรือtransactional.application(รูปแบบ app-code เดียวกัน)applications_group: ไม่รองรับใน v2 ใช้คำขอหลายรายการต่อแอปauth: ย้ายไปที่เฮดเดอร์Authorizationไม่อยู่ในส่วนเนื้อหาอีกต่อไปtransactionId→transaction_idซึ่งเป็นฟิลด์ระดับคำขอควบคู่ไปกับsegment/transactionalมีพฤติกรรมการขจัดข้อมูลซ้ำซ้อนเช่นเดียวกับ v1: การเรียกซ้ำด้วยค่าเดียวกันภายใน 5 นาทีจะส่งคืนmessage_codeเดิมแทนที่จะส่งใหม่ โดยจับคู่จากคีย์เพียงอย่างเดียว ไม่ใช่จากเพย์โหลด ดูที่transaction_id
การตั้งเวลา
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ทำซ้ำส่วนเนื้อหาในแต่ละบล็อกแพลตฟอร์มเป้าหมาย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 totemplate_bindings: การผูกเทมเพลต Liquid ไม่มีใน v2 ให้ใช้ v1 ต่อไปหากคุณต้องพึ่งพามัน
บล็อกเฉพาะแพลตฟอร์ม
Anchor link tov1 ยอมรับพารามิเตอร์เฉพาะแพลตฟอร์มที่ระดับบนสุดของแต่ละรายการ notifications[*] (ios, android, safari, chrome, …) ใน v2 พารามิเตอร์เหล่านี้จะย้ายเข้าไปอยู่ในภาษา:
// 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" } } } }}ชื่อฟิลด์ภายในบล็อกแพลตฟอร์มอาจแตกต่างกันในบางที่ ดู การอ้างอิงเพย์โหลด สำหรับชื่อ 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(มีโครงสร้าง)content→payload.content.localized_content.{locale}.{platform}.body- ฟิลด์อื่นๆ ทั้งหมดเหมือนกับ
/createMessageข้างต้น
จาก /createEmailMessage
Anchor link toย้ายไปที่ Notify พร้อมกับ platforms: ["EMAIL"] และบล็อก email_payload การอ้างอิงฉบับเต็ม: การอ้างอิงเพย์โหลดอีเมล
subject→email_payload.subject(แมปที่ใช้ภาษาเป็นคีย์ ห่อหุ้มค่าภาษาเดียวใน{"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 ของแอป แทนที่จะมาจากเนื้อหาของคำขอ
/createSMSMessage ไม่มีรายการที่เทียบเท่ากับ MMS หากต้องการส่ง MMS (หัวเรื่อง + ไฟล์แนบรูปภาพ) ให้ใช้ sms.subject และ sms.file_urls — ดูที่ MMS
จาก /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(พรีเซ็ตทั่วไปที่ระดับเพย์โหลด)- การกำหนดเป้าหมาย: หมายเลขโทรศัพท์ 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(รหัสพรีเซ็ต LINE) →line.templateฟิลด์ v2 จะเก็บรหัสที่อ้างอิงถึงเทมเพลต LINE ที่กำหนดค่าไว้ใน Pushwoosh Control Paneltemplateแบบอินไลน์ (โครงสร้างข้อความรูปภาพ, carousel หรือ flex ของ v1): ไม่รองรับโดยตรงใน v2 กำหนดค่าข้อความ rich message ล่วงหน้าเป็นพรีเซ็ต LINE ใน Control Panel และอ้างอิงผ่านline.template- การกำหนดเป้าหมาย: รายการ
devicesของ v1 (รหัสผู้ใช้ LINE ที่ลงทะเบียนผ่าน SDK //registerDevice) จะกลายเป็นtransactional.users.list(หรือ hwid ผ่านtransactional.hwids.list) ใน v2
ความแตกต่างของการตอบกลับ
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