การดู SDK ของ Engage: คำแนะนำการผสานรวมทางเทคนิคของบุคคลที่สาม

เพิ่มการมีส่วนร่วมในแอปโดยการเข้าถึงผู้ใช้ในทุกที่ที่ผู้ใช้อยู่ ผสานรวม Engage SDK เพื่อแสดงเนื้อหา "รับชมต่อ" และคำแนะนำที่ปรับเปลี่ยนในแบบของคุณแก่ผู้ใช้โดยตรงในแพลตฟอร์มต่างๆ ในอุปกรณ์ เช่น คอลเล็กชัน, Entertainment Space และ Play Store การผสานรวมนี้จะเพิ่มขนาด APK โดยเฉลี่ยไม่ถึง 50 KB (บีบอัดแล้ว) และใช้เวลาของนักพัฒนาแอปประมาณ 1 สัปดาห์สำหรับแอปส่วนใหญ่ ดูข้อมูลเพิ่มเติมได้ที่เว็บไซต์ธุรกิจของเรา

คู่มือนี้มีวิธีการสำหรับพาร์ทเนอร์นักพัฒนาแอปในการผสานรวมเนื้อหาวิดีโอ โดยใช้ Engage SDK เพื่อสร้างทั้งพื้นที่แสดงผลใหม่นี้และแพลตฟอร์ม Google ที่มีอยู่

การรองรับหมวดหมู่และแพลตฟอร์ม

การมีสิทธิ์ใช้แพลตฟอร์ม Engage SDK ขึ้นอยู่กับหมวดหมู่เนื้อหาของแอป ใช้ตารางต่อไปนี้เพื่อพิจารณาสิทธิ์ของคุณสำหรับแพลตฟอร์มที่เฉพาะเจาะจง

สถานะ หมวดหมู่เนื้อหาหรือกรณีการใช้งาน แพลตฟอร์มที่รองรับ
รองรับ
(มีสิทธิ์แสดงในทุกแพลตฟอร์ม)
  • สตรีมมิงภาพยนตร์และทีวี
  • รายการทีวีสด / กีฬา
  • วิดีโอคลิปแบบออนดีมานด์
  • วิดีโอกีฬา
  • ละครสั้น
  • วิดีโอพอดแคสต์
  • คอลเล็กชัน
  • Entertainment Space
  • แท็บแอปใน Play Store
  • แท็บ "คุณ" ใน Play Store
  • หน้าข้อมูลสินค้าใน Store ของ Play Store
รองรับบางส่วน
(มีสิทธิ์ในบางแพลตฟอร์ม)
  • วิดีโอคลิปจากแอปข่าว
  • คอลเล็กชัน
  • Entertainment Space
สิ่งที่ทำไม่ได้
  • รีโมตคอนโทรล
  • โปรแกรมดาวน์โหลด โปรแกรมเล่น และโปรแกรมตัดต่อวิดีโอ
  • รีวิวภาพยนตร์และรายการทีวี
  • ตั๋วภาพยนตร์
  • แนะนำรายการทีวี
  • วิดีโอคอลและห้องแชท

รายละเอียดการผสานรวม

ส่วนนี้จะอธิบายขั้นตอน โมเดลข้อมูล และคำศัพท์ที่จำเป็นในการผสานรวมกับ Engage SDK สำหรับเนื้อหาวิดีโอ

คำศัพท์

การผสานรวมนี้ประกอบด้วยคลัสเตอร์ 3 ประเภท ได้แก่ วิดีโอแนะนำ ดูต่อ และแนะนำ

  • คลัสเตอร์วิดีโอแนะนำจะแสดงคำแนะนำเนื้อหาที่ปรับเปลี่ยนในแบบของคุณให้รับชมจากพาร์ทเนอร์นักพัฒนาแอปแต่ละราย

    คำแนะนำจะมีโครงสร้างดังต่อไปนี้

    • คลัสเตอร์วิดีโอแนะนำ: มุมมอง UI ที่มีกลุ่มวิดีโอแนะนำจากพาร์ทเนอร์นักพัฒนาแอปรายเดียวกัน

      รูปที่ 1 UI ของ Entertainment Space ที่แสดงคลัสเตอร์วิดีโอแนะนำจากพาร์ทเนอร์รายเดียว
    • เอนทิตี: ออบเจ็กต์ที่แสดงรายการเดียวในคลัสเตอร์ เอนทิตีอาจเป็นภาพยนตร์ รายการทีวี ซีรีส์ วิดีโอสด และอื่นๆ ดูรายการประเภทเอนทิตีที่รองรับได้ในส่วนระบุข้อมูลเอนทิตี

      รูปที่ 2 UI ของ Entertainment Space แสดงเอนทิตีเดียวภายในคลัสเตอร์วิดีโอแนะนำของพาร์ทเนอร์รายเดียว
  • คลัสเตอร์ความต่อเนื่องจะแสดงวิดีโอที่ดูค้างไว้และตอนที่เพิ่งเผยแพร่ใหม่ที่เกี่ยวข้องจากพาร์ทเนอร์นักพัฒนาแอปหลายรายในการจัดกลุ่ม UI เดียว พาร์ทเนอร์นักพัฒนาแอปแต่ละรายจะได้รับอนุญาตให้ออกอากาศเอนทิตีได้สูงสุด 10 รายการในคลัสเตอร์ความต่อเนื่อง การวิจัยแสดงให้เห็นว่าคำแนะนำที่ปรับเปลี่ยนในแบบของคุณ รวมถึงเนื้อหาที่ต่อเนื่องซึ่งปรับเปลี่ยนในแบบของคุณสร้างการมีส่วนร่วมของผู้ใช้ได้ดีที่สุด

    รูปที่ 3 UI ของ Entertainment Space แสดงคลัสเตอร์ความต่อเนื่องพร้อมวิดีโอแนะนำที่ดูค้างไว้จากพาร์ทเนอร์หลายราย (ปัจจุบันแสดงวิดีโอแนะนำเพียงรายการเดียว)
  • คลัสเตอร์แนะนำจะแสดงเอนทิตีที่เลือกจากพาร์ทเนอร์นักพัฒนาแอปหลายรายในการจัดกลุ่ม UI เดียว จะมีคลัสเตอร์แนะนำเพียงคลัสเตอร์เดียว ซึ่งจะแสดงใกล้กับด้านบนของ UI โดยมีตำแหน่งที่มีลำดับความสำคัญสูงกว่าคลัสเตอร์วิดีโอแนะนำทั้งหมด พาร์ทเนอร์นักพัฒนาแอปแต่ละรายจะได้รับอนุญาตให้ออกอากาศเอนทิตีได้สูงสุด 10 รายการในคลัสเตอร์แนะนำ

    รูปที่ 4 UI ของ Entertainment Space แสดงคลัสเตอร์แนะนำพร้อมคำแนะนำจากพาร์ทเนอร์หลายราย (ปัจจุบันมองเห็นคำแนะนำเพียงรายการเดียว)

สิ่งที่ต้องเตรียมก่อนดำเนินการ

ระดับ API ขั้นต่ำ: 19

เพิ่มไลบรารี com.google.android.engage:engage-core ลงในแอปโดยทำดังนี้

dependencies {
    // Make sure you also include that repository in your project's build.gradle file.
    implementation 'com.google.android.engage:engage-core:1.6.0'
}

ดูข้อมูลเพิ่มเติมได้ที่ระดับการมองเห็นแพ็กเกจใน Android 11

สรุป

การออกแบบนี้อิงตามการใช้งานบริการที่มีผลผูกพัน

ข้อมูลที่ไคลเอ็นต์เผยแพร่ได้จะขึ้นอยู่กับขีดจำกัดต่อไปนี้สำหรับคลัสเตอร์ประเภทต่างๆ

ประเภทคลัสเตอร์ ขีดจำกัดของคลัสเตอร์ ขีดจำกัดเอนทิตีสูงสุดในคลัสเตอร์
คลัสเตอร์วิดีโอแนะนำ ไม่เกิน 7 รายการ ไม่เกิน 50 รายการ
คลัสเตอร์ความต่อเนื่อง ไม่เกิน 1 รายการ ไม่เกิน 20 รายการ
คลัสเตอร์แนะนำ ไม่เกิน 1 รายการ ไม่เกิน 20 รายการ

ขั้นตอนที่ 0: การย้ายข้อมูลจากการผสานรวม Media Home SDK ที่มีอยู่

ส่วนนี้จะอธิบายวิธีย้ายข้อมูลโมเดลข้อมูล Media Home SDK และการเรียก API ที่มีอยู่ไปยัง Engage SDK

แมปโมเดลข้อมูลจากการผสานรวมที่มีอยู่

หากคุณย้ายข้อมูลจากการผสานรวม Media Home ที่มีอยู่ ตารางต่อไปนี้จะสรุปวิธีแมปโมเดลข้อมูลใน SDK ที่มีอยู่กับ Engage SDK ใหม่

เทียบเท่ากับการผสานรวม MediaHomeVideoContract เทียบเท่ากับการผสานรวม Engage SDK
com.google.android.mediahome.video.PreviewChannel com.google.android.engage.common.datamodel.RecommendationCluster
com.google.android.mediahome.video.PreviewChannel.Builder com.google.android.engage.common.datamodel.RecommendationCluster.Builder
com.google.android.mediahome.video.PreviewChannelHelper com.google.android.engage.video.service.AppEngageVideoClient
com.google.android.mediahome.video.PreviewProgram แบ่งออกเป็นชั้นเรียนต่างๆ ได้แก่ EventVideo, LiveStreamingVideo, Movie, TvEpisode, TvSeason, TvShow, VideoClipEntity
com.google.android.mediahome.video.PreviewProgram.Builder แบ่งออกเป็นเครื่องมือสร้างในคลาสแยกต่างหาก ได้แก่ EventVideo, LiveStreamingVideo, Movie, TvEpisode, TvSeason, TvShow, VideoClipEntity
com.google.android.mediahome.video.VideoContract ไม่จำเป็นต้องใช้อีกแล้ว
com.google.android.mediahome.video.WatchNextProgram แบ่งออกเป็นแอตทริบิวต์ในคลาสแยกต่างหาก ได้แก่ EventVideoEntity, LiveStreamingVideoEntity, MovieEntity, TvEpisodeEntity, TvSeasonEntity, TvShowEntity, VideoClipEntity
com.google.android.mediahome.video.WatchNextProgram.Builder แบ่งออกเป็นแอตทริบิวต์ในคลาสแยกต่างหาก ได้แก่ EventVideoEntity, LiveStreamingVideoEntity, MovieEntity, TvEpisodeEntity, TvSeasonEntity, TvShowEntity, VideoClipEntity

การเผยแพร่คลัสเตอร์ใน Media Home SDK เทียบกับ Engage SDK

เมื่อใช้ Media Home SDK ระบบจะเผยแพร่คลัสเตอร์และเอนทิตีผ่าน API แยกกัน ดังนี้

// 1. Fetch existing channels
List<PreviewChannel> channels = PreviewChannelHelper.getAllChannels();

// 2. If there are no channels, publish new channels
long channelId = PreviewChannelHelper.publishChannel(builder.build());

// 3. If there are existing channels, decide whether to update channel contents
PreviewChannelHelper.updatePreviewChannel(channelId, builder.build());

// 4. Delete all programs in the channel
PreviewChannelHelper.deleteAllPreviewProgramsByChannelId(channelId);

// 5. publish new programs in the channel
PreviewChannelHelper.publishPreviewProgram(builder.build());

เมื่อใช้ Engage SDK การเผยแพร่คลัสเตอร์และเอนทิตีจะรวมอยู่ในการเรียก API เดียว เอนทิตีทั้งหมดที่อยู่ในคลัสเตอร์จะเผยแพร่พร้อมกับคลัสเตอร์นั้น ดังนี้

Kotlin

RecommendationCluster.Builder()
            .addEntity(MOVIE_ENTITY)
            .addEntity(MOVIE_ENTITY)
            .addEntity(MOVIE_ENTITY)
            .setTitle("Top Picks For You")
            .build()

Java

new RecommendationCluster.Builder()
                        .addEntity(MOVIE_ENTITY)
                        .addEntity(MOVIE_ENTITY)
                        .addEntity(MOVIE_ENTITY)
                        .setTitle("Top Picks For You")
                        .build();

ขั้นตอนที่ 1: ระบุข้อมูลนิติบุคคล

SDK ได้กำหนดเอนทิตีต่างๆ เพื่อแสดงรายการแต่ละประเภท เรารองรับเอนทิตีต่อไปนี้สำหรับหมวดหมู่การดู

  1. MovieEntity
  2. TvShowEntity
  3. TvSeasonEntity
  4. TvEpisodeEntity
  5. LiveStreamingVideoEntity
  6. VideoClipEntity

แผนภูมิต่อไปนี้แสดงแอตทริบิวต์และข้อกำหนดสำหรับแต่ละประเภท

MovieEntity

แอตทริบิวต์ ข้อกำหนด หมายเหตุ
ชื่อ ต้องระบุ
รูปภาพโปสเตอร์ ต้องระบุ ต้องมีรูปภาพอย่างน้อย 1 รูป และต้องระบุสัดส่วนภาพ (แนะนำให้ใช้แนวนอน แต่ขอแนะนำให้ส่งทั้งรูปภาพแนวตั้งและแนวนอนสำหรับสถานการณ์ต่างๆ)

ดูคำแนะนำได้ที่ข้อกำหนดเกี่ยวกับรูปภาพ

URI การเล่น ต้องระบุ

Deep Link ไปยังแอปของผู้ให้บริการเพื่อเริ่มเล่นภาพยนตร์

หมายเหตุ: คุณใช้ Deep Link สำหรับการระบุแหล่งที่มาได้ ดูคำถามที่พบบ่อยนี้

URI ของหน้าข้อมูล ไม่บังคับ

Deep Link ไปยังแอปของผู้ให้บริการเพื่อแสดงรายละเอียดเกี่ยวกับภาพยนตร์

หมายเหตุ: คุณใช้ Deep Link สำหรับการระบุแหล่งที่มาได้ ดูคำถามที่พบบ่อยนี้

วันที่เผยแพร่ ไม่บังคับ ในหน่วยมิลลิวินาทีของ Epoch
ความพร้อมใช้งาน ต้องระบุ

AVAILABLE: เนื้อหาพร้อมให้บริการแก่ผู้ใช้โดยไม่ต้องดำเนินการใดๆ เพิ่มเติม

FREE_WITH_SUBSCRIPTION: เนื้อหาจะพร้อมใช้งานหลังจากที่ผู้ใช้ซื้อการสมัครใช้บริการ

PAID_CONTENT: เนื้อหาที่ผู้ใช้ต้องซื้อหรือเช่า

PURCHASED: ผู้ใช้ซื้อหรือเช่าเนื้อหาแล้ว

ราคาข้อเสนอ ไม่บังคับ ข้อความอิสระ
ระยะเวลา ต้องระบุ ในหน่วยมิลลิวินาที
ประเภท ต้องระบุ ข้อความอิสระ
การจัดประเภทเนื้อหา ไม่บังคับ ข้อความอิสระตามมาตรฐานอุตสาหกรรม (ตัวอย่าง)
ข้อความกระตุ้นการตัดสินใจ ไม่บังคับ ข้อความอิสระที่จะแสดงเป็นคำกระตุ้นให้ดำเนินการ (Call-To-Action)
แท็ก ไม่บังคับ รายการแท็กที่เชื่อมโยงกับเอนทิตี
ประเภทฟีดวิดีโอถัดไป ต้องมีแบบมีเงื่อนไข

ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง และต้องเป็นประเภทใดประเภทหนึ่งต่อไปนี้

CONTINUE: ผู้ใช้ดูเนื้อหานี้ไปแล้วมากกว่า 1 นาที

NEW: ผู้ใช้ดูตอนที่มีอยู่ทั้งหมดจากเนื้อหาแบบเป็นตอนแล้ว แต่มีตอนใหม่พร้อมให้รับชมและมีตอนที่ยังไม่ได้ดูเพียงตอนเดียว ซึ่งใช้ได้กับเนื้อหาที่เป็นตอนๆ เช่น รายการทีวีหรือการแข่งขันฟุตบอลที่บันทึกไว้ในซีรีส์

ถัดไป: ผู้ใช้ดูเนื้อหาแบบเป็นตอนจบไปแล้วอย่างน้อย 1 ตอน แต่ยังมีตอนเหลืออยู่อีกมากกว่า 1 ตอน หรือเหลืออยู่เพียง 1 ตอนพอดี โดยที่ตอนสุดท้ายไม่ใช่ตอน "ใหม่" และเผยแพร่ก่อนที่ผู้ใช้จะเริ่มดูเนื้อหาแบบเป็นตอน

รายการที่อยากดู: ผู้ใช้เลือกอย่างชัดแจ้งที่จะเพิ่มภาพยนตร์ กิจกรรม หรือซีรีส์ลงในรายการที่อยากดูเพื่อดูแลจัดการสิ่งที่ต้องการดูต่อไปด้วยตนเอง

เวลาที่มีส่วนร่วมล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง ในหน่วยมิลลิวินาทีของ Epoch
เวลาของตำแหน่งการเล่นล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่องและ WatchNextType เป็น CONTINUE ในหน่วยมิลลิวินาทีของ Epoch

TvShowEntity

แอตทริบิวต์ ข้อกำหนด หมายเหตุ
ชื่อ ต้องระบุ
รูปภาพโปสเตอร์ ต้องระบุ ต้องมีรูปภาพอย่างน้อย 1 รูป และต้องระบุสัดส่วนภาพ (แนะนำให้ใช้แนวนอน แต่ขอแนะนำให้ส่งทั้งรูปภาพแนวตั้งและแนวนอนสำหรับสถานการณ์ต่างๆ)

ดูคำแนะนำได้ที่ข้อกำหนดเกี่ยวกับรูปภาพ

URI ของหน้าข้อมูล ต้องระบุ

Deep Link ไปยังแอปของผู้ให้บริการเพื่อแสดงรายละเอียดของรายการทีวี

หมายเหตุ: คุณใช้ Deep Link สำหรับการระบุแหล่งที่มาได้ ดูคำถามที่พบบ่อยนี้

URI การเล่น ไม่บังคับ

Deep Link ไปยังแอปของผู้ให้บริการเพื่อเริ่มเล่นรายการทีวี

หมายเหตุ: คุณใช้ Deep Link สำหรับการระบุแหล่งที่มาได้ ดูคำถามที่พบบ่อยนี้

วันที่ออกอากาศตอนแรก ไม่บังคับ ในหน่วยมิลลิวินาทีของ Epoch
วันที่ออกอากาศของตอนล่าสุด ไม่บังคับ ในหน่วยมิลลิวินาทีของ Epoch
ความพร้อมใช้งาน ต้องระบุ

AVAILABLE: เนื้อหาพร้อมให้บริการแก่ผู้ใช้โดยไม่ต้องดำเนินการใดๆ เพิ่มเติม

FREE_WITH_SUBSCRIPTION: เนื้อหาจะพร้อมใช้งานหลังจากที่ผู้ใช้ซื้อการสมัครใช้บริการ

PAID_CONTENT: เนื้อหาที่ผู้ใช้ต้องซื้อหรือเช่า

PURCHASED: ผู้ใช้ซื้อหรือเช่าเนื้อหาแล้ว

ราคาข้อเสนอ ไม่บังคับ ข้อความอิสระ
จำนวนฤดูกาล ต้องระบุ จำนวนเต็มบวก
ประเภท ต้องระบุ ข้อความอิสระ
การจัดประเภทเนื้อหา ไม่บังคับ ข้อความอิสระตามมาตรฐานอุตสาหกรรม (ตัวอย่าง)
ข้อความกระตุ้นการตัดสินใจ ไม่บังคับ ข้อความอิสระที่จะแสดงเป็นคำกระตุ้นให้ดำเนินการ (Call-To-Action)
แท็ก ไม่บังคับ รายการแท็กที่เชื่อมโยงกับเอนทิตี
ประเภทฟีดวิดีโอถัดไป ต้องมีแบบมีเงื่อนไข

ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง และต้องเป็นประเภทใดประเภทหนึ่งต่อไปนี้

CONTINUE: ผู้ใช้ดูเนื้อหานี้ไปแล้วมากกว่า 1 นาที

NEW: ผู้ใช้ดูตอนที่มีอยู่ทั้งหมดจากเนื้อหาแบบเป็นตอนแล้ว แต่มีตอนใหม่พร้อมให้รับชมและมีตอนที่ยังไม่ได้ดูเพียงตอนเดียว ซึ่งใช้ได้กับเนื้อหาที่เป็นตอนๆ เช่น รายการทีวีหรือการแข่งขันฟุตบอลที่บันทึกไว้ในซีรีส์

ถัดไป: ผู้ใช้ดูเนื้อหาแบบเป็นตอนจบไปแล้วอย่างน้อย 1 ตอน แต่ยังมีตอนเหลืออยู่อีกมากกว่า 1 ตอน หรือเหลืออยู่เพียง 1 ตอนพอดี โดยที่ตอนสุดท้ายไม่ใช่ตอน "ใหม่" และเผยแพร่ก่อนที่ผู้ใช้จะเริ่มดูเนื้อหาแบบเป็นตอน

รายการที่อยากดู: ผู้ใช้เลือกอย่างชัดแจ้งที่จะเพิ่มภาพยนตร์ กิจกรรม หรือซีรีส์ลงในรายการที่อยากดูเพื่อดูแลจัดการสิ่งที่ต้องการดูต่อไปด้วยตนเอง

เวลาที่มีส่วนร่วมล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง ในหน่วยมิลลิวินาทีของ Epoch
เวลาของตำแหน่งการเล่นล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่องและ WatchNextType เป็น CONTINUE ในหน่วยมิลลิวินาทีของ Epoch

TvSeasonEntity

แอตทริบิวต์ ข้อกำหนด หมายเหตุ
ชื่อ ต้องระบุ
รูปภาพโปสเตอร์ ต้องระบุ ต้องมีรูปภาพอย่างน้อย 1 รูป และต้องระบุสัดส่วนภาพ (แนะนำให้ใช้แนวนอน แต่ขอแนะนำให้ส่งทั้งรูปภาพแนวตั้งและแนวนอนสำหรับสถานการณ์ต่างๆ)

ดูคำแนะนำได้ที่ข้อกำหนดเกี่ยวกับรูปภาพ

URI ของหน้าข้อมูล ต้องระบุ

Deep Link ไปยังแอปของผู้ให้บริการเพื่อแสดงรายละเอียดของซีซันรายการทีวี

หมายเหตุ: คุณใช้ Deep Link สำหรับการระบุแหล่งที่มาได้ ดูคำถามที่พบบ่อยนี้

URI การเล่น ไม่บังคับ

Deep Link ไปยังแอปของผู้ให้บริการเพื่อเริ่มเล่นซีซันของรายการทีวี

หมายเหตุ: คุณใช้ Deep Link สำหรับการระบุแหล่งที่มาได้ ดูคำถามที่พบบ่อยนี้

แสดงหมายเลขซีซัน

ไม่บังคับ

พร้อมใช้งานในเวอร์ชัน 1.3.1

สตริง
วันที่ออกอากาศตอนแรก ไม่บังคับ ในหน่วยมิลลิวินาทีของ Epoch
วันที่ออกอากาศของตอนล่าสุด ไม่บังคับ ในหน่วยมิลลิวินาทีของ Epoch
ความพร้อมใช้งาน ต้องระบุ

AVAILABLE: เนื้อหาพร้อมให้บริการแก่ผู้ใช้โดยไม่ต้องดำเนินการใดๆ เพิ่มเติม

FREE_WITH_SUBSCRIPTION: เนื้อหาจะพร้อมใช้งานหลังจากที่ผู้ใช้ซื้อการสมัครใช้บริการ

PAID_CONTENT: เนื้อหาที่ผู้ใช้ต้องซื้อหรือเช่า

PURCHASED: ผู้ใช้ซื้อหรือเช่าเนื้อหาแล้ว

ราคาข้อเสนอ ไม่บังคับ ข้อความอิสระ
จำนวนตอน ต้องระบุ จำนวนเต็มบวก
ประเภท ต้องระบุ ข้อความอิสระ
การจัดประเภทเนื้อหา ไม่บังคับ ข้อความอิสระตามมาตรฐานอุตสาหกรรม (ตัวอย่าง)
ข้อความกระตุ้นการตัดสินใจ ไม่บังคับ ข้อความอิสระที่จะแสดงเป็นคำกระตุ้นให้ดำเนินการ (Call-To-Action)
แท็ก ไม่บังคับ รายการแท็กที่เชื่อมโยงกับเอนทิตี
ประเภทฟีดวิดีโอถัดไป ต้องมีแบบมีเงื่อนไข

ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง และต้องเป็นประเภทใดประเภทหนึ่งต่อไปนี้

CONTINUE: ผู้ใช้ดูเนื้อหานี้ไปแล้วมากกว่า 1 นาที

NEW: ผู้ใช้ดูตอนที่มีอยู่ทั้งหมดจากเนื้อหาแบบเป็นตอนแล้ว แต่มีตอนใหม่พร้อมให้รับชมและมีตอนที่ยังไม่ได้ดูเพียงตอนเดียว ซึ่งใช้ได้กับเนื้อหาที่เป็นตอนๆ เช่น รายการทีวีหรือการแข่งขันฟุตบอลที่บันทึกไว้ในซีรีส์

ถัดไป: ผู้ใช้ดูเนื้อหาแบบเป็นตอนจบไปแล้วอย่างน้อย 1 ตอน แต่ยังมีตอนเหลืออยู่อีกมากกว่า 1 ตอน หรือเหลืออยู่เพียง 1 ตอนพอดี โดยที่ตอนสุดท้ายไม่ใช่ตอน "ใหม่" และเผยแพร่ก่อนที่ผู้ใช้จะเริ่มดูเนื้อหาแบบเป็นตอน

รายการที่อยากดู: ผู้ใช้เลือกอย่างชัดแจ้งที่จะเพิ่มภาพยนตร์ กิจกรรม หรือซีรีส์ลงในรายการที่อยากดูเพื่อดูแลจัดการสิ่งที่ต้องการดูต่อไปด้วยตนเอง

เวลาที่มีส่วนร่วมล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง ในหน่วยมิลลิวินาทีของ Epoch
เวลาของตำแหน่งการเล่นล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่องและ WatchNextType เป็น CONTINUE ในหน่วยมิลลิวินาทีของ Epoch

TvEpisodeEntity

แอตทริบิวต์ ข้อกำหนด หมายเหตุ
ชื่อ ต้องระบุ
รูปภาพโปสเตอร์ ต้องระบุ ต้องมีรูปภาพอย่างน้อย 1 รูป และต้องระบุสัดส่วนภาพ (แนะนำให้ใช้แนวนอน แต่ขอแนะนำให้ส่งทั้งรูปภาพแนวตั้งและแนวนอนสำหรับสถานการณ์ต่างๆ)

ดูคำแนะนำได้ที่ข้อกำหนดเกี่ยวกับรูปภาพ

URI การเล่น ต้องระบุ

Deep Link ไปยังแอปของผู้ให้บริการเพื่อเริ่มเล่นตอน

หมายเหตุ: คุณใช้ Deep Link สำหรับการระบุแหล่งที่มาได้ ดูคำถามที่พบบ่อยนี้

URI ของหน้าข้อมูล ไม่บังคับ

Deep Link ไปยังแอปของผู้ให้บริการเพื่อแสดงรายละเอียดเกี่ยวกับตอนของรายการทีวี

หมายเหตุ: คุณใช้ Deep Link สำหรับการระบุแหล่งที่มาได้ ดูคำถามที่พบบ่อยนี้

แสดงหมายเลขตอน

ไม่บังคับ

พร้อมใช้งานในเวอร์ชัน 1.3.1

สตริง
วันที่ออกอากาศ ต้องระบุ ในหน่วยมิลลิวินาทีของ Epoch
ความพร้อมใช้งาน ต้องระบุ

AVAILABLE: เนื้อหาพร้อมให้บริการแก่ผู้ใช้โดยไม่ต้องดำเนินการใดๆ เพิ่มเติม

FREE_WITH_SUBSCRIPTION: เนื้อหาจะพร้อมใช้งานหลังจากที่ผู้ใช้ซื้อการสมัครใช้บริการ

PAID_CONTENT: เนื้อหาที่ผู้ใช้ต้องซื้อหรือเช่า

PURCHASED: ผู้ใช้ซื้อหรือเช่าเนื้อหาแล้ว

ราคาข้อเสนอ ไม่บังคับ ข้อความอิสระ
ระยะเวลา ต้องระบุ ต้องเป็นค่าบวกในหน่วยมิลลิวินาที
ประเภท ต้องระบุ ข้อความอิสระ
การจัดประเภทเนื้อหา ไม่บังคับ ข้อความอิสระตามมาตรฐานอุตสาหกรรม (ตัวอย่าง)
ข้อความกระตุ้นการตัดสินใจ ไม่บังคับ ข้อความอิสระที่จะแสดงเป็นคำกระตุ้นให้ดำเนินการ (Call-To-Action)
แท็ก ไม่บังคับ รายการแท็กที่เชื่อมโยงกับเอนทิตี
ประเภทฟีดวิดีโอถัดไป ต้องมีแบบมีเงื่อนไข

ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง และต้องเป็นประเภทใดประเภทหนึ่งต่อไปนี้

CONTINUE: ผู้ใช้ดูเนื้อหานี้ไปแล้วมากกว่า 1 นาที

NEW: ผู้ใช้ดูตอนที่มีอยู่ทั้งหมดจากเนื้อหาแบบเป็นตอนแล้ว แต่มีตอนใหม่พร้อมให้รับชมและมีตอนที่ยังไม่ได้ดูเพียงตอนเดียว ซึ่งใช้ได้กับเนื้อหาที่เป็นตอนๆ เช่น รายการทีวีหรือการแข่งขันฟุตบอลที่บันทึกไว้ในซีรีส์

ถัดไป: ผู้ใช้ดูเนื้อหาแบบเป็นตอนจบไปแล้วอย่างน้อย 1 ตอน แต่ยังมีตอนเหลืออยู่อีกมากกว่า 1 ตอน หรือเหลืออยู่เพียง 1 ตอนพอดี โดยที่ตอนสุดท้ายไม่ใช่ตอน "ใหม่" และเผยแพร่ก่อนที่ผู้ใช้จะเริ่มดูเนื้อหาแบบเป็นตอน

รายการที่อยากดู: ผู้ใช้เลือกอย่างชัดแจ้งที่จะเพิ่มภาพยนตร์ กิจกรรม หรือซีรีส์ลงในรายการที่อยากดูเพื่อดูแลจัดการสิ่งที่ต้องการดูต่อไปด้วยตนเอง

เวลาที่มีส่วนร่วมล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง ในหน่วยมิลลิวินาทีของ Epoch
เวลาของตำแหน่งการเล่นล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่องและ WatchNextType เป็น CONTINUE ในหน่วยมิลลิวินาทีของ Epoch

LiveStreamingVideoEntity

แอตทริบิวต์ ข้อกำหนด หมายเหตุ
ชื่อ ต้องระบุ
รูปภาพโปสเตอร์ ต้องระบุ ต้องมีรูปภาพอย่างน้อย 1 รูป และต้องระบุสัดส่วนภาพ (แนะนำให้ใช้แนวนอน แต่ขอแนะนำให้ส่งทั้งรูปภาพแนวตั้งและแนวนอนสำหรับสถานการณ์ต่างๆ)

ดูคำแนะนำได้ที่ข้อกำหนดเกี่ยวกับรูปภาพ

URI การเล่น ต้องระบุ

Deep Link ไปยังแอปของผู้ให้บริการเพื่อเริ่มเล่นวิดีโอ

หมายเหตุ: คุณใช้ Deep Link สำหรับการระบุแหล่งที่มาได้ ดูคำถามที่พบบ่อยนี้

ผู้เผยแพร่ ต้องระบุ ข้อความอิสระ
เวลาเริ่มต้น ไม่บังคับ ในหน่วยมิลลิวินาทีของ Epoch
เวลาสิ้นสุด ไม่บังคับ ในหน่วยมิลลิวินาทีของ Epoch
ยอดดู ไม่บังคับ ข้อความอิสระ ต้องแปลเป็นภาษาท้องถิ่น
ข้อความกระตุ้นการตัดสินใจ ไม่บังคับ ข้อความอิสระที่จะแสดงเป็นคำกระตุ้นให้ดำเนินการ (Call-To-Action)
แท็ก ไม่บังคับ รายการแท็กที่เชื่อมโยงกับเอนทิตี
ประเภทฟีดวิดีโอถัดไป ต้องมีแบบมีเงื่อนไข

ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง และต้องเป็นประเภทใดประเภทหนึ่งต่อไปนี้

CONTINUE: ผู้ใช้ดูเนื้อหานี้ไปแล้วมากกว่า 1 นาที

NEW: ผู้ใช้ดูตอนที่มีอยู่ทั้งหมดจากเนื้อหาแบบเป็นตอนแล้ว แต่มีตอนใหม่พร้อมให้รับชมและมีตอนที่ยังไม่ได้ดูเพียงตอนเดียว ซึ่งใช้ได้กับเนื้อหาที่เป็นตอนๆ เช่น รายการทีวีหรือการแข่งขันฟุตบอลที่บันทึกไว้ในซีรีส์

ถัดไป: ผู้ใช้ดูเนื้อหาแบบเป็นตอนจบไปแล้วอย่างน้อย 1 ตอน แต่ยังมีตอนเหลืออยู่อีกมากกว่า 1 ตอน หรือเหลืออยู่เพียง 1 ตอนพอดี โดยที่ตอนสุดท้ายไม่ใช่ตอน "ใหม่" และเผยแพร่ก่อนที่ผู้ใช้จะเริ่มดูเนื้อหาแบบเป็นตอน

รายการที่อยากดู: ผู้ใช้เลือกอย่างชัดแจ้งที่จะเพิ่มภาพยนตร์ กิจกรรม หรือซีรีส์ลงในรายการที่อยากดูเพื่อดูแลจัดการสิ่งที่ต้องการดูต่อไปด้วยตนเอง

เวลาที่มีส่วนร่วมล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง ในหน่วยมิลลิวินาทีของ Epoch
เวลาของตำแหน่งการเล่นล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่องและ WatchNextType เป็น CONTINUE ในหน่วยมิลลิวินาทีของ Epoch

VideoClipEntity

ออบเจ็กต์ VideoClipEntity แสดงเอนทิตีวิดีโอที่มาจากโซเชียลมีเดีย เช่น TikTok หรือ YouTube

แอตทริบิวต์ ข้อกำหนด หมายเหตุ
ชื่อ ต้องระบุ
รูปภาพโปสเตอร์ ต้องระบุ ต้องมีรูปภาพอย่างน้อย 1 รูป และต้องระบุสัดส่วนภาพ (แนะนำให้ใช้แนวนอน แต่ขอแนะนำให้ส่งทั้งรูปภาพแนวตั้งและแนวนอนสำหรับสถานการณ์ต่างๆ)

ดูคำแนะนำได้ที่ข้อกำหนดเกี่ยวกับรูปภาพ

URI การเล่น ต้องระบุ

Deep Link ไปยังแอปของผู้ให้บริการเพื่อเริ่มเล่นวิดีโอ

หมายเหตุ: คุณใช้ Deep Link สำหรับการระบุแหล่งที่มาได้ ดูคำถามที่พบบ่อยนี้

เวลาที่สร้าง ต้องระบุ ในหน่วยมิลลิวินาทีของ Epoch
ระยะเวลา ต้องระบุ ต้องเป็นค่าบวกในหน่วยมิลลิวินาที
ครีเอเตอร์ ต้องระบุ ข้อความอิสระ
รูปภาพของครีเอเตอร์ ไม่บังคับ รูปภาพอวาตาร์ของครีเอเตอร์
ยอดดู ไม่บังคับ ข้อความอิสระ ต้องแปลเป็นภาษาท้องถิ่น
ข้อความกระตุ้นการตัดสินใจ ไม่บังคับ ข้อความอิสระที่จะแสดงเป็นคำกระตุ้นให้ดำเนินการ (Call-To-Action)
แท็ก ไม่บังคับ รายการแท็กที่เชื่อมโยงกับเอนทิตี
ประเภทฟีดวิดีโอถัดไป ต้องมีแบบมีเงื่อนไข

ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง และต้องเป็นประเภทใดประเภทหนึ่งต่อไปนี้

CONTINUE: ผู้ใช้ดูเนื้อหานี้ไปแล้วมากกว่า 1 นาที

NEW: ผู้ใช้ดูตอนที่มีอยู่ทั้งหมดจากเนื้อหาแบบเป็นตอนแล้ว แต่มีตอนใหม่พร้อมให้รับชมและมีตอนที่ยังไม่ได้ดูเพียงตอนเดียว ซึ่งใช้ได้กับเนื้อหาที่เป็นตอนๆ เช่น รายการทีวีหรือการแข่งขันฟุตบอลที่บันทึกไว้ในซีรีส์

ถัดไป: ผู้ใช้ดูเนื้อหาแบบเป็นตอนจบไปแล้วอย่างน้อย 1 ตอน แต่ยังมีตอนเหลืออยู่อีกมากกว่า 1 ตอน หรือเหลืออยู่เพียง 1 ตอนพอดี โดยที่ตอนสุดท้ายไม่ใช่ตอน "ใหม่" และเผยแพร่ก่อนที่ผู้ใช้จะเริ่มดูเนื้อหาแบบเป็นตอน

รายการที่อยากดู: ผู้ใช้เลือกอย่างชัดแจ้งที่จะเพิ่มภาพยนตร์ กิจกรรม หรือซีรีส์ลงในรายการที่อยากดูเพื่อดูแลจัดการสิ่งที่ต้องการดูต่อไปด้วยตนเอง

เวลาที่มีส่วนร่วมล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่อง ในหน่วยมิลลิวินาทีของ Epoch
เวลาของตำแหน่งการเล่นล่าสุด ต้องมีแบบมีเงื่อนไข ต้องระบุเมื่อรายการอยู่ในคลัสเตอร์ความต่อเนื่องและ WatchNextType เป็น CONTINUE ในหน่วยมิลลิวินาทีของ Epoch

ข้อกำหนดเกี่ยวกับรูปภาพ

ส่วนต่อไปนี้จะแสดงข้อกำหนดที่จำเป็นสำหรับชิ้นงานรูปภาพ

รูปแบบไฟล์

PNG, JPG, GIF แบบภาพนิ่ง, WebP

ขนาดไฟล์สูงสุด

5120 KB

คำแนะนำเพิ่มเติม

  • พื้นที่ปลอดภัยสำหรับรูปภาพ: ใส่เนื้อหาสำคัญไว้ตรงกลาง ซึ่งก็คือ 80% ของรูปภาพนั้น

ตัวอย่าง

Kotlin

var movie = MovieEntity.Builder()
    .setName("Avengers")
    .addPosterImage(Image.Builder()
                          .setImageUri(Uri.parse("http://www.x.com/image.png"))
                          .setImageHeightInPixel(960)
                          .setImageWidthInPixel(408)
                          .build())
    .setPlayBackUri(Uri.parse("http://tv.com/playback/1"))
    .setReleaseDateEpochMillis(1633032895L)
    .setAvailability(ContentAvailability.AVAILABILITY_AVAILABLE)
    .setDurationMillis(12345678L)
    .addGenre("action")
    .addContentRating("R")
    .setWatchNextType(WatchNextType.TYPE_NEW)
    .setLastEngagementTimeMillis(1664568895L)
    .setCallToActionText("Watch Now")
    .addTag("Action")
    .build()

Java

MovieEntity movie = new MovieEntity.Builder()
                  .setName("Avengers")
                  .addPosterImage(
                      new Image.Builder()
                          .setImageUri(Uri.parse("http://www.x.com/image.png"))
                          .setImageHeightInPixel(960)
                          .setImageWidthInPixel(408)
                          .build())
                  .setPlayBackUri(Uri.parse("http://tv.com/playback/1"))
                  .setReleaseDateEpochMillis(1633032895L)
                  .setAvailability(ContentAvailability.AVAILABILITY_AVAILABLE)
                  .setDurationMillis(12345678L)
                  .addGenre("action")
                  .addContentRating("R")
                  .setWatchNextType(WatchNextType.TYPE_NEW)
                  .setLastEngagementTimeMillis(1664568895L)
                  .setCallToActionText("Watch Now")
                  .addTag("Action")
                  .build();

ขั้นตอนที่ 2: ระบุข้อมูลคลัสเตอร์

ขอแนะนำให้เรียกใช้งานการเผยแพร่เนื้อหาในเบื้องหลัง (เช่น ใช้ WorkManager) และกำหนดเวลาเป็นประจำหรือตามเหตุการณ์ (เช่น ทุกครั้งที่ผู้ใช้เปิดแอปหรือเมื่อผู้ใช้เพิ่งเพิ่มสินค้าลงในรถเข็น)

AppEngagePublishClient มีหน้าที่เผยแพร่คลัสเตอร์ API ต่อไปนี้พร้อมใช้งานในไคลเอ็นต์

  • isServiceAvailable
  • publishRecommendationClusters
  • publishFeaturedCluster
  • publishContinuationCluster
  • publishUserAccountManagementRequest
  • updatePublishStatus
  • deleteRecommendationsClusters
  • deleteFeaturedCluster
  • deleteContinuationCluster
  • deleteUserManagementCluster
  • deleteClusters

isServiceAvailable

API นี้ใช้เพื่อตรวจสอบว่าบริการพร้อมสำหรับการผสานรวมหรือไม่ และเนื้อหาจะแสดงบนอุปกรณ์ได้หรือไม่

คุณสามารถตรวจสอบความพร้อมให้บริการสำหรับคลัสเตอร์ทุกประเภทที่ต้องการเผยแพร่ได้ isServiceAvailable API จะยอมรับออบเจ็กต์คำขอ ServiceAvailabilityRequest ซึ่งมีประเภทคลัสเตอร์ที่ต้องตรวจสอบความพร้อมให้บริการ คุณสามารถดูค่า enum ของ ClusterType ที่จำเป็นสำหรับ ServiceAvailabilityRequest ได้จากตารางต่อไปนี้

ประเภทคลัสเตอร์ ค่าคงที่ประเภทคลัสเตอร์ ค่าจำนวนเต็ม
ไม่ทราบ TYPE_UNKNOWN 0
คลัสเตอร์วิดีโอแนะนำ TYPE_RECOMMENDATION 1
คลัสเตอร์แนะนำ TYPE_FEATURED 2
คลัสเตอร์ความต่อเนื่อง TYPE_CONTINUATION 3
คลัสเตอร์การจัดการผู้ใช้ TYPE_ENGAGEMENT 8
คลัสเตอร์การสมัครใช้บริการ TYPE_SUBSCRIPTION 12

Kotlin

val request = ServiceAvailabilityRequest.Builder()
    .addIntendedClusterType(ClusterType.TYPE_CONTINUATION)
    .addIntendedClusterType(ClusterType.TYPE_RECOMMENDATION)
    .build()

client.isServiceAvailable(request).addOnCompleteListener { task ->
    if (task.isSuccessful) {
        val availabilityMap = task.result
        if (availabilityMap[ClusterType.TYPE_CONTINUATION] == true) {
            // Proceed with publishing continuation content
        }
        if (availabilityMap[ClusterType.TYPE_RECOMMENDATION] == true) {
            // Proceed with publishing recommendation content
        }
    } else {
        // The IPC call itself fails, proceed with error handling logic here,
        // such as retry.
    }
}

Java

ServiceAvailabilityRequest request =
    new ServiceAvailabilityRequest.Builder()
        .addIntendedClusterType(ClusterType.TYPE_CONTINUATION)
        .addIntendedClusterType(ClusterType.TYPE_RECOMMENDATION)
        .build();

client.isServiceAvailable(request).addOnCompleteListener(task -> {
    if (task.isSuccessful()) {
        Map<Integer, Boolean> availabilityMap = task.getResult();
        if (Boolean.TRUE.equals(availabilityMap.get(ClusterType.TYPE_CONTINUATION))) {
            // Proceed with publishing continuation content
        }
        if (Boolean.TRUE.equals(availabilityMap.get(ClusterType.TYPE_RECOMMENDATION))) {
            // Proceed with publishing recommendation content
        }
    } else {
        // The IPC call itself fails, proceed with error handling logic here,
        // such as retry.
    }
});
ฟีเจอร์ความพร้อมให้บริการแบบมีเงื่อนไข

แอปที่ผสานรวมบางแอปจะขอการกำหนดค่าพิเศษที่เปิดและปิดใช้บริการ Engage เป็นระยะๆ เพื่อลดค่าใช้จ่ายการแสดงผล อย่างไรก็ตาม กลยุทธ์การนำเข้าเนื้อหาเป็นระยะๆ นี้ส่งผลเสียต่อประสบการณ์ของผู้ใช้ เนื่องจากระบบจะไม่แสดงเนื้อหาที่ล้าสมัย และจะไม่แสดงเนื้อหาในบางแพลตฟอร์ม

ตั้งแต่เวอร์ชัน 1.6.0 เป็นต้นไป Engage SDK จะช่วยให้ตรวจสอบความพร้อมใช้งานของคลัสเตอร์บางประเภทได้ หากแอปของคุณใช้การส่งผ่านข้อมูลเป็นระยะๆ ให้ทำดังนี้

  • คลัสเตอร์การรับชมต่อ (เช่น รับชมต่อ) จะยังคงเปิดใช้อยู่โดยค่าเริ่มต้นในอุปกรณ์ที่รองรับทั้งหมด
  • คลัสเตอร์ประเภทอื่นๆ (เช่น วิดีโอแนะนำ) จะเปิดและปิดใช้เป็นระยะๆ

หากการกำหนดค่าเริ่มต้นนี้ไม่เหมาะกับความต้องการของคุณ โปรดติดต่อ engage-developers@google.com

สำหรับ SDK เวอร์ชันก่อน v1.6.0 (เลิกใช้งานแล้ว)

Kotlin

client.isServiceAvailable.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Handle IPC call success
        if(task.result) {
          // Service is available on the device, proceed with content publish
          // calls.
        } else {
          // Service is not available, no further action is needed.
        }
    } else {
      // The IPC call itself fails, proceed with error handling logic here,
      // such as retry.
    }
}

Java

client.isServiceAvailable().addOnCompleteListener(task - > {
    if (task.isSuccessful()) {
        // Handle success
        if(task.getResult()) {
          // Service is available on the device, proceed with content publish
          // calls.
        } else {
          // Service is not available, no further action is needed.
        }
    } else {
      // The IPC call itself fails, proceed with error handling logic here,
      // such as retry.
    }
});

publishRecommendationClusters

API นี้ใช้เพื่อเผยแพร่รายการออบเจ็กต์ RecommendationCluster

Kotlin

client.publishRecommendationClusters(
      PublishRecommendationClustersRequest.Builder()
        .addRecommendationCluster(
          RecommendationCluster.Builder()
            .addEntity(entity1)
            .addEntity(entity2)
            .setTitle("Top Picks For You")
            .build()
        )
        .build()
    )

Java

client.publishRecommendationClusters(
            new PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    new RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Top Picks For You")
                        .build())
                .build());

เมื่อบริการได้รับคำขอ ระบบจะดำเนินการต่อไปนี้ภายในธุรกรรมเดียว

  • ระบบจะนำข้อมูล RecommendationCluster ที่มีอยู่จากพาร์ทเนอร์นักพัฒนาออก
  • ระบบจะแยกวิเคราะห์และจัดเก็บข้อมูลจากคำขอในคลัสเตอร์วิดีโอแนะนำที่อัปเดต

ในกรณีที่เกิดข้อผิดพลาด ระบบจะปฏิเสธคำขอทั้งหมดและคงสถานะที่มีอยู่ไว้

publishFeaturedCluster

API นี้ใช้เพื่อเผยแพร่รายการออบเจ็กต์ FeaturedCluster

Kotlin

client.publishFeaturedCluster(
    PublishFeaturedClusterRequest.Builder()
      .setFeaturedCluster(
        FeaturedCluster.Builder()
          .addEntity(entity1)
          .addEntity(entity2)
          .build())
      .build())

Java

client.publishFeaturedCluster(
            new PublishFeaturedClusterRequest.Builder()
                .setFeaturedCluster(
                    new FeaturedCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .build())
                .build());

เมื่อบริการได้รับคำขอ ระบบจะดำเนินการต่อไปนี้ภายในธุรกรรมเดียว

  • ระบบจะนำข้อมูล FeaturedCluster ที่มีอยู่จากพาร์ทเนอร์นักพัฒนาออก
  • ระบบจะแยกวิเคราะห์และจัดเก็บข้อมูลจากคำขอในคลัสเตอร์ที่แนะนำที่อัปเดต

ในกรณีที่เกิดข้อผิดพลาด ระบบจะปฏิเสธคำขอทั้งหมดและคงสถานะที่มีอยู่ไว้

publishContinuationCluster

API นี้ใช้เพื่อเผยแพร่ออบเจ็กต์ ContinuationCluster

Kotlin

client.publishContinuationCluster(
    PublishContinuationClusterRequest.Builder()
      .setContinuationCluster(
        ContinuationCluster.Builder()
          .addEntity(entity1)
          .addEntity(entity2)
          .build())
      .build())

Java

client.publishContinuationCluster(
            new PublishContinuationClusterRequest.Builder()
                .setContinuationCluster(
                    new ContinuationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .build())
                .build());

เมื่อบริการได้รับคำขอ ระบบจะดำเนินการต่อไปนี้ภายในธุรกรรมเดียว

  • ระบบจะนำข้อมูล ContinuationCluster ที่มีอยู่จากพาร์ทเนอร์นักพัฒนาออก
  • ระบบจะแยกวิเคราะห์และจัดเก็บข้อมูลจากคำขอในคลัสเตอร์ความต่อเนื่องที่อัปเดต

ในกรณีที่เกิดข้อผิดพลาด ระบบจะปฏิเสธคำขอทั้งหมดและคงสถานะที่มีอยู่ไว้

publishUserAccountManagementRequest

API นี้ใช้เพื่อเผยแพร่การ์ดลงชื่อเข้าใช้ การดำเนินการลงชื่อเข้าใช้จะนำผู้ใช้ไปยังหน้าลงชื่อเข้าใช้ของแอปเพื่อให้แอปเผยแพร่เนื้อหา (หรือแสดงเนื้อหาที่ปรับเปลี่ยนในแบบของผู้ใช้มากขึ้น) ได้

ข้อมูลเมตาต่อไปนี้เป็นส่วนหนึ่งของการ์ดลงชื่อเข้าใช้ -

แอตทริบิวต์ ข้อกำหนด คำอธิบาย
URI การดำเนินการ ต้องระบุ Deep Link ไปยังการดำเนินการ (เช่น ไปยังหน้าลงชื่อเข้าใช้แอป)
รูปภาพ ไม่บังคับ - หากไม่ได้ระบุ ต้องระบุชื่อ

รูปภาพที่แสดงในการ์ด

รูปภาพสัดส่วนภาพ 16x9 ที่มีความละเอียด 1264x712

ชื่อ ไม่บังคับ - หากไม่ได้ระบุ ต้องระบุรูปภาพ ชื่อบนบัตร
ข้อความเกี่ยวกับการดำเนินการ ไม่บังคับ ข้อความที่แสดงบน CTA (เช่น ลงชื่อเข้าใช้)
ชื่อรอง ไม่บังคับ คำบรรยายที่ไม่บังคับในการ์ด

Kotlin

var SIGN_IN_CARD_ENTITY =
      SignInCardEntity.Builder()
          .addPosterImage(
              Image.Builder()
                  .setImageUri(Uri.parse("http://www.x.com/image.png"))
                  .setImageHeightInPixel(500)
                  .setImageWidthInPixel(500)
                  .build())
          .setActionText("Sign In")
          .setActionUri(Uri.parse("http://xx.com/signin"))
          .build()

client.publishUserAccountManagementRequest(
            PublishUserAccountManagementRequest.Builder()
                .setSignInCardEntity(SIGN_IN_CARD_ENTITY)
                .build());

Java

SignInCardEntity SIGN_IN_CARD_ENTITY =
      new SignInCardEntity.Builder()
          .addPosterImage(
              new Image.Builder()
                  .setImageUri(Uri.parse("http://www.x.com/image.png"))
                  .setImageHeightInPixel(500)
                  .setImageWidthInPixel(500)
                  .build())
          .setActionText("Sign In")
          .setActionUri(Uri.parse("http://xx.com/signin"))
          .build();

client.publishUserAccountManagementRequest(
            new PublishUserAccountManagementRequest.Builder()
                .setSignInCardEntity(SIGN_IN_CARD_ENTITY)
                .build());

เมื่อบริการได้รับคำขอ ระบบจะดำเนินการต่อไปนี้ภายในธุรกรรมเดียว

  • ระบบจะนำข้อมูล UserAccountManagementCluster ที่มีอยู่จากพาร์ทเนอร์นักพัฒนาออก
  • ระบบจะแยกวิเคราะห์และจัดเก็บข้อมูลจากคำขอในคลัสเตอร์ UserAccountManagementCluster ที่อัปเดต

ในกรณีที่เกิดข้อผิดพลาด ระบบจะปฏิเสธคำขอทั้งหมดและคงสถานะที่มีอยู่ไว้

updatePublishStatus

หากไม่มีการเผยแพร่คลัสเตอร์ใดเลยเนื่องจากเหตุผลทางธุรกิจภายใน เราขอแนะนำอย่างยิ่งให้อัปเดตสถานะการเผยแพร่โดยใช้ API updatePublishStatus ซึ่งเป็นสิ่งสำคัญเนื่องจากเหตุผลต่อไปนี้

  • การระบุสถานะในทุกสถานการณ์ แม้ว่าเนื้อหาจะเผยแพร่แล้ว (STATUS == PUBLISHED) ก็มีความสำคัญต่อการสร้างแดชบอร์ดที่ใช้สถานะที่ชัดเจนนี้เพื่อแสดงประสิทธิภาพและเมตริกอื่นๆ ของการผสานรวม
  • หากไม่มีการเผยแพร่เนื้อหาแต่สถานะการผสานรวมไม่เสียหาย (STATUS == NOT_PUBLISHED) Google จะหลีกเลี่ยงการทริกเกอร์การแจ้งเตือนในแดชบอร์ดประสิทธิภาพของแอปได้ ซึ่งเป็นการยืนยันว่าเนื้อหาไม่ได้เผยแพร่เนื่องจากสถานการณ์ที่คาดไว้จากมุมมองของผู้ให้บริการ
  • ซึ่งจะช่วยให้นักพัฒนาแอปทราบข้อมูลเชิงลึกเกี่ยวกับช่วงเวลาที่เผยแพร่ข้อมูลเทียบกับช่วงเวลาที่ไม่ได้เผยแพร่
  • Google อาจใช้รหัสสถานะเพื่อกระตุ้นให้ผู้ใช้ดำเนินการบางอย่างในแอปเพื่อให้เห็นเนื้อหาแอปหรือเอาชนะอุปสรรคได้

รายการรหัสสถานะการเผยแพร่ที่มีสิทธิ์มีดังนี้

// Content is published
AppEngagePublishStatusCode.PUBLISHED,

// Content is not published as user is not signed in
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN,

// Content is not published as user is not subscribed
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SUBSCRIPTION,

// Content is not published as user location is ineligible
AppEngagePublishStatusCode.NOT_PUBLISHED_INELIGIBLE_LOCATION,

// Content is not published as there is no eligible content
AppEngagePublishStatusCode.NOT_PUBLISHED_NO_ELIGIBLE_CONTENT,

// Content is not published as the feature is disabled by the client
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_FEATURE_DISABLED_BY_CLIENT,

// Content is not published as the feature due to a client error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_CLIENT_ERROR,

// Content is not published as the feature due to a service error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_SERVICE_ERROR,

// Content is not published due to some other reason
// Reach out to engage-developers@ before using this enum.
AppEngagePublishStatusCode.NOT_PUBLISHED_OTHER

หากเนื้อหาไม่ได้รับการเผยแพร่เนื่องจากผู้ใช้ไม่ได้เข้าสู่ระบบ Google ขอแนะนำให้เผยแพร่การ์ดลงชื่อเข้าใช้ หากผู้ให้บริการไม่สามารถเผยแพร่การ์ดการลงชื่อเข้าใช้ไม่ว่าด้วยเหตุผลใดก็ตาม เราขอแนะนำให้เรียกใช้ API updatePublishStatus พร้อมรหัสสถานะ NOT_PUBLISHED_REQUIRES_SIGN_IN

Kotlin

client.updatePublishStatus(
   PublishStatusRequest.Builder()
     .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN)
     .build())

Java

client.updatePublishStatus(
    new PublishStatusRequest.Builder()
        .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN)
        .build());

deleteRecommendationsClusters

API นี้ใช้เพื่อลบเนื้อหาของคลัสเตอร์วิดีโอแนะนำ

Kotlin

client.deleteRecommendationsClusters()

Java

client.deleteRecommendationsClusters();

เมื่อบริการได้รับคำขอ ระบบจะนำข้อมูลที่มีอยู่ออกจากคลัสเตอร์วิดีโอแนะนำ ในกรณีที่เกิดข้อผิดพลาด ระบบจะปฏิเสธคำขอทั้งหมดและคงสถานะที่มีอยู่ไว้

deleteFeaturedCluster

API นี้ใช้เพื่อลบเนื้อหาของคลัสเตอร์ที่แนะนํา

Kotlin

client.deleteFeaturedCluster()

Java

client.deleteFeaturedCluster();

เมื่อบริการได้รับคำขอ ระบบจะนำข้อมูลที่มีอยู่ออกจากคลัสเตอร์ที่แนะนำ ในกรณีที่เกิดข้อผิดพลาด ระบบจะปฏิเสธคำขอทั้งหมดและคงสถานะที่มีอยู่ไว้

deleteContinuationCluster

API นี้ใช้เพื่อลบเนื้อหาของคลัสเตอร์ความต่อเนื่อง

Kotlin

client.deleteContinuationCluster()

Java

client.deleteContinuationCluster();

เมื่อบริการได้รับคำขอ ระบบจะนำข้อมูลที่มีอยู่ออกจากคลัสเตอร์ความต่อเนื่อง ในกรณีที่เกิดข้อผิดพลาด ระบบจะปฏิเสธคำขอทั้งหมดและคงสถานะที่มีอยู่ไว้

deleteUserManagementCluster

API นี้ใช้เพื่อลบเนื้อหาของคลัสเตอร์ UserAccountManagement

Kotlin

client.deleteUserManagementCluster()

Java

client.deleteUserManagementCluster();

เมื่อบริการได้รับคำขอ ระบบจะนำข้อมูลที่มีอยู่ออกจากคลัสเตอร์ UserAccountManagement ในกรณีที่เกิดข้อผิดพลาด คำขอทั้งหมดจะถูกปฏิเสธและระบบจะคงสถานะที่มีอยู่ไว้

deleteClusters

API นี้ใช้เพื่อลบเนื้อหาของประเภทคลัสเตอร์ที่ระบุ

Kotlin

client.deleteClusters(
    DeleteClustersRequest.Builder()
      .addClusterType(ClusterType.TYPE_CONTINUATION)
      .addClusterType(ClusterType.TYPE_FEATURED)
      .addClusterType(ClusterType.TYPE_RECOMMENDATION)
      .build())

Java

client.deleteClusters(
            new DeleteClustersRequest.Builder()
                .addClusterType(ClusterType.TYPE_CONTINUATION)
                .addClusterType(ClusterType.TYPE_FEATURED)
                .addClusterType(ClusterType.TYPE_RECOMMENDATION)
                .build());

เมื่อบริการได้รับคำขอ ระบบจะนำข้อมูลที่มีอยู่ออกจากคลัสเตอร์ทั้งหมดที่ตรงกับประเภทคลัสเตอร์ที่ระบุ ไคลเอ็นต์สามารถเลือกส่งคลัสเตอร์ประเภทเดียวหรือหลายประเภทก็ได้ ในกรณีที่เกิดข้อผิดพลาด ระบบจะปฏิเสธคำขอทั้งหมดและคงสถานะที่มีอยู่ไว้

การจัดการข้อผิดพลาด

เราขอแนะนำอย่างยิ่งให้ฟังผลลัพธ์ของงานจาก API การเผยแพร่ เพื่อให้สามารถดำเนินการติดตามผลเพื่อกู้คืนและส่งงานที่สำเร็จอีกครั้งได้

Kotlin

client.publishRecommendationClusters(
        PublishRecommendationClustersRequest.Builder()
          .addRecommendationCluster(..)
          .build())
      .addOnCompleteListener { task ->
        if (task.isSuccessful) {
          // do something
        } else {
          val exception = task.exception
          if (exception is AppEngageException) {
            @AppEngageErrorCode val errorCode = exception.errorCode
            if (errorCode == AppEngageErrorCode.SERVICE_NOT_FOUND) {
              // do something
            }
          }
        }
      }

Java

client.publishRecommendationClusters(
              new PublishRecommendationClustersRequest.Builder()
                  .addRecommendationCluster(...)
                  .build())
          .addOnCompleteListener(
              task -> {
                if (task.isSuccessful()) {
                  // do something
                } else {
                  Exception exception = task.getException();
                  if (exception instanceof AppEngageException) {
                    @AppEngageErrorCode
                    int errorCode = ((AppEngageException) exception).getErrorCode();
                    if (errorCode == AppEngageErrorCode.SERVICE_NOT_FOUND) {
                      // do something
                    }
                  }
                }
              });

ระบบจะแสดงข้อผิดพลาดเป็น AppEngageException โดยมีสาเหตุรวมเป็นรหัสข้อผิดพลาด

รหัสข้อผิดพลาด ชื่อข้อผิดพลาด หมายเหตุ
1 SERVICE_NOT_FOUND บริการไม่พร้อมใช้งานในอุปกรณ์ที่ระบุ
2 SERVICE_NOT_AVAILABLE บริการพร้อมใช้งานในอุปกรณ์ที่ระบุ แต่ไม่พร้อมใช้งานในขณะที่โทร (เช่น มีการปิดใช้อย่างชัดแจ้ง)
3 SERVICE_CALL_EXECUTION_FAILURE การดำเนินการงานไม่สำเร็จเนื่องจากปัญหาเกี่ยวกับชุดข้อความ ในกรณีนี้ คุณสามารถลองอีกครั้งได้
4 SERVICE_CALL_PERMISSION_DENIED ผู้โทรไม่ได้รับอนุญาตให้โทรหาบริการ
5 SERVICE_CALL_INVALID_ARGUMENT คำขอมีข้อมูลที่ไม่ถูกต้อง (เช่น มีคลัสเตอร์มากกว่าจำนวนที่อนุญาต)
6 SERVICE_CALL_INTERNAL เกิดข้อผิดพลาดในฝั่งบริการ
7 SERVICE_CALL_RESOURCE_EXHAUSTED มีการเรียกใช้บริการบ่อยเกินไป

ขั้นตอนที่ 3: จัดการ Intent ของการออกอากาศ

นอกจากการเรียก API เพื่อเผยแพร่เนื้อหาผ่านงานแล้ว คุณยังต้องตั้งค่า BroadcastReceiver เพื่อรับคำขอเผยแพร่เนื้อหาด้วย

เป้าหมายของ Intent การออกอากาศคือการเปิดใช้งานแอปอีกครั้งและการบังคับให้ซิงค์ข้อมูลเป็นหลัก Intent การออกอากาศไม่ได้ออกแบบมาให้ส่งบ่อยเกินไป โดยจะทริกเกอร์ก็ต่อเมื่อบริการ Engage พิจารณาว่าเนื้อหาอาจเก่าแล้ว (เช่น มีอายุ 1 สัปดาห์) วิธีนี้จะช่วยเพิ่มความมั่นใจว่าผู้ใช้จะได้รับประสบการณ์การใช้งานเนื้อหาที่อัปเดตใหม่ แม้ว่าจะไม่ได้เรียกใช้แอปพลิเคชันเป็นเวลานานก็ตาม

คุณต้องตั้งค่า BroadcastReceiver ด้วย 2 วิธีต่อไปนี้

  • ลงทะเบียนอินสแตนซ์ของคลาส BroadcastReceiver แบบไดนามิกโดยใช้ Context.registerReceiver() ซึ่งจะช่วยให้แอปพลิเคชันที่ยังคงทำงานอยู่ในหน่วยความจำสามารถสื่อสารได้

Kotlin

class AppEngageBroadcastReceiver : BroadcastReceiver(){
  // Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION broadcast
  // is received
  // Trigger featured cluster publish when PUBLISH_FEATURED broadcast is received
  // Trigger continuation cluster publish when PUBLISH_CONTINUATION broadcast is
  // received
}

fun registerBroadcastReceivers(context: Context){
  var  context = context
  context = context.applicationContext

// Register Recommendation Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_RECOMMENDATION),
                           com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                           /*scheduler=*/null)

// Register Featured Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_FEATURED),
                           com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                           /*scheduler=*/null)

// Register Continuation Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_CONTINUATION),
                           com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                           /*scheduler=*/null)
}

Java

class AppEngageBroadcastReceiver extends BroadcastReceiver {
// Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION broadcast
// is received

// Trigger featured cluster publish when PUBLISH_FEATURED broadcast is received

// Trigger continuation cluster publish when PUBLISH_CONTINUATION broadcast is
// received
}

public static void registerBroadcastReceivers(Context context) {

context = context.getApplicationContext();

// Register Recommendation Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
                         new IntentFilter(com.google.android.engage.service.Intents. ACTION_PUBLISH_RECOMMENDATION),
                         com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                         /*scheduler=*/null);

// Register Featured Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
                         new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_FEATURED),
                         com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                         /*scheduler=*/null);

// Register Continuation Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
                         new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_CONTINUATION),
                         com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                         /*scheduler=*/null);

}
  • ประกาศการติดตั้งใช้งานแบบคงที่ด้วยแท็ก <receiver> ในไฟล์ AndroidManifest.xml ซึ่งจะช่วยให้แอปพลิเคชันได้รับ Intent การออกอากาศเมื่อไม่ได้ทำงาน และยังช่วยให้แอปพลิเคชันเผยแพร่เนื้อหาได้ด้วย

<application>
   <receiver
      android:name=".AppEngageBroadcastReceiver"
      android:permission="com.google.android.engage.REQUEST_ENGAGE_DATA"
      android:exported="true"
      android:enabled="true">
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_RECOMMENDATION" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_FEATURED" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_CONTINUATION" />
      </intent-filter>
   </receiver>
</application>

บริการจะส่ง Intent ต่อไปนี้

  • com.google.android.engage.action.PUBLISH_RECOMMENDATION ขอแนะนำให้เริ่มการโทร publishRecommendationClusters เมื่อได้รับ Intent นี้
  • com.google.android.engage.action.PUBLISH_FEATURED ขอแนะนำให้เริ่มการโทร publishFeaturedCluster เมื่อได้รับ Intent นี้
  • com.google.android.engage.action.PUBLISH_CONTINUATION ขอแนะนำให้เริ่มการโทร publishContinuationCluster เมื่อได้รับ Intent นี้

เวิร์กโฟลว์การผสานรวม

ดูคำแนะนำทีละขั้นตอนในการยืนยันการผสานรวมหลังจากที่ผสานรวมเสร็จแล้วได้ที่เวิร์กโฟลว์การผสานรวมของนักพัฒนาแอป Engage

คำถามที่พบบ่อย

ดูคำถามที่พบบ่อยได้ที่คำถามที่พบบ่อยเกี่ยวกับ Engage SDK

รายชื่อติดต่อ

โปรดติดต่อ engage-developers@google.com หากมีคำถามระหว่างกระบวนการผสานรวม

ขั้นตอนถัดไป

หลังจากผสานรวมเสร็จแล้ว ขั้นตอนถัดไปมีดังนี้

  • ส่งอีเมลไปที่ engage-developers@google.com และแนบ APK ที่ผสานรวมซึ่งพร้อมให้ Google ทดสอบ
  • Google จะดำเนินการตรวจสอบและตรวจสอบภายในเพื่อให้แน่ใจว่าการผสานรวมทำงานได้ตามที่คาดไว้ หากจำเป็นต้องทำการเปลี่ยนแปลง Google จะติดต่อคุณพร้อมรายละเอียดที่จำเป็น
  • เมื่อการทดสอบเสร็จสมบูรณ์และไม่จำเป็นต้องทำการเปลี่ยนแปลงใดๆ Google จะติดต่อคุณเพื่อแจ้งให้ทราบว่าคุณสามารถเริ่มเผยแพร่ APK ที่อัปเดตและผสานรวมแล้วไปยัง Play Store ได้
  • หลังจาก Google ยืนยันว่า APK ที่อัปเดตแล้วได้รับการเผยแพร่ไปยัง Play Store แล้ว ระบบอาจเผยแพร่คลัสเตอร์วิดีโอแนะนำ วิดีโอแนะนำ และวิดีโอที่ดูต่อ และผู้ใช้จะเห็นคลัสเตอร์ดังกล่าว