@yaoyuanchao/dingtalk 1.3.2 → 1.3.3

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": "@yaoyuanchao/dingtalk",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "type": "module",
5
5
  "description": "DingTalk channel plugin for Clawdbot with Stream Mode support",
6
6
  "license": "MIT",
package/src/api.ts CHANGED
@@ -93,12 +93,16 @@ export async function getDingTalkAccessToken(clientId: string, clientSecret: str
93
93
  export async function sendViaSessionWebhook(
94
94
  sessionWebhook: string,
95
95
  text: string,
96
- ): Promise<{ ok: boolean }> {
96
+ ): Promise<{ ok: boolean; errcode?: number; errmsg?: string }> {
97
97
  const res = await jsonPost(sessionWebhook, {
98
98
  msgtype: "text",
99
99
  text: { content: text },
100
100
  });
101
- return { ok: res?.errcode === 0 || !res?.errcode };
101
+ const ok = res?.errcode === 0 || !res?.errcode;
102
+ if (!ok) {
103
+ console.warn(`[dingtalk] SessionWebhook text error: errcode=${res?.errcode}, errmsg=${res?.errmsg}`);
104
+ }
105
+ return { ok, errcode: res?.errcode, errmsg: res?.errmsg };
102
106
  }
103
107
 
104
108
  /** Send markdown via sessionWebhook */
@@ -106,12 +110,16 @@ export async function sendMarkdownViaSessionWebhook(
106
110
  sessionWebhook: string,
107
111
  title: string,
108
112
  text: string,
109
- ): Promise<{ ok: boolean }> {
113
+ ): Promise<{ ok: boolean; errcode?: number; errmsg?: string }> {
110
114
  const res = await jsonPost(sessionWebhook, {
111
115
  msgtype: "markdown",
112
116
  markdown: { title, text },
113
117
  });
114
- return { ok: res?.errcode === 0 || !res?.errcode };
118
+ const ok = res?.errcode === 0 || !res?.errcode;
119
+ if (!ok) {
120
+ console.warn(`[dingtalk] SessionWebhook markdown error: errcode=${res?.errcode}, errmsg=${res?.errmsg}`);
121
+ }
122
+ return { ok, errcode: res?.errcode, errmsg: res?.errmsg };
115
123
  }
116
124
 
117
125
  /** Send image via sessionWebhook using markdown format */
package/src/monitor.ts CHANGED
@@ -577,10 +577,13 @@ async function processInboundMessage(
577
577
  cfg: actualCfg,
578
578
  dispatcherOptions: {
579
579
  deliver: async (payload: any) => {
580
+ log?.info?.("[dingtalk] Deliver payload keys: " + Object.keys(payload || {}).join(',') + " text?=" + (typeof payload?.text) + " markdown?=" + (typeof payload?.markdown));
580
581
  const textToSend = resolveDeliverText(payload, log);
581
582
  if (textToSend) {
582
583
  await deliverReply(replyTarget, textToSend, log);
583
584
  setStatus?.({ lastOutboundAt: Date.now() });
585
+ } else {
586
+ log?.info?.("[dingtalk] Deliver: no text resolved from payload");
584
587
  }
585
588
  },
586
589
  onError: (err: any) => {
@@ -680,8 +683,12 @@ async function dispatchWithFullPipeline(params: {
680
683
  responsePrefix: '',
681
684
  deliver: async (payload: any) => {
682
685
  try {
686
+ log?.info?.("[dingtalk] Pipeline deliver payload keys: " + Object.keys(payload || {}).join(',') + " text?=" + (typeof payload?.text) + " markdown?=" + (typeof payload?.markdown));
683
687
  const textToSend = resolveDeliverText(payload, log);
684
- if (!textToSend) return { ok: true };
688
+ if (!textToSend) {
689
+ log?.info?.("[dingtalk] Pipeline deliver: no text resolved from payload");
690
+ return { ok: true };
691
+ }
685
692
  await deliverReply(replyTarget, textToSend, log);
686
693
  setStatus?.({ lastOutboundAt: Date.now() });
687
694
  return { ok: true };
@@ -709,7 +716,15 @@ async function dispatchWithFullPipeline(params: {
709
716
  * We merge them into the text as markdown image syntax so DingTalk can render them.
710
717
  */
711
718
  function resolveDeliverText(payload: any, log?: any): string | undefined {
712
- let text = payload.markdown || payload.text;
719
+ // payload.markdown may be a boolean flag (not the actual text), so check type
720
+ let text = (typeof payload.markdown === 'string' && payload.markdown) || payload.text;
721
+
722
+ // Guard: ensure text is a string (platform might send unexpected types)
723
+ if (text != null && typeof text !== 'string') {
724
+ log?.info?.("[dingtalk] Deliver payload has non-string text type=" + typeof text + ", payload keys=" + Object.keys(payload).join(','));
725
+ text = String(text);
726
+ }
727
+
713
728
  const mediaUrl = payload.mediaUrl || payload.media || payload.imageUrl || payload.image;
714
729
 
715
730
  if (mediaUrl && typeof mediaUrl === 'string' && mediaUrl.startsWith('http')) {
@@ -762,13 +777,17 @@ async function deliverReply(target: any, text: string, log?: any): Promise<void>
762
777
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
763
778
  try {
764
779
  log?.info?.("[dingtalk] Using sessionWebhook (attempt " + attempt + "/" + maxRetries + "), format=" + messageFormat);
765
- log?.info?.("[dingtalk] Sending text: " + chunk.substring(0, 200));
780
+ log?.info?.("[dingtalk] Sending text (" + chunk.length + " chars): " + chunk.substring(0, 200));
781
+ let sendResult: { ok: boolean; errcode?: number; errmsg?: string };
766
782
  if (isMarkdown) {
767
- await sendMarkdownViaSessionWebhook(target.sessionWebhook, "Reply", chunk);
783
+ sendResult = await sendMarkdownViaSessionWebhook(target.sessionWebhook, "Reply", chunk);
768
784
  } else {
769
- await sendViaSessionWebhook(target.sessionWebhook, chunk);
785
+ sendResult = await sendViaSessionWebhook(target.sessionWebhook, chunk);
786
+ }
787
+ if (!sendResult.ok) {
788
+ throw new Error(`SessionWebhook rejected: errcode=${sendResult.errcode}, errmsg=${sendResult.errmsg}`);
770
789
  }
771
- log?.info?.("[dingtalk] SessionWebhook send OK");
790
+ log?.info?.("[dingtalk] SessionWebhook send OK (errcode=" + (sendResult.errcode ?? 0) + ")");
772
791
  webhookSuccess = true;
773
792
  break;
774
793
  } catch (err) {