คู่มือการตั้งค่าไอคอนการแจ้งเตือน

คู่มือการตั้งค่ารูปไอคอนการแจ้งเตือน

เอกสารนี้มีคำแนะนำเกี่ยวกับการตั้งค่ารูปไอคอนการแจ้งเตือนขนาดเล็ก ไอคอนด้านขวา และภาพขนาดใหญ่สำหรับการแจ้งเตือนผ่านพุช alt text

📱 การตั้งค่าไอคอน iOS

การตั้งค่าไอคอนขนาดเล็ก

ไปที่ Images.xcassets-AppIcon และตั้งค่าไอคอน iPhone Notification ขนาดที่ต้องการ:

  • 40 x 40px
  • 60 x 60px

alt text

การตั้งค่าไอคอนด้านขวา / ภาพขนาดใหญ่

✅ รุ่นที่รองรับ

  • รองรับใน iOS 10 ขึ้นไปโดยใช้ SDK iOS ของ EngageLab v3.0.0 และเวอร์ชันหลังจากนั้น

🧑‍💻 การตั้งค่าฝั่งลูกค้า

  1. สร้าง Service Extension target

  2. นำเข้าไฟล์ mtpush-extension-ios-xxx.xcframework ไปยัง Service Extension target ของคุณ

  3. เพิ่มเฟรมเวิร์กสองตัวต่อไปนี้:

    • libz.tbd
    • libresolv.tbd
  4. เรียก [mtpushSetAppkey:] เพื่อตั้งค่า AppKey (ต้องตรงกับที่ใช้เมื่อสร้างแอปพลิเคชัน AppPush)

  5. ในคอลแบ็ค [didReceiveNotificationRequest:] ดึง URL ของภาพ ตัวอย่างโค้ด:

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { self.contentHandler = contentHandler; self.bestAttemptContent = [request.content mutableCopy]; self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [NotificationService]", self.bestAttemptContent.title]; NSString * attachmentPath = self.bestAttemptContent.userInfo[@"my-attachment"]; if (attachmentPath) { NSURL *fileURL = [NSURL URLWithString:attachmentPath]; [self downloadAndSave:fileURL handler:^(NSString *localPath) { if (localPath) { UNNotificationAttachment * attachment = [UNNotificationAttachment attachmentWithIdentifier:@"myAttachment" URL:[NSURL fileURLWithPath:localPath] options:nil error:nil]; self.bestAttemptContent.attachments = @[attachment]; } [self apnsDeliverWith:request]; }]; } else { [self apnsDeliverWith:request]; } } - (void)downloadAndSave:(NSURL *)fileURL handler:(void (^)(NSString *))handler { NSURLSession * session = [NSURLSession sharedSession]; NSURLSessionDownloadTask *task = [session downloadTaskWithURL:fileURL completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSString *localPath = nil; if (!error) { NSString * localURL = [NSString stringWithFormat:@"%@/%@", NSTemporaryDirectory(),fileURL.lastPathComponent]; if ([[NSFileManager defaultManager] moveItemAtPath:location.path toPath:localURL error:nil]) { localPath = localURL; } } handler(localPath); }]; [task resume]; }
              
              - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
  self.contentHandler = contentHandler;
  self.bestAttemptContent = [request.content mutableCopy];
  self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [NotificationService]", self.bestAttemptContent.title];
  
  NSString * attachmentPath = self.bestAttemptContent.userInfo[@"my-attachment"];
  if (attachmentPath) {
    NSURL *fileURL = [NSURL URLWithString:attachmentPath];
    [self downloadAndSave:fileURL handler:^(NSString *localPath) {
      if (localPath) {
        UNNotificationAttachment * attachment = [UNNotificationAttachment attachmentWithIdentifier:@"myAttachment" URL:[NSURL fileURLWithPath:localPath] options:nil error:nil];
        self.bestAttemptContent.attachments = @[attachment];
      }
      [self apnsDeliverWith:request];
    }];
  } else {
    [self apnsDeliverWith:request];
  }
}

- (void)downloadAndSave:(NSURL *)fileURL handler:(void (^)(NSString *))handler {
  NSURLSession * session = [NSURLSession sharedSession];
  NSURLSessionDownloadTask *task = [session downloadTaskWithURL:fileURL completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    NSString *localPath = nil;
    if (!error) {
      NSString * localURL = [NSString stringWithFormat:@"%@/%@", NSTemporaryDirectory(),fileURL.lastPathComponent];
      if ([[NSFileManager defaultManager] moveItemAtPath:location.path toPath:localURL error:nil]) {
        localPath = localURL;
      }
    }
    handler(localPath);
  }];
  [task resume];
}

            
โค้ดนี้โชว์เป็นหน้าต่างลอย

🌐 การตั้งค่าฝั่งเซิร์ฟเวอร์

คุณต้องตั้งค่า mutable-content และ extras ในส่วนของ ios:

ฟิลด์ ชนิด จำเป็น ฟิลด์หลัก คำอธิบาย
mutable-content boolean ไม่จำเป็น notification.ios เปิดใช้งานส่วนขยายการแจ้งเตือน; ต้องเป็น true เพื่อรองรับการขยายการแจ้งเตือนใน iOS 10
extras JSON Object ไม่จำเป็น notification.ios ฟิลด์เพิ่มเติม; คีย์ (เช่น my-attachment) ต้องตรงกับตรรกะฝั่งลูกค้า

ตัวอย่าง JSON:

"notification": { "ios": { "alert": { "title": "title", "subtitle": "subtitle" }, "mutable-content": true, "extras": { "my-attachment": "https://raw.githubusercontent.com/Tikon/imgRepo/master/ic_launcher.png" } } }
              
              "notification": {
  "ios": {
    "alert": {
      "title": "title",
      "subtitle": "subtitle"
    },
    "mutable-content": true,
    "extras": {
      "my-attachment": "https://raw.githubusercontent.com/Tikon/imgRepo/master/ic_launcher.png"
    }
  }
}

            
โค้ดนี้โชว์เป็นหน้าต่างลอย

🤖 การตั้งค่าไอคอน Android

✅ รุ่นที่รองรับ

รองรับตั้งแต่ SDK Android ของ EngageLab v4.4.0 เป็นต้นไป

📡 ภาพรวมการรองรับช่องทาง

ช่องทาง ไอคอนขนาดเล็กแบบไดนามิก ไอคอนด้านขวา ภาพขนาดใหญ่
EngageLab ✅ (รองรับจากระบบ) ✅ (ยกเว้น Meizu) ✅ (รองรับจากระบบ)
Xiaomi
Huawei ✅ (บริการ/ข่าวสารเท่านั้น)
Honor ✅ (ไม่ใช่การตลาด)
OPPO
FCM
Meizu
vivo

📝 หมายเหตุ:

  • OPPO: หากเป้าหมายผู้ใช้เกิน 20 คนและ ColorOS > 5.0 การแจ้งเตือนครั้งแรกจะมีภาพขนาดใหญ่แสดงใน Wi-Fi
  • Xiaomi: ตั้งแต่เดือนสิงหาคม 2023 ไม่รองรับการตั้งค่าไอคอนและภาพไดนามิกผ่านพุช

🎨 การตั้งค่าไอคอนขนาดเล็ก

🧑‍💻 การตั้งค่าฝั่งลูกค้า

  • หาก res/drawable/mtpush_notification_icon มีอยู่ในโปรเจ็กต์ จะถูกใช้งานโดยอัตโนมัติ
  • หากไม่มี จะใช้ไอคอนของแอปพลิเคชันหลัก

ตัวอย่างช่องทาง FCM:

<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/mtpush_notification_icon" /> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/colorAccent" />
              
              <meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/mtpush_notification_icon" />
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />

            
โค้ดนี้โชว์เป็นหน้าต่างลอย

🌐 การตั้งค่าฝั่งเซิร์ฟเวอร์

ฟิลด์ ชนิด จำเป็น ฟิลด์หลัก คำอธิบาย
small_icon_uri string ไม่จำเป็น notification.android URL ไอคอนเครือข่ายหรือพาธทรัพยากร, ขนาดสูงสุด 300KB
small_icon_uri string ไม่จำเป็น options.third_party_channel.<vendor> ไอคอนเฉพาะช่องทาง OEM (Huawei เท่านั้น)

ตัวอย่าง JSON:

"notification": { "android": { "alert": "Hi, Push!", "title": "Send to Android", "small_icon_uri": "https://res.engagelab.net/oversea/e/website/2025/_nuxt/app-push.II1rRaB5.webp" } }, "options": { "time_to_live": 60, "third_party_channel": { "huawei": { "distribution": "pns_mtpush", "small_icon_uri": "logog" } } }
              
              "notification": {
  "android": {
    "alert": "Hi, Push!",
    "title": "Send to Android",
    "small_icon_uri": "https://res.engagelab.net/oversea/e/website/2025/_nuxt/app-push.II1rRaB5.webp"
  }
},
"options": {
  "time_to_live": 60,
  "third_party_channel": {
    "huawei": {
      "distribution": "pns_mtpush",
      "small_icon_uri": "logog"
    }
  }
}

            
โค้ดนี้โชว์เป็นหน้าต่างลอย

🖼️ การตั้งค่าไอคอนด้านขวา / ภาพขนาดใหญ่

🌐 ฟิลด์เซิร์ฟเวอร์

ฟิลด์ ชนิด จำเป็น ฟิลด์หลัก คำอธิบาย
style int ไม่จำเป็น notification.android สไตล์การแจ้งเตือน: ค่าเริ่มต้น 0, 1=bigText, 2=Inbox, 3=bigPicture
big_pic_path string ไม่จำเป็น notification.android จำเป็นเมื่อ style=3; รองรับ URL หรือพาธท้องถิ่น
large_icon string ไม่จำเป็น notification.android ไอคอนด้านขวา; รองรับแหล่งข้อมูลเครือข่ายหรือ drawable (สูงสุด 300KB)

ตัวอย่าง JSON:

{ "notification":
              
              {
  "notification":

            
โค้ดนี้โชว์เป็นหน้าต่างลอย

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

ปัญหาไอคอนเล็ก

1. ทำไมไอคอนแสดงเป็นสีเทา?

  • ใน Android 5.0 และเวอร์ชันที่สูงกว่า หาก targetSdkVersion ≥ 21 ระบบจะใช้สีมาสก์กับไอคอนการแจ้งเตือน ซึ่งอาจทำให้ไอคอนแสดงเป็นสีเทา เพื่อให้ไอคอนแสดงชัดเจน แนะนำให้ใช้ไอคอนที่ ไม่มีเงา ไม่มีการไล่สี และพื้นหลังโปร่งใส และตั้งชื่อว่า mtpush_notification_icon แทนที่ไอคอนนี้ในไดเรกทอรี res/drawable ของโปรเจกต์ และอัปเดตทรัพยากรไอคอนอื่น ๆ ในไดเรกทอรี res (เช่น drawable-xxhdpi) เพื่อให้สอดคล้องกัน หลังจากตั้งค่าอย่างถูกต้อง ระบบจะเรนเดอร์ไอคอนเป็นโครงร่างสีเทาเพื่อหลีกเลี่ยงปัญหา

  • เนื่องจากข้อจำกัดของบางระบบ (เช่น โทรศัพท์ OnePlus และอุปกรณ์ Google ที่รัน Android 10) อาจไม่รองรับหรือไม่สามารถปรับแต่งไอคอนได้

  • บนอุปกรณ์ Xiaomi ตัวเปิดอาจแคชไอคอน หลังจากตั้งค่าข้างต้น ต้อง รีสตาร์ทอุปกรณ์ ก่อนทดสอบ

  • ไม่ว่าจะใช้อุปกรณ์ Xiaomi ผ่านช่องทาง EngageLab หรือช่องทางการแจ้งเตือนของ Xiaomi เอง ต้องเปลี่ยนเป็นรูปแบบการแจ้งเตือนแบบเนทีฟ เพื่อให้ไอคอนแสดงอย่างถูกต้อง วิธีเปลี่ยนมีดังนี้: alt text

2. ทำไมไอคอนใหม่ไม่แสดงผล?

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

ปัญหาไอคอนด้านขวา / ภาพขนาดใหญ่

ทำไมไอคอนหรือภาพไม่แสดง?

  1. ช่องทาง EngageLab: ตรวจสอบว่ามีการเรียกใช้ตัวสร้างการแจ้งเตือนเริ่มต้นหรือไม่ หากมี ให้ลบและติดตั้งแอปพลิเคชันใหม่
  2. APNs (iOS): ไอคอนด้านขวาและภาพขนาดใหญ่เป็นภาพเดียวกัน จะแสดงภาพเฉพาะเมื่อดึงลงในโหมดโฟร์กราวด์ มิฉะนั้นจะแสดงเฉพาะไอคอน
  3. FCM (Android): เริ่มต้นจะแสดงไอคอนด้านขวา; เมื่อขยายการแจ้งเตือนจะแสดงภาพขนาดใหญ่ alt text
icon
ติดต่อฝ่ายขาย