@qihoo/tuitui-openclaw-channel 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qihoo/tuitui-openclaw-channel",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "maintainers": [
5
5
  {
6
6
  "name": "huzunjie",
package/src/channel.ts CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  deleteAccountFromConfigSection,
13
13
  buildChannelConfigSchema,
14
14
  } from 'openclaw/plugin-sdk';
15
- import type { TuiTuiInboundMessage } from './types';
15
+ import type { TuiTuiInboundMessage, TuiTuiOutboundDeliverOptions } from './types';
16
16
  import {
17
17
  CHANNEL_ID,
18
18
  CHANNEL_NAME,
@@ -293,7 +293,7 @@ export function createTuiTuiChannelPlugin(apiRuntime: any) {
293
293
  return { channel: CHANNEL_ID, messageId: `tuitui-page-${Date.now()}`, chatId };
294
294
  },
295
295
 
296
- sendMedia: async ({ cfg, to, payload, mediaUrl, accountId, account }: any) => {
296
+ sendMedia: async ({ cfg, to, mediaUrl, accountId, account }: any) => {
297
297
  account = account || resolveAccount(cfg, accountId);
298
298
  checkAccount(account, 'send media');
299
299
 
@@ -446,16 +446,10 @@ export function createTuiTuiChannelPlugin(apiRuntime: any) {
446
446
  const groupCfg = account.groups?.[String(groupId)];
447
447
 
448
448
  // @机器人触发策略
449
- let requireMention = true;
450
- if (groupCfg && typeof groupCfg.requireMention === 'boolean') {
451
- requireMention = groupCfg.requireMention;
452
- }
449
+ const requireMention = typeof groupCfg?.requireMention === 'boolean' ? groupCfg.requireMention : true;
453
450
 
454
451
  // 是否需要回复
455
- let shouldReply = true;
456
- if (groupCfg !== undefined && typeof groupCfg.shouldReply === 'boolean') {
457
- shouldReply = groupCfg.shouldReply;
458
- }
452
+ let shouldReply = typeof groupCfg?.shouldReply === 'boolean' ? groupCfg.shouldReply : true;
459
453
 
460
454
  if (!userAccount || !groupId) {
461
455
  log?.info?.(`[${CHANNEL_ID}] Missing user_account or group_id in group_chat event`);
@@ -598,6 +592,8 @@ export function createTuiTuiChannelPlugin(apiRuntime: any) {
598
592
  Surface: CHANNEL_ID,
599
593
  Provider: CHANNEL_ID,
600
594
  SenderName: msgUname || String(senderId),
595
+ MsgUname: msgUname,
596
+ UserAccount: userAccount,
601
597
  };
602
598
 
603
599
  // Add group-specific fields
@@ -617,23 +613,11 @@ export function createTuiTuiChannelPlugin(apiRuntime: any) {
617
613
  log?.error?.(`[${CHANNEL_ID}] TuiTuiRuntime error,未能发送回复。`);
618
614
  return;
619
615
  }
620
- const currentCfg = await apiRuntime.config.loadConfig();
621
616
  await apiRuntime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
622
617
  ctx: msgCtx,
623
- cfg: currentCfg,
618
+ cfg: await apiRuntime.config.loadConfig(),
624
619
  dispatcherOptions: {
625
- deliver: async (payload: {
626
- text?: string;
627
- body?: string;
628
- mediaUrl?: string;
629
- mediaUrls?: string[];
630
- custom?: {
631
- msgtype: string;
632
- tousers?: string[];
633
- togroups?: string[];
634
- [key: string]: any;
635
- };
636
- }) => {
620
+ deliver: async (payload: TuiTuiOutboundDeliverOptions) => {
637
621
 
638
622
  // 如果设置了 suppressReply 标志,则不发送回复
639
623
  if (suppressReply) {
@@ -657,7 +641,7 @@ export function createTuiTuiChannelPlugin(apiRuntime: any) {
657
641
  // Handle media messages
658
642
  const mediaUrl = payload.mediaUrl || payload.mediaUrls?.[0];
659
643
  if (mediaUrl) {
660
- const at = chatTypeIsGroup ? [msgUname] : [];
644
+ const at = chatTypeIsGroup && userAccount ? [userAccount] : [];
661
645
  await sendMediaMsg(account, chatTarget, chatTypeIsGroup, mediaUrl, 'tuitui.deliver.media', at);
662
646
  }
663
647
  return;
@@ -666,9 +650,9 @@ export function createTuiTuiChannelPlugin(apiRuntime: any) {
666
650
  const replyText = payload?.text || payload?.body;
667
651
  if (replyText) {
668
652
  // at 使用 userAccount(群聊 @ 用户)
669
- const atList = chatTypeIsGroup && userAccount ? [userAccount] : [];
653
+ const at = chatTypeIsGroup && userAccount ? [userAccount] : [];
670
654
  // 群消息回复时不再使用 reference_msgid 避免并发时引用错乱,依靠 @ 来提醒用户
671
- await sendTextMsg(account, chatTarget, chatTypeIsGroup, replyText, 'tuitui.deliver.text', atList);
655
+ await sendTextMsg(account, chatTarget, chatTypeIsGroup, replyText, 'tuitui.deliver.text', at);
672
656
  }
673
657
  },
674
658
  onReplyStart: () => {
@@ -679,11 +663,12 @@ export function createTuiTuiChannelPlugin(apiRuntime: any) {
679
663
  });
680
664
 
681
665
  const onErrOrClose = () => {
666
+ if (ws && ws.readyState !== WebSocket.CLOSED) ws.close(); // 关闭超时链接,防止产生多个
682
667
  _setStatus({ running: false, connected: false });
683
668
  _sendMsg = defSendMsg;
684
669
  if (!abortSignal?.aborted) {
685
670
  log?.warn?.(`[${CHANNEL_ID}] WebSocket Restart`);
686
- startWebSocket(); // 重启
671
+ setTimeout(startWebSocket, 10e3); // 10秒后尝试重启
687
672
  }
688
673
  };
689
674
  ws.on('close', () => {
package/src/types.ts CHANGED
@@ -115,3 +115,16 @@ export interface TuiTuiGroupEmojiReactionTarget {
115
115
  group?: string;
116
116
  msgid?: string;
117
117
  }
118
+
119
+ export interface TuiTuiOutboundDeliverOptions {
120
+ text?: string;
121
+ body?: string;
122
+ mediaUrl?: string;
123
+ mediaUrls?: string[];
124
+ custom?: {
125
+ msgtype: string;
126
+ tousers?: string[];
127
+ togroups?: string[];
128
+ [key: string]: any;
129
+ };
130
+ }