FoxTalk
Docs/Custom messages

Custom messages

WuKongIM uses an integer contentType to distinguish message kinds. FoxTalk reserves base contentTypes in the base app, and extension modules register their own types into the IM service.

lib/src/modules/module_ids.dart centralises the contentTypes used by extension modules in ModuleMessageContentTypeIds. Recommended ranges:

1 ~ 99
Reserved by upstream WuKongIM (text / image / voice / video / card / location / file ...).
100 ~ 999
App-layer custom messages.
1000+
FoxTalk business additions (e.g. groupApprove=1009).

Examples: ModuleMessageContentTypeIds.location = 6, .file = 8, .gifSticker = 3, .lottieSticker = 12, .emojiSticker = 13. New contentTypes must first be checked against upstream WKConstant.h to avoid protocol clashes.

WKMessageContent interface

Custom message content extends WKMessageContent from wukongimfluttersdk and implements encodeJson / decodeJson — the IM service then routes encoding/decoding through the SDK pipeline automatically.

class WKLocationContent extends WKMessageContent {
  String address = '';
  String title = '';
  double latitude = 0;
  double longitude = 0;

  @override
  Map<String, dynamic> encodeJson() => {
        'address': address,
        'title': title,
        'latitude': latitude,
        'longitude': longitude,
      };

  @override
  WKMessageContent decodeJson(dynamic data) {
    // Populate fields from data...
    return this;
  }
}

Register a content handler

In the module's register method, call registerMessageContentHandler with the contentType and a decoder. LocationModule is a canonical example:

registry.registerMessageContentHandler(
  id: ModuleActionIds.messageLocationContent,
  moduleId: id,
  value: const MessageContentRegistration(
    contentType: ModuleMessageContentTypeIds.location,
    decoder: _decodeLocationContent,
  ),
);

WKLocationContent _decodeLocationContent(dynamic data) {
  return WKLocationContent().decodeJson(data) as WKLocationContent;
}

UI rendering

Bubble rendering is registered via registerMessageBubbleRenderer with a ModuleMessageBubbleRenderer. While iterating messages, the chat bubble list looks up renderers in the registry by contentType, falling back to an [unknown message] placeholder when none is found.

last updated · 2026-06