diff --git a/src/mixins/message-mixin.ts b/src/mixins/message-mixin.ts
index 8cae91d3..4204c267 100644
--- a/src/mixins/message-mixin.ts
+++ b/src/mixins/message-mixin.ts
@@ -37,6 +37,7 @@ import {
   type SayablePayload,
   sayableTypes,
 }                                 from '../schemas/sayable.js'
+import type { ChannelPayload } from '../schemas/channel.js'
 
 const filebox = (filebox: string | FileBoxInterface) => typeof filebox === 'string' ? FileBox.fromJSON(filebox) : filebox
 
@@ -67,6 +68,7 @@ const messageMixin = <MinxinBase extends typeof PuppetSkeleton & CacheMixin>(bas
     abstract messageMiniProgram  (messageId: string)                       : Promise<MiniProgramPayload>
     abstract messageUrl          (messageId: string)                       : Promise<UrlLinkPayload>
     abstract messageLocation     (messageId: string)                       : Promise<LocationPayload>
+    abstract messageChannel      (messageId: string)                       : Promise<ChannelPayload>
 
     abstract messageForward         (conversationId: string, messageId: string,)                     : Promise<void | string>
     abstract messageSendContact     (conversationId: string, contactId: string)                      : Promise<void | string>
@@ -76,6 +78,7 @@ const messageMixin = <MinxinBase extends typeof PuppetSkeleton & CacheMixin>(bas
     abstract messageSendPost        (conversationId: string, postPayload: PostPayload)               : Promise<void | string>
     abstract messageSendText        (conversationId: string, text: string, mentionIdList?: string[]) : Promise<void | string>
     abstract messageSendUrl         (conversationId: string, urlLinkPayload: UrlLinkPayload)         : Promise<void | string>
+    abstract messageSendChannel     (conversationId: string, channelPayload: ChannelPayload)         : Promise<void | string>
 
     abstract messageRecall (messageId: string) : Promise<boolean>
 
@@ -280,6 +283,8 @@ const messageMixin = <MinxinBase extends typeof PuppetSkeleton & CacheMixin>(bas
           return this.messageSendText(conversationId, sayable.payload.text, sayable.payload.mentions)
         case sayableTypes.Post:
           return this.messageSendPost(conversationId, sayable.payload)
+        case sayableTypes.Channel:
+          return this.messageSendChannel(conversationId, sayable.payload)
         default:
           throw new Error('unsupported sayable payload: ' + JSON.stringify(sayable))
       }
diff --git a/src/mixins/sayable-mixin.ts b/src/mixins/sayable-mixin.ts
index 97f5faf3..dc985227 100644
--- a/src/mixins/sayable-mixin.ts
+++ b/src/mixins/sayable-mixin.ts
@@ -60,6 +60,10 @@ const sayableMixin = <MixinBase extends typeof PuppetSkeleton & MessageMixin & P
           const postPayload = await this.postPayload(sayableId)
           return sayablePayloads.post(postPayload)
         }
+        case MessageType.Channel: {
+          const channelPayload = await this.messageChannel(sayableId)
+          return sayablePayloads.channel(channelPayload)
+        }
 
         default:
           log.warn('PuppetSayableMixin',
diff --git a/src/mods/payloads.ts b/src/mods/payloads.ts
index bcea15aa..e360d917 100644
--- a/src/mods/payloads.ts
+++ b/src/mods/payloads.ts
@@ -36,6 +36,7 @@ import type {
   TapPayload,
   UrlLinkPayload,
   SayablePayload,
+  ChannelPayload,
 }                           from '../schemas/mod.js'
 import {
   sayablePayloads,
@@ -81,6 +82,7 @@ export type {
   SayablePayload            as Sayable,
   TapPayload                as Tap,
   UrlLinkPayload            as UrlLink,
+  ChannelPayload            as Channel,
 }
 export {
   sayablePayloads as sayable, // Sayable payload creators
diff --git a/src/mods/types.ts b/src/mods/types.ts
index 89823aad..9b955d50 100644
--- a/src/mods/types.ts
+++ b/src/mods/types.ts
@@ -12,6 +12,7 @@ import {
   PostType,
   TapType,
   sayableTypes,
+  ChannelType,
 
   CHAT_EVENT_DICT,
   PUPPET_EVENT_DICT,
@@ -32,6 +33,7 @@ export {
   PostType            as Post,
   TapType             as Tap,
   sayableTypes        as Sayable,
+  ChannelType         as Channel,
   /**
    * Huan(202201): `DirtyType as Payload` will be removed after Dec 31, 2023
    * @deprecated: use Dirty instead of Payload
diff --git a/src/schemas/channel.ts b/src/schemas/channel.ts
new file mode 100644
index 00000000..3f2264be
--- /dev/null
+++ b/src/schemas/channel.ts
@@ -0,0 +1,19 @@
+export interface ChannelPayload {
+  avatar: string,
+  coverUrl: string,
+  desc: string,
+  extras: string,
+  feedType: number,
+  nickname: string,
+  thumbUrl: string,
+  url: string,
+  objectId?: string,
+  objectNonceId?: string,
+}
+
+export enum ChannelType {
+  Unknown = 0,
+  Photo = 2,
+  Video = 4,
+  Live = 9,
+}
diff --git a/src/schemas/message.ts b/src/schemas/message.ts
index 4d10970f..9357a5a0 100644
--- a/src/schemas/message.ts
+++ b/src/schemas/message.ts
@@ -20,7 +20,7 @@ export enum MessageType {
   Url         = 14,   // Url(5)
   Video       = 15,   // Video(4), Video(43)
   Post        = 16,   // Moment, Channel, Tweet, etc
-
+  Channel     = 17,   // Channel
   System      = 18,   // System Message
 }
 
diff --git a/src/schemas/mod.ts b/src/schemas/mod.ts
index 56bc8959..292d0257 100644
--- a/src/schemas/mod.ts
+++ b/src/schemas/mod.ts
@@ -93,6 +93,11 @@ import type {
   ChatEventName,
 }                         from './puppet.js'
 
+import {
+  type ChannelPayload,
+  ChannelType,
+} from './channel.js'
+
 import {
   sayablePayloads,
   sayableTypes,
@@ -122,6 +127,7 @@ export {
   sayableTypes,
   ScanStatus,
   TapType,
+  ChannelType,
   type ChatEventName,
   type ContactPayload,
   type ContactQueryFilter,
@@ -170,5 +176,6 @@ export {
   type TapPayload,
   type TapQueryFilter,
   type UrlLinkPayload,
+  type ChannelPayload,
   YOU,
 }
diff --git a/src/schemas/sayable.ts b/src/schemas/sayable.ts
index f2a23b8f..53503f29 100644
--- a/src/schemas/sayable.ts
+++ b/src/schemas/sayable.ts
@@ -6,6 +6,7 @@ import { MessageType }              from './message.js'
 import type { LocationPayload }     from './location.js'
 import type { UrlLinkPayload }      from './url-link.js'
 import type { MiniProgramPayload }  from './mini-program.js'
+import type { ChannelPayload }      from './channel.js'
 import type {
   PostPayload,
   SayablePayloadPost,
@@ -21,6 +22,7 @@ const payloadLocation    = (locationPayload: LocationPayload)       => ({ ...loc
 const payloadMiniProgram = (miniProgramPayload: MiniProgramPayload) => ({ ...miniProgramPayload })
 const payloadUrlLink     = (urlLinkPayload: UrlLinkPayload)         => ({ ...urlLinkPayload })
 const payloadPost        = (postPayload: PostPayload)               => ({ ...postPayload })
+const payloadChannel     = (channelPayload: ChannelPayload)         => ({ ...channelPayload })
 
 /**
  * using `types` as a static typed string name list for `createAction`
@@ -61,6 +63,7 @@ const location    = createAction(sayableTypes.Location,    payloadLocation)()
 const miniProgram = createAction(sayableTypes.MiniProgram, payloadMiniProgram)()
 const url         = createAction(sayableTypes.Url,         payloadUrlLink)()
 const post        = createAction(sayableTypes.Post,        payloadPost)()
+const channel     = createAction(sayableTypes.Channel,     payloadChannel)()
 
 /**
  * Huan(202201): Recursive type references
@@ -77,6 +80,7 @@ const sayablePayloadsNoPost = {
   text,
   url,
   video,
+  channel,
 } as const
 
 /**