@lark-project/openclaw-lark-project 2026.3.131

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.
Files changed (368) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -0
  3. package/README.zh.md +80 -0
  4. package/dist/index.js +172 -0
  5. package/dist/index.js.map +7 -0
  6. package/dist/skills/feishu-bitable/SKILL.md +248 -0
  7. package/dist/skills/feishu-bitable/references/examples.md +813 -0
  8. package/dist/skills/feishu-bitable/references/field-properties.md +763 -0
  9. package/dist/skills/feishu-bitable/references/record-values.md +911 -0
  10. package/dist/skills/feishu-calendar/SKILL.md +244 -0
  11. package/dist/skills/feishu-channel-rules/SKILL.md +18 -0
  12. package/dist/skills/feishu-channel-rules/references/markdown-syntax.md +138 -0
  13. package/dist/skills/feishu-create-doc/SKILL.md +719 -0
  14. package/dist/skills/feishu-fetch-doc/SKILL.md +93 -0
  15. package/dist/skills/feishu-im-read/SKILL.md +163 -0
  16. package/dist/skills/feishu-project/SKILL.md +122 -0
  17. package/dist/skills/feishu-task/SKILL.md +293 -0
  18. package/dist/skills/feishu-troubleshoot/SKILL.md +70 -0
  19. package/dist/skills/feishu-update-doc/SKILL.md +285 -0
  20. package/dist/src/card/builder.js +293 -0
  21. package/dist/src/card/builder.js.map +7 -0
  22. package/dist/src/card/cardkit.js +126 -0
  23. package/dist/src/card/cardkit.js.map +7 -0
  24. package/dist/src/card/flush-controller.js +107 -0
  25. package/dist/src/card/flush-controller.js.map +7 -0
  26. package/dist/src/card/markdown-style.js +57 -0
  27. package/dist/src/card/markdown-style.js.map +7 -0
  28. package/dist/src/card/reply-dispatcher-types.js +39 -0
  29. package/dist/src/card/reply-dispatcher-types.js.map +7 -0
  30. package/dist/src/card/reply-dispatcher.js +245 -0
  31. package/dist/src/card/reply-dispatcher.js.map +7 -0
  32. package/dist/src/card/reply-mode.js +29 -0
  33. package/dist/src/card/reply-mode.js.map +7 -0
  34. package/dist/src/card/streaming-card-controller.js +653 -0
  35. package/dist/src/card/streaming-card-controller.js.map +7 -0
  36. package/dist/src/card/unavailable-guard.js +76 -0
  37. package/dist/src/card/unavailable-guard.js.map +7 -0
  38. package/dist/src/channel/abort-detect.js +79 -0
  39. package/dist/src/channel/abort-detect.js.map +7 -0
  40. package/dist/src/channel/chat-queue.js +50 -0
  41. package/dist/src/channel/chat-queue.js.map +7 -0
  42. package/dist/src/channel/config-adapter.js +89 -0
  43. package/dist/src/channel/config-adapter.js.map +7 -0
  44. package/dist/src/channel/directory.js +133 -0
  45. package/dist/src/channel/directory.js.map +7 -0
  46. package/dist/src/channel/event-handlers.js +175 -0
  47. package/dist/src/channel/event-handlers.js.map +7 -0
  48. package/dist/src/channel/monitor.js +108 -0
  49. package/dist/src/channel/monitor.js.map +7 -0
  50. package/dist/src/channel/onboarding-config.js +76 -0
  51. package/dist/src/channel/onboarding-config.js.map +7 -0
  52. package/dist/src/channel/onboarding-migrate.js +55 -0
  53. package/dist/src/channel/onboarding-migrate.js.map +7 -0
  54. package/dist/src/channel/onboarding.js +285 -0
  55. package/dist/src/channel/onboarding.js.map +7 -0
  56. package/dist/src/channel/plugin.js +260 -0
  57. package/dist/src/channel/plugin.js.map +7 -0
  58. package/dist/src/channel/probe.js +14 -0
  59. package/dist/src/channel/probe.js.map +7 -0
  60. package/dist/src/channel/types.js +1 -0
  61. package/dist/src/channel/types.js.map +7 -0
  62. package/dist/src/commands/auth.js +73 -0
  63. package/dist/src/commands/auth.js.map +7 -0
  64. package/dist/src/commands/diagnose.js +658 -0
  65. package/dist/src/commands/diagnose.js.map +7 -0
  66. package/dist/src/commands/doctor.js +327 -0
  67. package/dist/src/commands/doctor.js.map +7 -0
  68. package/dist/src/commands/index.js +124 -0
  69. package/dist/src/commands/index.js.map +7 -0
  70. package/dist/src/core/accounts.js +129 -0
  71. package/dist/src/core/accounts.js.map +7 -0
  72. package/dist/src/core/agent-config.js +60 -0
  73. package/dist/src/core/agent-config.js.map +7 -0
  74. package/dist/src/core/api-error.js +55 -0
  75. package/dist/src/core/api-error.js.map +7 -0
  76. package/dist/src/core/app-owner-fallback.js +17 -0
  77. package/dist/src/core/app-owner-fallback.js.map +7 -0
  78. package/dist/src/core/app-scope-checker.js +95 -0
  79. package/dist/src/core/app-scope-checker.js.map +7 -0
  80. package/dist/src/core/auth-errors.js +120 -0
  81. package/dist/src/core/auth-errors.js.map +7 -0
  82. package/dist/src/core/chat-info-cache.js +102 -0
  83. package/dist/src/core/chat-info-cache.js.map +7 -0
  84. package/dist/src/core/config-schema.js +150 -0
  85. package/dist/src/core/config-schema.js.map +7 -0
  86. package/dist/src/core/device-flow.js +174 -0
  87. package/dist/src/core/device-flow.js.map +7 -0
  88. package/dist/src/core/feishu-fetch.js +12 -0
  89. package/dist/src/core/feishu-fetch.js.map +7 -0
  90. package/dist/src/core/footer-config.js +16 -0
  91. package/dist/src/core/footer-config.js.map +7 -0
  92. package/dist/src/core/lark-client.js +322 -0
  93. package/dist/src/core/lark-client.js.map +7 -0
  94. package/dist/src/core/lark-logger.js +92 -0
  95. package/dist/src/core/lark-logger.js.map +7 -0
  96. package/dist/src/core/lark-ticket.js +18 -0
  97. package/dist/src/core/lark-ticket.js.map +7 -0
  98. package/dist/src/core/message-unavailable.js +119 -0
  99. package/dist/src/core/message-unavailable.js.map +7 -0
  100. package/dist/src/core/owner-policy.js +25 -0
  101. package/dist/src/core/owner-policy.js.map +7 -0
  102. package/dist/src/core/permission-url.js +37 -0
  103. package/dist/src/core/permission-url.js.map +7 -0
  104. package/dist/src/core/project-auth.js +177 -0
  105. package/dist/src/core/project-auth.js.map +7 -0
  106. package/dist/src/core/project-oauth-flow.js +124 -0
  107. package/dist/src/core/project-oauth-flow.js.map +7 -0
  108. package/dist/src/core/project-token-store.js +172 -0
  109. package/dist/src/core/project-token-store.js.map +7 -0
  110. package/dist/src/core/raw-request.js +45 -0
  111. package/dist/src/core/raw-request.js.map +7 -0
  112. package/dist/src/core/scope-manager.js +62 -0
  113. package/dist/src/core/scope-manager.js.map +7 -0
  114. package/dist/src/core/security-check.js +118 -0
  115. package/dist/src/core/security-check.js.map +7 -0
  116. package/dist/src/core/shutdown-hooks.js +37 -0
  117. package/dist/src/core/shutdown-hooks.js.map +7 -0
  118. package/dist/src/core/targets.js +55 -0
  119. package/dist/src/core/targets.js.map +7 -0
  120. package/dist/src/core/token-store.js +215 -0
  121. package/dist/src/core/token-store.js.map +7 -0
  122. package/dist/src/core/tool-client.js +335 -0
  123. package/dist/src/core/tool-client.js.map +7 -0
  124. package/dist/src/core/tool-scopes.js +207 -0
  125. package/dist/src/core/tool-scopes.js.map +7 -0
  126. package/dist/src/core/tools-config.js +57 -0
  127. package/dist/src/core/tools-config.js.map +7 -0
  128. package/dist/src/core/types.js +1 -0
  129. package/dist/src/core/types.js.map +7 -0
  130. package/dist/src/core/uat-client.js +124 -0
  131. package/dist/src/core/uat-client.js.map +7 -0
  132. package/dist/src/core/version.js +27 -0
  133. package/dist/src/core/version.js.map +7 -0
  134. package/dist/src/messaging/converters/audio.js +19 -0
  135. package/dist/src/messaging/converters/audio.js.map +7 -0
  136. package/dist/src/messaging/converters/calendar.js +46 -0
  137. package/dist/src/messaging/converters/calendar.js.map +7 -0
  138. package/dist/src/messaging/converters/content-converter.js +61 -0
  139. package/dist/src/messaging/converters/content-converter.js.map +7 -0
  140. package/dist/src/messaging/converters/file.js +18 -0
  141. package/dist/src/messaging/converters/file.js.map +7 -0
  142. package/dist/src/messaging/converters/folder.js +18 -0
  143. package/dist/src/messaging/converters/folder.js.map +7 -0
  144. package/dist/src/messaging/converters/hongbao.js +14 -0
  145. package/dist/src/messaging/converters/hongbao.js.map +7 -0
  146. package/dist/src/messaging/converters/image.js +16 -0
  147. package/dist/src/messaging/converters/image.js.map +7 -0
  148. package/dist/src/messaging/converters/index.js +48 -0
  149. package/dist/src/messaging/converters/index.js.map +7 -0
  150. package/dist/src/messaging/converters/interactive/card-converter.js +1040 -0
  151. package/dist/src/messaging/converters/interactive/card-converter.js.map +7 -0
  152. package/dist/src/messaging/converters/interactive/card-utils.js +36 -0
  153. package/dist/src/messaging/converters/interactive/card-utils.js.map +7 -0
  154. package/dist/src/messaging/converters/interactive/index.js +19 -0
  155. package/dist/src/messaging/converters/interactive/index.js.map +7 -0
  156. package/dist/src/messaging/converters/interactive/legacy.js +53 -0
  157. package/dist/src/messaging/converters/interactive/legacy.js.map +7 -0
  158. package/dist/src/messaging/converters/interactive/types.js +23 -0
  159. package/dist/src/messaging/converters/interactive/types.js.map +7 -0
  160. package/dist/src/messaging/converters/location.js +17 -0
  161. package/dist/src/messaging/converters/location.js.map +7 -0
  162. package/dist/src/messaging/converters/merge-forward.js +143 -0
  163. package/dist/src/messaging/converters/merge-forward.js.map +7 -0
  164. package/dist/src/messaging/converters/post.js +113 -0
  165. package/dist/src/messaging/converters/post.js.map +7 -0
  166. package/dist/src/messaging/converters/share.js +22 -0
  167. package/dist/src/messaging/converters/share.js.map +7 -0
  168. package/dist/src/messaging/converters/sticker.js +16 -0
  169. package/dist/src/messaging/converters/sticker.js.map +7 -0
  170. package/dist/src/messaging/converters/system.js +25 -0
  171. package/dist/src/messaging/converters/system.js.map +7 -0
  172. package/dist/src/messaging/converters/text.js +12 -0
  173. package/dist/src/messaging/converters/text.js.map +7 -0
  174. package/dist/src/messaging/converters/todo.js +37 -0
  175. package/dist/src/messaging/converters/todo.js.map +7 -0
  176. package/dist/src/messaging/converters/types.js +1 -0
  177. package/dist/src/messaging/converters/types.js.map +7 -0
  178. package/dist/src/messaging/converters/unknown.js +13 -0
  179. package/dist/src/messaging/converters/unknown.js.map +7 -0
  180. package/dist/src/messaging/converters/utils.js +35 -0
  181. package/dist/src/messaging/converters/utils.js.map +7 -0
  182. package/dist/src/messaging/converters/video-chat.js +21 -0
  183. package/dist/src/messaging/converters/video-chat.js.map +7 -0
  184. package/dist/src/messaging/converters/video.js +30 -0
  185. package/dist/src/messaging/converters/video.js.map +7 -0
  186. package/dist/src/messaging/converters/vote.js +24 -0
  187. package/dist/src/messaging/converters/vote.js.map +7 -0
  188. package/dist/src/messaging/inbound/dedup.js +82 -0
  189. package/dist/src/messaging/inbound/dedup.js.map +7 -0
  190. package/dist/src/messaging/inbound/dispatch-builders.js +98 -0
  191. package/dist/src/messaging/inbound/dispatch-builders.js.map +7 -0
  192. package/dist/src/messaging/inbound/dispatch-commands.js +94 -0
  193. package/dist/src/messaging/inbound/dispatch-commands.js.map +7 -0
  194. package/dist/src/messaging/inbound/dispatch-context.js +96 -0
  195. package/dist/src/messaging/inbound/dispatch-context.js.map +7 -0
  196. package/dist/src/messaging/inbound/dispatch.js +150 -0
  197. package/dist/src/messaging/inbound/dispatch.js.map +7 -0
  198. package/dist/src/messaging/inbound/enrich.js +137 -0
  199. package/dist/src/messaging/inbound/enrich.js.map +7 -0
  200. package/dist/src/messaging/inbound/gate-effects.js +28 -0
  201. package/dist/src/messaging/inbound/gate-effects.js.map +7 -0
  202. package/dist/src/messaging/inbound/gate.js +163 -0
  203. package/dist/src/messaging/inbound/gate.js.map +7 -0
  204. package/dist/src/messaging/inbound/handler.js +132 -0
  205. package/dist/src/messaging/inbound/handler.js.map +7 -0
  206. package/dist/src/messaging/inbound/media-resolver.js +70 -0
  207. package/dist/src/messaging/inbound/media-resolver.js.map +7 -0
  208. package/dist/src/messaging/inbound/mention.js +50 -0
  209. package/dist/src/messaging/inbound/mention.js.map +7 -0
  210. package/dist/src/messaging/inbound/parse-io.js +41 -0
  211. package/dist/src/messaging/inbound/parse-io.js.map +7 -0
  212. package/dist/src/messaging/inbound/parse.js +79 -0
  213. package/dist/src/messaging/inbound/parse.js.map +7 -0
  214. package/dist/src/messaging/inbound/permission.js +30 -0
  215. package/dist/src/messaging/inbound/permission.js.map +7 -0
  216. package/dist/src/messaging/inbound/policy.js +83 -0
  217. package/dist/src/messaging/inbound/policy.js.map +7 -0
  218. package/dist/src/messaging/inbound/reaction-handler.js +162 -0
  219. package/dist/src/messaging/inbound/reaction-handler.js.map +7 -0
  220. package/dist/src/messaging/inbound/user-name-cache.js +172 -0
  221. package/dist/src/messaging/inbound/user-name-cache.js.map +7 -0
  222. package/dist/src/messaging/outbound/actions.js +239 -0
  223. package/dist/src/messaging/outbound/actions.js.map +7 -0
  224. package/dist/src/messaging/outbound/chat-manage.js +74 -0
  225. package/dist/src/messaging/outbound/chat-manage.js.map +7 -0
  226. package/dist/src/messaging/outbound/deliver.js +162 -0
  227. package/dist/src/messaging/outbound/deliver.js.map +7 -0
  228. package/dist/src/messaging/outbound/fetch.js +7 -0
  229. package/dist/src/messaging/outbound/fetch.js.map +7 -0
  230. package/dist/src/messaging/outbound/forward.js +31 -0
  231. package/dist/src/messaging/outbound/forward.js.map +7 -0
  232. package/dist/src/messaging/outbound/media-url-utils.js +101 -0
  233. package/dist/src/messaging/outbound/media-url-utils.js.map +7 -0
  234. package/dist/src/messaging/outbound/media.js +463 -0
  235. package/dist/src/messaging/outbound/media.js.map +7 -0
  236. package/dist/src/messaging/outbound/outbound.js +95 -0
  237. package/dist/src/messaging/outbound/outbound.js.map +7 -0
  238. package/dist/src/messaging/outbound/reactions.js +312 -0
  239. package/dist/src/messaging/outbound/reactions.js.map +7 -0
  240. package/dist/src/messaging/outbound/send.js +194 -0
  241. package/dist/src/messaging/outbound/send.js.map +7 -0
  242. package/dist/src/messaging/outbound/typing.js +77 -0
  243. package/dist/src/messaging/outbound/typing.js.map +7 -0
  244. package/dist/src/messaging/shared/message-lookup.js +84 -0
  245. package/dist/src/messaging/shared/message-lookup.js.map +7 -0
  246. package/dist/src/messaging/types.js +1 -0
  247. package/dist/src/messaging/types.js.map +7 -0
  248. package/dist/src/tools/auto-auth.js +714 -0
  249. package/dist/src/tools/auto-auth.js.map +7 -0
  250. package/dist/src/tools/helpers.js +133 -0
  251. package/dist/src/tools/helpers.js.map +7 -0
  252. package/dist/src/tools/mcp/doc/create.js +35 -0
  253. package/dist/src/tools/mcp/doc/create.js.map +7 -0
  254. package/dist/src/tools/mcp/doc/fetch.js +33 -0
  255. package/dist/src/tools/mcp/doc/fetch.js.map +7 -0
  256. package/dist/src/tools/mcp/doc/index.js +32 -0
  257. package/dist/src/tools/mcp/doc/index.js.map +7 -0
  258. package/dist/src/tools/mcp/doc/update.js +61 -0
  259. package/dist/src/tools/mcp/doc/update.js.map +7 -0
  260. package/dist/src/tools/mcp/project/endpoint.js +25 -0
  261. package/dist/src/tools/mcp/project/endpoint.js.map +7 -0
  262. package/dist/src/tools/mcp/project/index.js +27 -0
  263. package/dist/src/tools/mcp/project/index.js.map +7 -0
  264. package/dist/src/tools/mcp/project/tools.js +579 -0
  265. package/dist/src/tools/mcp/project/tools.js.map +7 -0
  266. package/dist/src/tools/mcp/shared.js +170 -0
  267. package/dist/src/tools/mcp/shared.js.map +7 -0
  268. package/dist/src/tools/oapi/bitable/app-table-field.js +244 -0
  269. package/dist/src/tools/oapi/bitable/app-table-field.js.map +7 -0
  270. package/dist/src/tools/oapi/bitable/app-table-record.js +501 -0
  271. package/dist/src/tools/oapi/bitable/app-table-record.js.map +7 -0
  272. package/dist/src/tools/oapi/bitable/app-table-view.js +226 -0
  273. package/dist/src/tools/oapi/bitable/app-table-view.js.map +7 -0
  274. package/dist/src/tools/oapi/bitable/app-table.js +278 -0
  275. package/dist/src/tools/oapi/bitable/app-table.js.map +7 -0
  276. package/dist/src/tools/oapi/bitable/app.js +200 -0
  277. package/dist/src/tools/oapi/bitable/app.js.map +7 -0
  278. package/dist/src/tools/oapi/bitable/index.js +13 -0
  279. package/dist/src/tools/oapi/bitable/index.js.map +7 -0
  280. package/dist/src/tools/oapi/calendar/calendar.js +131 -0
  281. package/dist/src/tools/oapi/calendar/calendar.js.map +7 -0
  282. package/dist/src/tools/oapi/calendar/event-attendee.js +301 -0
  283. package/dist/src/tools/oapi/calendar/event-attendee.js.map +7 -0
  284. package/dist/src/tools/oapi/calendar/event.js +834 -0
  285. package/dist/src/tools/oapi/calendar/event.js.map +7 -0
  286. package/dist/src/tools/oapi/calendar/freebusy.js +111 -0
  287. package/dist/src/tools/oapi/calendar/freebusy.js.map +7 -0
  288. package/dist/src/tools/oapi/calendar/index.js +11 -0
  289. package/dist/src/tools/oapi/calendar/index.js.map +7 -0
  290. package/dist/src/tools/oapi/chat/chat.js +132 -0
  291. package/dist/src/tools/oapi/chat/chat.js.map +7 -0
  292. package/dist/src/tools/oapi/chat/index.js +11 -0
  293. package/dist/src/tools/oapi/chat/index.js.map +7 -0
  294. package/dist/src/tools/oapi/chat/members.js +83 -0
  295. package/dist/src/tools/oapi/chat/members.js.map +7 -0
  296. package/dist/src/tools/oapi/common/get-user.js +95 -0
  297. package/dist/src/tools/oapi/common/get-user.js.map +7 -0
  298. package/dist/src/tools/oapi/common/index.js +7 -0
  299. package/dist/src/tools/oapi/common/index.js.map +7 -0
  300. package/dist/src/tools/oapi/common/search-user.js +67 -0
  301. package/dist/src/tools/oapi/common/search-user.js.map +7 -0
  302. package/dist/src/tools/oapi/drive/doc-comments.js +310 -0
  303. package/dist/src/tools/oapi/drive/doc-comments.js.map +7 -0
  304. package/dist/src/tools/oapi/drive/doc-media.js +314 -0
  305. package/dist/src/tools/oapi/drive/doc-media.js.map +7 -0
  306. package/dist/src/tools/oapi/drive/file.js +548 -0
  307. package/dist/src/tools/oapi/drive/file.js.map +7 -0
  308. package/dist/src/tools/oapi/drive/index.js +29 -0
  309. package/dist/src/tools/oapi/drive/index.js.map +7 -0
  310. package/dist/src/tools/oapi/helpers.js +199 -0
  311. package/dist/src/tools/oapi/helpers.js.map +7 -0
  312. package/dist/src/tools/oapi/im/format-messages.js +128 -0
  313. package/dist/src/tools/oapi/im/format-messages.js.map +7 -0
  314. package/dist/src/tools/oapi/im/index.js +15 -0
  315. package/dist/src/tools/oapi/im/index.js.map +7 -0
  316. package/dist/src/tools/oapi/im/message-read.js +404 -0
  317. package/dist/src/tools/oapi/im/message-read.js.map +7 -0
  318. package/dist/src/tools/oapi/im/message.js +179 -0
  319. package/dist/src/tools/oapi/im/message.js.map +7 -0
  320. package/dist/src/tools/oapi/im/resource.js +126 -0
  321. package/dist/src/tools/oapi/im/resource.js.map +7 -0
  322. package/dist/src/tools/oapi/im/time-utils.js +169 -0
  323. package/dist/src/tools/oapi/im/time-utils.js.map +7 -0
  324. package/dist/src/tools/oapi/im/user-name-uat.js +103 -0
  325. package/dist/src/tools/oapi/im/user-name-uat.js.map +7 -0
  326. package/dist/src/tools/oapi/index.js +56 -0
  327. package/dist/src/tools/oapi/index.js.map +7 -0
  328. package/dist/src/tools/oapi/sdk-types.js +1 -0
  329. package/dist/src/tools/oapi/sdk-types.js.map +7 -0
  330. package/dist/src/tools/oapi/search/doc-search.js +215 -0
  331. package/dist/src/tools/oapi/search/doc-search.js.map +7 -0
  332. package/dist/src/tools/oapi/search/index.js +25 -0
  333. package/dist/src/tools/oapi/search/index.js.map +7 -0
  334. package/dist/src/tools/oapi/sheets/index.js +25 -0
  335. package/dist/src/tools/oapi/sheets/index.js.map +7 -0
  336. package/dist/src/tools/oapi/sheets/sheet.js +652 -0
  337. package/dist/src/tools/oapi/sheets/sheet.js.map +7 -0
  338. package/dist/src/tools/oapi/task/comment.js +151 -0
  339. package/dist/src/tools/oapi/task/comment.js.map +7 -0
  340. package/dist/src/tools/oapi/task/index.js +11 -0
  341. package/dist/src/tools/oapi/task/index.js.map +7 -0
  342. package/dist/src/tools/oapi/task/subtask.js +175 -0
  343. package/dist/src/tools/oapi/task/subtask.js.map +7 -0
  344. package/dist/src/tools/oapi/task/task.js +405 -0
  345. package/dist/src/tools/oapi/task/task.js.map +7 -0
  346. package/dist/src/tools/oapi/task/tasklist.js +366 -0
  347. package/dist/src/tools/oapi/task/tasklist.js.map +7 -0
  348. package/dist/src/tools/oapi/wiki/index.js +27 -0
  349. package/dist/src/tools/oapi/wiki/index.js.map +7 -0
  350. package/dist/src/tools/oapi/wiki/space-node.js +311 -0
  351. package/dist/src/tools/oapi/wiki/space-node.js.map +7 -0
  352. package/dist/src/tools/oapi/wiki/space.js +148 -0
  353. package/dist/src/tools/oapi/wiki/space.js.map +7 -0
  354. package/dist/src/tools/oauth-batch-auth.js +125 -0
  355. package/dist/src/tools/oauth-batch-auth.js.map +7 -0
  356. package/dist/src/tools/oauth-cards.js +269 -0
  357. package/dist/src/tools/oauth-cards.js.map +7 -0
  358. package/dist/src/tools/oauth.js +538 -0
  359. package/dist/src/tools/oauth.js.map +7 -0
  360. package/dist/src/tools/onboarding-auth.js +101 -0
  361. package/dist/src/tools/onboarding-auth.js.map +7 -0
  362. package/dist/src/tools/project-oauth.js +305 -0
  363. package/dist/src/tools/project-oauth.js.map +7 -0
  364. package/dist/src/tools/tat/im/index.js +9 -0
  365. package/dist/src/tools/tat/im/index.js.map +7 -0
  366. package/dist/src/tools/tat/im/resource.js +123 -0
  367. package/dist/src/tools/tat/im/resource.js.map +7 -0
  368. package/package.json +64 -0
@@ -0,0 +1,179 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import { json, createToolContext, assertLarkOk, handleInvokeErrorWithAutoAuth } from "../helpers";
3
+ const FeishuImMessageSchema = Type.Union([
4
+ // SEND
5
+ Type.Object({
6
+ action: Type.Literal("send"),
7
+ receive_id_type: Type.Union([Type.Literal("open_id"), Type.Literal("chat_id")], {
8
+ description: "\u63A5\u6536\u8005 ID \u7C7B\u578B\uFF1Aopen_id\uFF08\u79C1\u804A\uFF0Cou_xxx\uFF09\u3001chat_id\uFF08\u7FA4\u804A\uFF0Coc_xxx\uFF09"
9
+ }),
10
+ receive_id: Type.String({
11
+ description: "\u63A5\u6536\u8005 ID\uFF0C\u4E0E receive_id_type \u5BF9\u5E94\u3002open_id \u586B 'ou_xxx'\uFF0Cchat_id \u586B 'oc_xxx'"
12
+ }),
13
+ msg_type: Type.Union(
14
+ [
15
+ Type.Literal("text"),
16
+ Type.Literal("post"),
17
+ Type.Literal("image"),
18
+ Type.Literal("file"),
19
+ Type.Literal("audio"),
20
+ Type.Literal("media"),
21
+ Type.Literal("interactive"),
22
+ Type.Literal("share_chat"),
23
+ Type.Literal("share_user")
24
+ ],
25
+ {
26
+ description: "\u6D88\u606F\u7C7B\u578B\uFF1Atext\uFF08\u7EAF\u6587\u672C\uFF09\u3001post\uFF08\u5BCC\u6587\u672C\uFF09\u3001image\uFF08\u56FE\u7247\uFF09\u3001file\uFF08\u6587\u4EF6\uFF09\u3001interactive\uFF08\u6D88\u606F\u5361\u7247\uFF09\u3001share_chat\uFF08\u7FA4\u540D\u7247\uFF09\u3001share_user\uFF08\u4E2A\u4EBA\u540D\u7247\uFF09\u7B49"
27
+ }
28
+ ),
29
+ content: Type.String({
30
+ description: `\u6D88\u606F\u5185\u5BB9\uFF08JSON \u5B57\u7B26\u4E32\uFF09\uFF0C\u683C\u5F0F\u53D6\u51B3\u4E8E msg_type\u3002\u793A\u4F8B\uFF1Atext \u2192 '{"text":"\u4F60\u597D"}'\uFF0Cimage \u2192 '{"image_key":"img_xxx"}'\uFF0Cshare_chat \u2192 '{"chat_id":"oc_xxx"}'\uFF0Cpost \u2192 '{"zh_cn":{"title":"\u6807\u9898","content":[[{"tag":"text","text":"\u6B63\u6587"}]]}}'`
31
+ }),
32
+ uuid: Type.Optional(
33
+ Type.String({
34
+ description: "\u5E42\u7B49\u552F\u4E00\u6807\u8BC6\u3002\u540C\u4E00 uuid \u5728 1 \u5C0F\u65F6\u5185\u53EA\u4F1A\u53D1\u9001\u4E00\u6761\u6D88\u606F\uFF0C\u7528\u4E8E\u53BB\u91CD"
35
+ })
36
+ )
37
+ }),
38
+ // REPLY
39
+ Type.Object({
40
+ action: Type.Literal("reply"),
41
+ message_id: Type.String({
42
+ description: "\u88AB\u56DE\u590D\u6D88\u606F\u7684 ID\uFF08om_xxx \u683C\u5F0F\uFF09"
43
+ }),
44
+ msg_type: Type.Union(
45
+ [
46
+ Type.Literal("text"),
47
+ Type.Literal("post"),
48
+ Type.Literal("image"),
49
+ Type.Literal("file"),
50
+ Type.Literal("audio"),
51
+ Type.Literal("media"),
52
+ Type.Literal("interactive"),
53
+ Type.Literal("share_chat"),
54
+ Type.Literal("share_user")
55
+ ],
56
+ {
57
+ description: "\u6D88\u606F\u7C7B\u578B\uFF1Atext\uFF08\u7EAF\u6587\u672C\uFF09\u3001post\uFF08\u5BCC\u6587\u672C\uFF09\u3001image\uFF08\u56FE\u7247\uFF09\u3001interactive\uFF08\u6D88\u606F\u5361\u7247\uFF09\u7B49"
58
+ }
59
+ ),
60
+ content: Type.String({
61
+ description: "\u56DE\u590D\u6D88\u606F\u5185\u5BB9\uFF08JSON \u5B57\u7B26\u4E32\uFF09\uFF0C\u683C\u5F0F\u540C send \u7684 content"
62
+ }),
63
+ reply_in_thread: Type.Optional(
64
+ Type.Boolean({
65
+ description: "\u662F\u5426\u4EE5\u8BDD\u9898\u5F62\u5F0F\u56DE\u590D\u3002true \u5219\u6D88\u606F\u51FA\u73B0\u5728\u8BE5\u6D88\u606F\u7684\u8BDD\u9898\u4E2D\uFF0Cfalse\uFF08\u9ED8\u8BA4\uFF09\u5219\u51FA\u73B0\u5728\u804A\u5929\u4E3B\u6D41"
66
+ })
67
+ ),
68
+ uuid: Type.Optional(
69
+ Type.String({
70
+ description: "\u5E42\u7B49\u552F\u4E00\u6807\u8BC6"
71
+ })
72
+ )
73
+ })
74
+ ]);
75
+ function registerFeishuImUserMessageTool(api) {
76
+ if (!api.config) return;
77
+ const cfg = api.config;
78
+ const { toolClient, log } = createToolContext(api, "feishu_im_user_message");
79
+ api.registerTool(
80
+ {
81
+ name: "feishu_im_user_message",
82
+ label: "Feishu: IM User Message",
83
+ description: `\u98DE\u4E66\u7528\u6237\u8EAB\u4EFD IM \u6D88\u606F\u5DE5\u5177\u3002**\u6709\u4E14\u4EC5\u5F53\u7528\u6237\u660E\u786E\u8981\u6C42\u4EE5\u81EA\u5DF1\u8EAB\u4EFD\u53D1\u6D88\u606F\u3001\u56DE\u590D\u6D88\u606F\u65F6\u4F7F\u7528\uFF0C\u5F53\u6CA1\u6709\u660E\u786E\u8981\u6C42\u65F6\u4F18\u5148\u4F7F\u7528message\u7CFB\u7EDF\u5DE5\u5177**\u3002
84
+
85
+ Actions:
86
+ - send\uFF08\u53D1\u9001\u6D88\u606F\uFF09\uFF1A\u53D1\u9001\u6D88\u606F\u5230\u79C1\u804A\u6216\u7FA4\u804A\u3002\u79C1\u804A\u7528 receive_id_type=open_id\uFF0C\u7FA4\u804A\u7528 receive_id_type=chat_id
87
+ - reply\uFF08\u56DE\u590D\u6D88\u606F\uFF09\uFF1A\u56DE\u590D\u6307\u5B9A message_id \u7684\u6D88\u606F\uFF0C\u652F\u6301\u8BDD\u9898\u56DE\u590D\uFF08reply_in_thread=true\uFF09
88
+
89
+ \u3010\u91CD\u8981\u3011content \u5FC5\u987B\u662F\u5408\u6CD5 JSON \u5B57\u7B26\u4E32\uFF0C\u683C\u5F0F\u53D6\u51B3\u4E8E msg_type\u3002\u6700\u5E38\u7528\uFF1Atext \u7C7B\u578B content \u4E3A '{"text":"\u6D88\u606F\u5185\u5BB9"}'\u3002
90
+
91
+ \u3010\u5B89\u5168\u7EA6\u675F\u3011\u6B64\u5DE5\u5177\u4EE5\u7528\u6237\u8EAB\u4EFD\u53D1\u9001\u6D88\u606F\uFF0C\u53D1\u51FA\u540E\u5BF9\u65B9\u770B\u5230\u7684\u53D1\u9001\u8005\u662F\u7528\u6237\u672C\u4EBA\u3002\u8C03\u7528\u524D\u5FC5\u987B\u5148\u5411\u7528\u6237\u786E\u8BA4\uFF1A1) \u53D1\u9001\u5BF9\u8C61\uFF08\u54EA\u4E2A\u4EBA\u6216\u54EA\u4E2A\u7FA4\uFF092) \u6D88\u606F\u5185\u5BB9\u3002\u7981\u6B62\u5728\u7528\u6237\u672A\u660E\u786E\u540C\u610F\u7684\u60C5\u51B5\u4E0B\u81EA\u884C\u53D1\u9001\u6D88\u606F\u3002`,
92
+ parameters: FeishuImMessageSchema,
93
+ async execute(_toolCallId, params) {
94
+ const p = params;
95
+ try {
96
+ const client = toolClient();
97
+ switch (p.action) {
98
+ // -----------------------------------------------------------------
99
+ // SEND MESSAGE
100
+ // -----------------------------------------------------------------
101
+ case "send": {
102
+ log.info(
103
+ `send: receive_id_type=${p.receive_id_type}, receive_id=${p.receive_id}, msg_type=${p.msg_type}`
104
+ );
105
+ const res = await client.invoke(
106
+ "feishu_im_user_message.send",
107
+ (sdk, opts) => sdk.im.v1.message.create(
108
+ {
109
+ params: { receive_id_type: p.receive_id_type },
110
+ data: {
111
+ receive_id: p.receive_id,
112
+ msg_type: p.msg_type,
113
+ content: p.content,
114
+ uuid: p.uuid
115
+ }
116
+ },
117
+ opts
118
+ ),
119
+ {
120
+ as: "user"
121
+ }
122
+ );
123
+ assertLarkOk(res);
124
+ const data = res.data;
125
+ log.info(`send: message sent, message_id=${data?.message_id}`);
126
+ return json({
127
+ message_id: data?.message_id,
128
+ chat_id: data?.chat_id,
129
+ create_time: data?.create_time
130
+ });
131
+ }
132
+ // -----------------------------------------------------------------
133
+ // REPLY MESSAGE
134
+ // -----------------------------------------------------------------
135
+ case "reply": {
136
+ log.info(
137
+ `reply: message_id=${p.message_id}, msg_type=${p.msg_type}, reply_in_thread=${p.reply_in_thread ?? false}`
138
+ );
139
+ const res = await client.invoke(
140
+ "feishu_im_user_message.reply",
141
+ (sdk, opts) => sdk.im.v1.message.reply(
142
+ {
143
+ path: { message_id: p.message_id },
144
+ data: {
145
+ content: p.content,
146
+ msg_type: p.msg_type,
147
+ reply_in_thread: p.reply_in_thread,
148
+ uuid: p.uuid
149
+ }
150
+ },
151
+ opts
152
+ ),
153
+ {
154
+ as: "user"
155
+ }
156
+ );
157
+ assertLarkOk(res);
158
+ const data = res.data;
159
+ log.info(`reply: message sent, message_id=${data?.message_id}`);
160
+ return json({
161
+ message_id: data?.message_id,
162
+ chat_id: data?.chat_id,
163
+ create_time: data?.create_time
164
+ });
165
+ }
166
+ }
167
+ } catch (err) {
168
+ return await handleInvokeErrorWithAutoAuth(err, cfg);
169
+ }
170
+ }
171
+ },
172
+ { name: "feishu_im_user_message" }
173
+ );
174
+ api.logger.info?.("feishu_im_user_message: Registered feishu_im_user_message tool");
175
+ }
176
+ export {
177
+ registerFeishuImUserMessageTool
178
+ };
179
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/tools/oapi/im/message.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * feishu_im_user_message tool -- \u4EE5\u7528\u6237\u8EAB\u4EFD\u53D1\u9001/\u56DE\u590D IM \u6D88\u606F\n *\n * Actions: send, reply\n *\n * Uses the Feishu IM API:\n * - send: POST /open-apis/im/v1/messages?receive_id_type=...\n * - reply: POST /open-apis/im/v1/messages/:message_id/reply\n *\n * \u5168\u90E8\u4EE5\u7528\u6237\u8EAB\u4EFD\uFF08user_access_token\uFF09\u8C03\u7528\uFF0Cscope \u6765\u81EA real-scope.json\u3002\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport { Type } from '@sinclair/typebox';\nimport { json, createToolContext, assertLarkOk, handleInvokeErrorWithAutoAuth } from '../helpers';\n\n// ---------------------------------------------------------------------------\n// Schema\n// ---------------------------------------------------------------------------\n\nconst FeishuImMessageSchema = Type.Union([\n // SEND\n Type.Object({\n action: Type.Literal('send'),\n receive_id_type: Type.Union([Type.Literal('open_id'), Type.Literal('chat_id')], {\n description: '\u63A5\u6536\u8005 ID \u7C7B\u578B\uFF1Aopen_id\uFF08\u79C1\u804A\uFF0Cou_xxx\uFF09\u3001chat_id\uFF08\u7FA4\u804A\uFF0Coc_xxx\uFF09',\n }),\n receive_id: Type.String({\n description: \"\u63A5\u6536\u8005 ID\uFF0C\u4E0E receive_id_type \u5BF9\u5E94\u3002open_id \u586B 'ou_xxx'\uFF0Cchat_id \u586B 'oc_xxx'\",\n }),\n msg_type: Type.Union(\n [\n Type.Literal('text'),\n Type.Literal('post'),\n Type.Literal('image'),\n Type.Literal('file'),\n Type.Literal('audio'),\n Type.Literal('media'),\n Type.Literal('interactive'),\n Type.Literal('share_chat'),\n Type.Literal('share_user'),\n ],\n {\n description:\n '\u6D88\u606F\u7C7B\u578B\uFF1Atext\uFF08\u7EAF\u6587\u672C\uFF09\u3001post\uFF08\u5BCC\u6587\u672C\uFF09\u3001image\uFF08\u56FE\u7247\uFF09\u3001file\uFF08\u6587\u4EF6\uFF09\u3001interactive\uFF08\u6D88\u606F\u5361\u7247\uFF09\u3001share_chat\uFF08\u7FA4\u540D\u7247\uFF09\u3001share_user\uFF08\u4E2A\u4EBA\u540D\u7247\uFF09\u7B49',\n },\n ),\n content: Type.String({\n description:\n '\u6D88\u606F\u5185\u5BB9\uFF08JSON \u5B57\u7B26\u4E32\uFF09\uFF0C\u683C\u5F0F\u53D6\u51B3\u4E8E msg_type\u3002' +\n '\u793A\u4F8B\uFF1Atext \u2192 \\'{\"text\":\"\u4F60\u597D\"}\\'\uFF0C' +\n 'image \u2192 \\'{\"image_key\":\"img_xxx\"}\\'\uFF0C' +\n 'share_chat \u2192 \\'{\"chat_id\":\"oc_xxx\"}\\'\uFF0C' +\n 'post \u2192 \\'{\"zh_cn\":{\"title\":\"\u6807\u9898\",\"content\":[[{\"tag\":\"text\",\"text\":\"\u6B63\u6587\"}]]}}\\'',\n }),\n uuid: Type.Optional(\n Type.String({\n description: '\u5E42\u7B49\u552F\u4E00\u6807\u8BC6\u3002\u540C\u4E00 uuid \u5728 1 \u5C0F\u65F6\u5185\u53EA\u4F1A\u53D1\u9001\u4E00\u6761\u6D88\u606F\uFF0C\u7528\u4E8E\u53BB\u91CD',\n }),\n ),\n }),\n\n // REPLY\n Type.Object({\n action: Type.Literal('reply'),\n message_id: Type.String({\n description: '\u88AB\u56DE\u590D\u6D88\u606F\u7684 ID\uFF08om_xxx \u683C\u5F0F\uFF09',\n }),\n msg_type: Type.Union(\n [\n Type.Literal('text'),\n Type.Literal('post'),\n Type.Literal('image'),\n Type.Literal('file'),\n Type.Literal('audio'),\n Type.Literal('media'),\n Type.Literal('interactive'),\n Type.Literal('share_chat'),\n Type.Literal('share_user'),\n ],\n {\n description: '\u6D88\u606F\u7C7B\u578B\uFF1Atext\uFF08\u7EAF\u6587\u672C\uFF09\u3001post\uFF08\u5BCC\u6587\u672C\uFF09\u3001image\uFF08\u56FE\u7247\uFF09\u3001interactive\uFF08\u6D88\u606F\u5361\u7247\uFF09\u7B49',\n },\n ),\n content: Type.String({\n description: '\u56DE\u590D\u6D88\u606F\u5185\u5BB9\uFF08JSON \u5B57\u7B26\u4E32\uFF09\uFF0C\u683C\u5F0F\u540C send \u7684 content',\n }),\n reply_in_thread: Type.Optional(\n Type.Boolean({\n description: '\u662F\u5426\u4EE5\u8BDD\u9898\u5F62\u5F0F\u56DE\u590D\u3002true \u5219\u6D88\u606F\u51FA\u73B0\u5728\u8BE5\u6D88\u606F\u7684\u8BDD\u9898\u4E2D\uFF0Cfalse\uFF08\u9ED8\u8BA4\uFF09\u5219\u51FA\u73B0\u5728\u804A\u5929\u4E3B\u6D41',\n }),\n ),\n uuid: Type.Optional(\n Type.String({\n description: '\u5E42\u7B49\u552F\u4E00\u6807\u8BC6',\n }),\n ),\n }),\n]);\n\n// ---------------------------------------------------------------------------\n// Params type\n// ---------------------------------------------------------------------------\n\ntype FeishuImMessageParams =\n | {\n action: 'send';\n receive_id_type: 'open_id' | 'chat_id';\n receive_id: string;\n msg_type: string;\n content: string;\n uuid?: string;\n }\n | {\n action: 'reply';\n message_id: string;\n msg_type: string;\n content: string;\n reply_in_thread?: boolean;\n uuid?: string;\n };\n\n// ---------------------------------------------------------------------------\n// Registration\n// ---------------------------------------------------------------------------\n\nexport function registerFeishuImUserMessageTool(api: OpenClawPluginApi) {\n if (!api.config) return;\n const cfg = api.config;\n\n const { toolClient, log } = createToolContext(api, 'feishu_im_user_message');\n\n api.registerTool(\n {\n name: 'feishu_im_user_message',\n label: 'Feishu: IM User Message',\n description:\n '\u98DE\u4E66\u7528\u6237\u8EAB\u4EFD IM \u6D88\u606F\u5DE5\u5177\u3002**\u6709\u4E14\u4EC5\u5F53\u7528\u6237\u660E\u786E\u8981\u6C42\u4EE5\u81EA\u5DF1\u8EAB\u4EFD\u53D1\u6D88\u606F\u3001\u56DE\u590D\u6D88\u606F\u65F6\u4F7F\u7528\uFF0C\u5F53\u6CA1\u6709\u660E\u786E\u8981\u6C42\u65F6\u4F18\u5148\u4F7F\u7528message\u7CFB\u7EDF\u5DE5\u5177**\u3002' +\n '\\n\\nActions:' +\n '\\n- send\uFF08\u53D1\u9001\u6D88\u606F\uFF09\uFF1A\u53D1\u9001\u6D88\u606F\u5230\u79C1\u804A\u6216\u7FA4\u804A\u3002\u79C1\u804A\u7528 receive_id_type=open_id\uFF0C\u7FA4\u804A\u7528 receive_id_type=chat_id' +\n '\\n- reply\uFF08\u56DE\u590D\u6D88\u606F\uFF09\uFF1A\u56DE\u590D\u6307\u5B9A message_id \u7684\u6D88\u606F\uFF0C\u652F\u6301\u8BDD\u9898\u56DE\u590D\uFF08reply_in_thread=true\uFF09' +\n '\\n\\n\u3010\u91CD\u8981\u3011content \u5FC5\u987B\u662F\u5408\u6CD5 JSON \u5B57\u7B26\u4E32\uFF0C\u683C\u5F0F\u53D6\u51B3\u4E8E msg_type\u3002' +\n '\u6700\u5E38\u7528\uFF1Atext \u7C7B\u578B content \u4E3A \\'{\"text\":\"\u6D88\u606F\u5185\u5BB9\"}\\'\u3002' +\n '\\n\\n\u3010\u5B89\u5168\u7EA6\u675F\u3011\u6B64\u5DE5\u5177\u4EE5\u7528\u6237\u8EAB\u4EFD\u53D1\u9001\u6D88\u606F\uFF0C\u53D1\u51FA\u540E\u5BF9\u65B9\u770B\u5230\u7684\u53D1\u9001\u8005\u662F\u7528\u6237\u672C\u4EBA\u3002' +\n '\u8C03\u7528\u524D\u5FC5\u987B\u5148\u5411\u7528\u6237\u786E\u8BA4\uFF1A1) \u53D1\u9001\u5BF9\u8C61\uFF08\u54EA\u4E2A\u4EBA\u6216\u54EA\u4E2A\u7FA4\uFF092) \u6D88\u606F\u5185\u5BB9\u3002' +\n '\u7981\u6B62\u5728\u7528\u6237\u672A\u660E\u786E\u540C\u610F\u7684\u60C5\u51B5\u4E0B\u81EA\u884C\u53D1\u9001\u6D88\u606F\u3002',\n parameters: FeishuImMessageSchema,\n async execute(_toolCallId: string, params: unknown) {\n const p = params as FeishuImMessageParams;\n try {\n const client = toolClient();\n\n switch (p.action) {\n // -----------------------------------------------------------------\n // SEND MESSAGE\n // -----------------------------------------------------------------\n case 'send': {\n log.info(\n `send: receive_id_type=${p.receive_id_type}, receive_id=${p.receive_id}, msg_type=${p.msg_type}`,\n );\n\n const res = await client.invoke(\n 'feishu_im_user_message.send',\n (sdk, opts) =>\n sdk.im.v1.message.create(\n {\n params: { receive_id_type: p.receive_id_type },\n data: {\n receive_id: p.receive_id,\n msg_type: p.msg_type,\n content: p.content,\n uuid: p.uuid,\n },\n },\n opts,\n ),\n {\n as: 'user',\n },\n );\n assertLarkOk(res);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const data = res.data as any;\n log.info(`send: message sent, message_id=${data?.message_id}`);\n\n return json({\n message_id: data?.message_id,\n chat_id: data?.chat_id,\n create_time: data?.create_time,\n });\n }\n\n // -----------------------------------------------------------------\n // REPLY MESSAGE\n // -----------------------------------------------------------------\n case 'reply': {\n log.info(\n `reply: message_id=${p.message_id}, msg_type=${p.msg_type}, reply_in_thread=${p.reply_in_thread ?? false}`,\n );\n\n const res = await client.invoke(\n 'feishu_im_user_message.reply',\n (sdk, opts) =>\n sdk.im.v1.message.reply(\n {\n path: { message_id: p.message_id },\n data: {\n content: p.content,\n msg_type: p.msg_type,\n reply_in_thread: p.reply_in_thread,\n uuid: p.uuid,\n },\n },\n opts,\n ),\n {\n as: 'user',\n },\n );\n assertLarkOk(res);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const data = res.data as any;\n log.info(`reply: message sent, message_id=${data?.message_id}`);\n\n return json({\n message_id: data?.message_id,\n chat_id: data?.chat_id,\n create_time: data?.create_time,\n });\n }\n }\n } catch (err) {\n return await handleInvokeErrorWithAutoAuth(err, cfg);\n }\n },\n },\n { name: 'feishu_im_user_message' },\n );\n\n api.logger.info?.('feishu_im_user_message: Registered feishu_im_user_message tool');\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,126 @@
1
+ import { buildRandomTempFilePath } from "openclaw/plugin-sdk";
2
+ import { Type } from "@sinclair/typebox";
3
+ import { json, createToolContext, handleInvokeErrorWithAutoAuth } from "../helpers";
4
+ import * as fs from "node:fs/promises";
5
+ import * as path from "node:path";
6
+ const MIME_TO_EXT = {
7
+ // Images
8
+ "image/png": ".png",
9
+ "image/jpeg": ".jpg",
10
+ "image/jpg": ".jpg",
11
+ "image/gif": ".gif",
12
+ "image/webp": ".webp",
13
+ "image/svg+xml": ".svg",
14
+ "image/bmp": ".bmp",
15
+ "image/tiff": ".tiff",
16
+ // Videos
17
+ "video/mp4": ".mp4",
18
+ "video/mpeg": ".mpeg",
19
+ "video/quicktime": ".mov",
20
+ "video/x-msvideo": ".avi",
21
+ "video/webm": ".webm",
22
+ // Audio
23
+ "audio/mpeg": ".mp3",
24
+ "audio/wav": ".wav",
25
+ "audio/ogg": ".ogg",
26
+ "audio/mp4": ".m4a",
27
+ // Documents
28
+ "application/pdf": ".pdf",
29
+ "application/msword": ".doc",
30
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx",
31
+ "application/vnd.ms-excel": ".xls",
32
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx",
33
+ "application/vnd.ms-powerpoint": ".ppt",
34
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation": ".pptx",
35
+ // Others
36
+ "application/zip": ".zip",
37
+ "application/x-rar-compressed": ".rar",
38
+ "text/plain": ".txt",
39
+ "application/json": ".json"
40
+ };
41
+ const FetchResourceSchema = Type.Object({
42
+ message_id: Type.String({
43
+ description: "\u6D88\u606F ID\uFF08om_xxx \u683C\u5F0F\uFF09\uFF0C\u4ECE\u6D88\u606F\u4E8B\u4EF6\u6216\u6D88\u606F\u5217\u8868\u4E2D\u83B7\u53D6"
44
+ }),
45
+ file_key: Type.String({
46
+ description: "\u8D44\u6E90 Key\uFF0C\u4ECE\u6D88\u606F\u4F53\u4E2D\u83B7\u53D6\u3002\u56FE\u7247\u6D88\u606F\u7684 image_key\uFF08img_xxx\uFF09\u6216\u6587\u4EF6\u6D88\u606F\u7684 file_key\uFF08file_xxx\uFF09"
47
+ }),
48
+ type: Type.Union([Type.Literal("image"), Type.Literal("file")], {
49
+ description: "\u8D44\u6E90\u7C7B\u578B\uFF1Aimage\uFF08\u56FE\u7247\u6D88\u606F\u4E2D\u7684\u56FE\u7247\uFF09\u3001file\uFF08\u6587\u4EF6/\u97F3\u9891/\u89C6\u9891\u6D88\u606F\u4E2D\u7684\u6587\u4EF6\uFF09"
50
+ })
51
+ });
52
+ function registerFeishuImUserFetchResourceTool(api) {
53
+ if (!api.config) return;
54
+ const cfg = api.config;
55
+ const { toolClient, log } = createToolContext(api, "feishu_im_user_fetch_resource");
56
+ api.registerTool(
57
+ {
58
+ name: "feishu_im_user_fetch_resource",
59
+ label: "Feishu: IM Fetch Resource",
60
+ description: "\u3010\u4EE5\u7528\u6237\u8EAB\u4EFD\u3011\u4E0B\u8F7D\u98DE\u4E66 IM \u6D88\u606F\u4E2D\u7684\u6587\u4EF6\u6216\u56FE\u7247\u8D44\u6E90\u5230\u672C\u5730\u6587\u4EF6\u3002\u9700\u8981\u7528\u6237 OAuth \u6388\u6743\u3002\n\n\u9002\u7528\u573A\u666F\uFF1A\u5F53\u4F60\u4EE5\u7528\u6237\u8EAB\u4EFD\u8C03\u7528\u4E86\u6D88\u606F\u5217\u8868/\u641C\u7D22\u7B49 API \u83B7\u53D6\u5230 message_id \u548C file_key \u65F6\uFF0C\u5E94\u4F7F\u7528\u672C\u5DE5\u5177\u4EE5\u540C\u6837\u7684\u7528\u6237\u8EAB\u4EFD\u4E0B\u8F7D\u8D44\u6E90\u3002\n\u6CE8\u610F\uFF1A\u5982\u679C message_id \u6765\u81EA\u5F53\u524D\u5BF9\u8BDD\u4E0A\u4E0B\u6587\uFF08\u7528\u6237\u53D1\u7ED9\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3001\u5F15\u7528\u7684\u6D88\u606F\uFF09\uFF0C\u8BF7\u4F7F\u7528 feishu_im_bot_image \u5DE5\u5177\u4EE5\u673A\u5668\u4EBA\u8EAB\u4EFD\u4E0B\u8F7D\uFF0C\u65E0\u9700\u7528\u6237\u6388\u6743\u3002\n\n\u53C2\u6570\u8BF4\u660E\uFF1A\n- message_id\uFF1A\u6D88\u606F ID\uFF08om_xxx\uFF09\uFF0C\u4ECE\u6D88\u606F\u4E8B\u4EF6\u6216\u6D88\u606F\u5217\u8868\u4E2D\u83B7\u53D6\n- file_key\uFF1A\u8D44\u6E90 Key\uFF0C\u4ECE\u6D88\u606F\u4F53\u4E2D\u83B7\u53D6\u3002\u56FE\u7247\u7528 image_key\uFF08img_xxx\uFF09\uFF0C\u6587\u4EF6\u7528 file_key\uFF08file_xxx\uFF09\n- type\uFF1A\u56FE\u7247\u7528 image\uFF0C\u6587\u4EF6/\u97F3\u9891/\u89C6\u9891\u7528 file\n\n\u6587\u4EF6\u81EA\u52A8\u4FDD\u5B58\u5230 /tmp/openclaw/ \u4E0B\uFF0C\u8FD4\u56DE\u503C\u4E2D\u7684 saved_path \u4E3A\u5B9E\u9645\u4FDD\u5B58\u8DEF\u5F84\u3002\n\u9650\u5236\uFF1A\u6587\u4EF6\u5927\u5C0F\u4E0D\u8D85\u8FC7 100MB\u3002\u4E0D\u652F\u6301\u4E0B\u8F7D\u8868\u60C5\u5305\u3001\u5408\u5E76\u8F6C\u53D1\u6D88\u606F\u3001\u5361\u7247\u4E2D\u7684\u8D44\u6E90\u3002",
61
+ parameters: FetchResourceSchema,
62
+ async execute(_toolCallId, params) {
63
+ const p = params;
64
+ try {
65
+ const client = toolClient();
66
+ log.info(`fetch_resource: message_id="${p.message_id}", file_key="${p.file_key}", type="${p.type}"`);
67
+ const res = await client.invoke(
68
+ "feishu_im_user_fetch_resource.default",
69
+ (sdk, opts) => sdk.im.v1.messageResource.get(
70
+ {
71
+ params: { type: p.type },
72
+ path: { message_id: p.message_id, file_key: p.file_key }
73
+ },
74
+ opts
75
+ ),
76
+ {
77
+ as: "user"
78
+ }
79
+ );
80
+ const stream = res.getReadableStream();
81
+ const chunks = [];
82
+ for await (const chunk of stream) {
83
+ chunks.push(chunk);
84
+ }
85
+ const buffer = Buffer.concat(chunks);
86
+ log.info(`fetch_resource: downloaded ${buffer.length} bytes`);
87
+ const contentType = res.headers?.["content-type"] || "";
88
+ log.info(`fetch_resource: content-type=${contentType}`);
89
+ const mimeType = contentType ? contentType.split(";")[0].trim() : "";
90
+ const mimeExt = mimeType ? MIME_TO_EXT[mimeType] : void 0;
91
+ const finalPath = buildRandomTempFilePath({
92
+ prefix: "im-resource",
93
+ extension: mimeExt
94
+ });
95
+ log.info(`fetch_resource: saving to ${finalPath}`);
96
+ await fs.mkdir(path.dirname(finalPath), { recursive: true });
97
+ try {
98
+ await fs.writeFile(finalPath, buffer);
99
+ log.info(`fetch_resource: saved to ${finalPath}`);
100
+ return json({
101
+ message_id: p.message_id,
102
+ file_key: p.file_key,
103
+ type: p.type,
104
+ size_bytes: buffer.length,
105
+ content_type: contentType,
106
+ saved_path: finalPath
107
+ });
108
+ } catch (err) {
109
+ log.error(`fetch_resource: failed to save file: ${err}`);
110
+ return json({
111
+ error: `\u4FDD\u5B58\u6587\u4EF6\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`
112
+ });
113
+ }
114
+ } catch (err) {
115
+ return await handleInvokeErrorWithAutoAuth(err, cfg);
116
+ }
117
+ }
118
+ },
119
+ { name: "feishu_im_user_fetch_resource" }
120
+ );
121
+ api.logger.info?.("feishu_im_user_fetch_resource: Registered feishu_im_user_fetch_resource tool");
122
+ }
123
+ export {
124
+ registerFeishuImUserFetchResourceTool
125
+ };
126
+ //# sourceMappingURL=resource.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/tools/oapi/im/resource.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * feishu_im_user_fetch_resource tool -- \u4EE5\u7528\u6237\u8EAB\u4EFD\u4E0B\u8F7D IM \u6D88\u606F\u4E2D\u7684\u6587\u4EF6/\u56FE\u7247\u8D44\u6E90\n *\n * \u4F7F\u7528\u98DE\u4E66 API:\n * - im.v1.messageResource.get: GET /open-apis/im/v1/messages/:message_id/resources/:file_key\n *\n * \u5168\u90E8\u4EE5\u7528\u6237\u8EAB\u4EFD\uFF08user_access_token\uFF09\u8C03\u7528\uFF0Cscope \u6765\u81EA real-scope.json\u3002\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport { buildRandomTempFilePath } from 'openclaw/plugin-sdk';\nimport { Type } from '@sinclair/typebox';\nimport { json, createToolContext, handleInvokeErrorWithAutoAuth } from '../helpers';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\n// ---------------------------------------------------------------------------\n// Helper: MIME type to extension mapping\n// ---------------------------------------------------------------------------\n\nconst MIME_TO_EXT: Record<string, string> = {\n // Images\n 'image/png': '.png',\n 'image/jpeg': '.jpg',\n 'image/jpg': '.jpg',\n 'image/gif': '.gif',\n 'image/webp': '.webp',\n 'image/svg+xml': '.svg',\n 'image/bmp': '.bmp',\n 'image/tiff': '.tiff',\n // Videos\n 'video/mp4': '.mp4',\n 'video/mpeg': '.mpeg',\n 'video/quicktime': '.mov',\n 'video/x-msvideo': '.avi',\n 'video/webm': '.webm',\n // Audio\n 'audio/mpeg': '.mp3',\n 'audio/wav': '.wav',\n 'audio/ogg': '.ogg',\n 'audio/mp4': '.m4a',\n // Documents\n 'application/pdf': '.pdf',\n 'application/msword': '.doc',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': '.docx',\n 'application/vnd.ms-excel': '.xls',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': '.xlsx',\n 'application/vnd.ms-powerpoint': '.ppt',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation': '.pptx',\n // Others\n 'application/zip': '.zip',\n 'application/x-rar-compressed': '.rar',\n 'text/plain': '.txt',\n 'application/json': '.json',\n};\n\n// ---------------------------------------------------------------------------\n// Schema\n// ---------------------------------------------------------------------------\n\nconst FetchResourceSchema = Type.Object({\n message_id: Type.String({\n description: '\u6D88\u606F ID\uFF08om_xxx \u683C\u5F0F\uFF09\uFF0C\u4ECE\u6D88\u606F\u4E8B\u4EF6\u6216\u6D88\u606F\u5217\u8868\u4E2D\u83B7\u53D6',\n }),\n file_key: Type.String({\n description: '\u8D44\u6E90 Key\uFF0C\u4ECE\u6D88\u606F\u4F53\u4E2D\u83B7\u53D6\u3002\u56FE\u7247\u6D88\u606F\u7684 image_key\uFF08img_xxx\uFF09\u6216\u6587\u4EF6\u6D88\u606F\u7684 file_key\uFF08file_xxx\uFF09',\n }),\n type: Type.Union([Type.Literal('image'), Type.Literal('file')], {\n description: '\u8D44\u6E90\u7C7B\u578B\uFF1Aimage\uFF08\u56FE\u7247\u6D88\u606F\u4E2D\u7684\u56FE\u7247\uFF09\u3001file\uFF08\u6587\u4EF6/\u97F3\u9891/\u89C6\u9891\u6D88\u606F\u4E2D\u7684\u6587\u4EF6\uFF09',\n }),\n});\n\n// ---------------------------------------------------------------------------\n// Params type\n// ---------------------------------------------------------------------------\n\ninterface FetchResourceParams {\n message_id: string;\n file_key: string;\n type: 'image' | 'file';\n}\n\n// ---------------------------------------------------------------------------\n// Registration\n// ---------------------------------------------------------------------------\n\nexport function registerFeishuImUserFetchResourceTool(api: OpenClawPluginApi) {\n if (!api.config) return;\n const cfg = api.config;\n\n const { toolClient, log } = createToolContext(api, 'feishu_im_user_fetch_resource');\n\n api.registerTool(\n {\n name: 'feishu_im_user_fetch_resource',\n label: 'Feishu: IM Fetch Resource',\n description:\n '\u3010\u4EE5\u7528\u6237\u8EAB\u4EFD\u3011\u4E0B\u8F7D\u98DE\u4E66 IM \u6D88\u606F\u4E2D\u7684\u6587\u4EF6\u6216\u56FE\u7247\u8D44\u6E90\u5230\u672C\u5730\u6587\u4EF6\u3002\u9700\u8981\u7528\u6237 OAuth \u6388\u6743\u3002' +\n '\\n\\n\u9002\u7528\u573A\u666F\uFF1A\u5F53\u4F60\u4EE5\u7528\u6237\u8EAB\u4EFD\u8C03\u7528\u4E86\u6D88\u606F\u5217\u8868/\u641C\u7D22\u7B49 API \u83B7\u53D6\u5230 message_id \u548C file_key \u65F6\uFF0C' +\n '\u5E94\u4F7F\u7528\u672C\u5DE5\u5177\u4EE5\u540C\u6837\u7684\u7528\u6237\u8EAB\u4EFD\u4E0B\u8F7D\u8D44\u6E90\u3002' +\n '\\n\u6CE8\u610F\uFF1A\u5982\u679C message_id \u6765\u81EA\u5F53\u524D\u5BF9\u8BDD\u4E0A\u4E0B\u6587\uFF08\u7528\u6237\u53D1\u7ED9\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3001\u5F15\u7528\u7684\u6D88\u606F\uFF09\uFF0C' +\n '\u8BF7\u4F7F\u7528 feishu_im_bot_image \u5DE5\u5177\u4EE5\u673A\u5668\u4EBA\u8EAB\u4EFD\u4E0B\u8F7D\uFF0C\u65E0\u9700\u7528\u6237\u6388\u6743\u3002' +\n '\\n\\n\u53C2\u6570\u8BF4\u660E\uFF1A' +\n '\\n- message_id\uFF1A\u6D88\u606F ID\uFF08om_xxx\uFF09\uFF0C\u4ECE\u6D88\u606F\u4E8B\u4EF6\u6216\u6D88\u606F\u5217\u8868\u4E2D\u83B7\u53D6' +\n '\\n- file_key\uFF1A\u8D44\u6E90 Key\uFF0C\u4ECE\u6D88\u606F\u4F53\u4E2D\u83B7\u53D6\u3002\u56FE\u7247\u7528 image_key\uFF08img_xxx\uFF09\uFF0C\u6587\u4EF6\u7528 file_key\uFF08file_xxx\uFF09' +\n '\\n- type\uFF1A\u56FE\u7247\u7528 image\uFF0C\u6587\u4EF6/\u97F3\u9891/\u89C6\u9891\u7528 file' +\n '\\n\\n\u6587\u4EF6\u81EA\u52A8\u4FDD\u5B58\u5230 /tmp/openclaw/ \u4E0B\uFF0C\u8FD4\u56DE\u503C\u4E2D\u7684 saved_path \u4E3A\u5B9E\u9645\u4FDD\u5B58\u8DEF\u5F84\u3002' +\n '\\n\u9650\u5236\uFF1A\u6587\u4EF6\u5927\u5C0F\u4E0D\u8D85\u8FC7 100MB\u3002\u4E0D\u652F\u6301\u4E0B\u8F7D\u8868\u60C5\u5305\u3001\u5408\u5E76\u8F6C\u53D1\u6D88\u606F\u3001\u5361\u7247\u4E2D\u7684\u8D44\u6E90\u3002',\n parameters: FetchResourceSchema,\n async execute(_toolCallId: string, params: unknown) {\n const p = params as FetchResourceParams;\n try {\n const client = toolClient();\n\n log.info(`fetch_resource: message_id=\"${p.message_id}\", file_key=\"${p.file_key}\", type=\"${p.type}\"`);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const res: any = await client.invoke(\n 'feishu_im_user_fetch_resource.default',\n (sdk, opts) =>\n sdk.im.v1.messageResource.get(\n {\n params: { type: p.type },\n path: { message_id: p.message_id, file_key: p.file_key },\n },\n opts,\n ),\n {\n as: 'user',\n },\n );\n\n // \u54CD\u5E94\u662F\u4E8C\u8FDB\u5236\u6D41\uFF0C\u4F7F\u7528 getReadableStream() \u8BFB\u53D6\n const stream = res.getReadableStream();\n const chunks: Buffer[] = [];\n\n for await (const chunk of stream) {\n chunks.push(chunk);\n }\n\n const buffer = Buffer.concat(chunks);\n\n log.info(`fetch_resource: downloaded ${buffer.length} bytes`);\n\n // \u4ECE\u54CD\u5E94\u5934\u83B7\u53D6 Content-Type\uFF0C\u5E76\u786E\u5B9A\u6587\u4EF6\u6269\u5C55\u540D\n const contentType = res.headers?.['content-type'] || '';\n log.info(`fetch_resource: content-type=${contentType}`);\n\n // \u4ECE Content-Type \u63A8\u65AD\u6269\u5C55\u540D\uFF0C\u81EA\u52A8\u751F\u6210\u4FDD\u5B58\u8DEF\u5F84\n const mimeType = contentType ? contentType.split(';')[0].trim() : '';\n const mimeExt = mimeType ? MIME_TO_EXT[mimeType] : undefined;\n\n const finalPath = buildRandomTempFilePath({\n prefix: 'im-resource',\n extension: mimeExt,\n });\n log.info(`fetch_resource: saving to ${finalPath}`);\n\n // \u786E\u4FDD\u7236\u76EE\u5F55\u5B58\u5728\n await fs.mkdir(path.dirname(finalPath), { recursive: true });\n\n // \u4FDD\u5B58\u6587\u4EF6\n try {\n await fs.writeFile(finalPath, buffer);\n log.info(`fetch_resource: saved to ${finalPath}`);\n\n return json({\n message_id: p.message_id,\n file_key: p.file_key,\n type: p.type,\n size_bytes: buffer.length,\n content_type: contentType,\n saved_path: finalPath,\n });\n } catch (err) {\n log.error(`fetch_resource: failed to save file: ${err}`);\n return json({\n error: `\u4FDD\u5B58\u6587\u4EF6\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n } catch (err) {\n return await handleInvokeErrorWithAutoAuth(err, cfg);\n }\n },\n },\n { name: 'feishu_im_user_fetch_resource' },\n );\n\n api.logger.info?.('feishu_im_user_fetch_resource: Registered feishu_im_user_fetch_resource tool');\n}\n"],
5
+ "mappings": "AAaA,SAAS,+BAA+B;AACxC,SAAS,YAAY;AACrB,SAAS,MAAM,mBAAmB,qCAAqC;AACvE,YAAY,QAAQ;AACpB,YAAY,UAAU;AAMtB,MAAM,cAAsC;AAAA;AAAA,EAE1C,aAAa;AAAA,EACb,cAAc;AAAA,EACd,aAAa;AAAA,EACb,aAAa;AAAA,EACb,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,cAAc;AAAA;AAAA,EAEd,aAAa;AAAA,EACb,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,cAAc;AAAA;AAAA,EAEd,cAAc;AAAA,EACd,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA;AAAA,EAEb,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,2EAA2E;AAAA,EAC3E,4BAA4B;AAAA,EAC5B,qEAAqE;AAAA,EACrE,iCAAiC;AAAA,EACjC,6EAA6E;AAAA;AAAA,EAE7E,mBAAmB;AAAA,EACnB,gCAAgC;AAAA,EAChC,cAAc;AAAA,EACd,oBAAoB;AACtB;AAMA,MAAM,sBAAsB,KAAK,OAAO;AAAA,EACtC,YAAY,KAAK,OAAO;AAAA,IACtB,aAAa;AAAA,EACf,CAAC;AAAA,EACD,UAAU,KAAK,OAAO;AAAA,IACpB,aAAa;AAAA,EACf,CAAC;AAAA,EACD,MAAM,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,GAAG,KAAK,QAAQ,MAAM,CAAC,GAAG;AAAA,IAC9D,aAAa;AAAA,EACf,CAAC;AACH,CAAC;AAgBM,SAAS,sCAAsC,KAAwB;AAC5E,MAAI,CAAC,IAAI,OAAQ;AACjB,QAAM,MAAM,IAAI;AAEhB,QAAM,EAAE,YAAY,IAAI,IAAI,kBAAkB,KAAK,+BAA+B;AAElF,MAAI;AAAA,IACF;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aACE;AAAA,MAWF,YAAY;AAAA,MACZ,MAAM,QAAQ,aAAqB,QAAiB;AAClD,cAAM,IAAI;AACV,YAAI;AACF,gBAAM,SAAS,WAAW;AAE1B,cAAI,KAAK,+BAA+B,EAAE,UAAU,gBAAgB,EAAE,QAAQ,YAAY,EAAE,IAAI,GAAG;AAGnG,gBAAM,MAAW,MAAM,OAAO;AAAA,YAC5B;AAAA,YACA,CAAC,KAAK,SACJ,IAAI,GAAG,GAAG,gBAAgB;AAAA,cACxB;AAAA,gBACE,QAAQ,EAAE,MAAM,EAAE,KAAK;AAAA,gBACvB,MAAM,EAAE,YAAY,EAAE,YAAY,UAAU,EAAE,SAAS;AAAA,cACzD;AAAA,cACA;AAAA,YACF;AAAA,YACF;AAAA,cACE,IAAI;AAAA,YACN;AAAA,UACF;AAGA,gBAAM,SAAS,IAAI,kBAAkB;AACrC,gBAAM,SAAmB,CAAC;AAE1B,2BAAiB,SAAS,QAAQ;AAChC,mBAAO,KAAK,KAAK;AAAA,UACnB;AAEA,gBAAM,SAAS,OAAO,OAAO,MAAM;AAEnC,cAAI,KAAK,8BAA8B,OAAO,MAAM,QAAQ;AAG5D,gBAAM,cAAc,IAAI,UAAU,cAAc,KAAK;AACrD,cAAI,KAAK,gCAAgC,WAAW,EAAE;AAGtD,gBAAM,WAAW,cAAc,YAAY,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,IAAI;AAClE,gBAAM,UAAU,WAAW,YAAY,QAAQ,IAAI;AAEnD,gBAAM,YAAY,wBAAwB;AAAA,YACxC,QAAQ;AAAA,YACR,WAAW;AAAA,UACb,CAAC;AACD,cAAI,KAAK,6BAA6B,SAAS,EAAE;AAGjD,gBAAM,GAAG,MAAM,KAAK,QAAQ,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAG3D,cAAI;AACF,kBAAM,GAAG,UAAU,WAAW,MAAM;AACpC,gBAAI,KAAK,4BAA4B,SAAS,EAAE;AAEhD,mBAAO,KAAK;AAAA,cACV,YAAY,EAAE;AAAA,cACd,UAAU,EAAE;AAAA,cACZ,MAAM,EAAE;AAAA,cACR,YAAY,OAAO;AAAA,cACnB,cAAc;AAAA,cACd,YAAY;AAAA,YACd,CAAC;AAAA,UACH,SAAS,KAAK;AACZ,gBAAI,MAAM,wCAAwC,GAAG,EAAE;AACvD,mBAAO,KAAK;AAAA,cACV,OAAO,yCAAW,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,YACpE,CAAC;AAAA,UACH;AAAA,QACF,SAAS,KAAK;AACZ,iBAAO,MAAM,8BAA8B,KAAK,GAAG;AAAA,QACrD;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,MAAM,gCAAgC;AAAA,EAC1C;AAEA,MAAI,OAAO,OAAO,8EAA8E;AAClG;",
6
+ "names": []
7
+ }
@@ -0,0 +1,169 @@
1
+ const BJ_OFFSET_MS = 8 * 60 * 60 * 1e3;
2
+ function formatBeijingISO(d) {
3
+ const bj = new Date(d.getTime() + BJ_OFFSET_MS);
4
+ const y = bj.getUTCFullYear();
5
+ const mo = String(bj.getUTCMonth() + 1).padStart(2, "0");
6
+ const da = String(bj.getUTCDate()).padStart(2, "0");
7
+ const h = String(bj.getUTCHours()).padStart(2, "0");
8
+ const mi = String(bj.getUTCMinutes()).padStart(2, "0");
9
+ const s = String(bj.getUTCSeconds()).padStart(2, "0");
10
+ return `${y}-${mo}-${da}T${h}:${mi}:${s}+08:00`;
11
+ }
12
+ function secondsToDateTime(seconds) {
13
+ return formatBeijingISO(new Date(seconds * 1e3));
14
+ }
15
+ function secondsStringToDateTime(seconds) {
16
+ return secondsToDateTime(parseInt(seconds, 10));
17
+ }
18
+ function millisToDateTime(millis) {
19
+ return formatBeijingISO(new Date(millis));
20
+ }
21
+ function millisStringToDateTime(millis) {
22
+ return millisToDateTime(parseInt(millis, 10));
23
+ }
24
+ function dateTimeToSeconds(datetime) {
25
+ const d = new Date(datetime);
26
+ if (isNaN(d.getTime())) {
27
+ throw new Error(`\u65E0\u6CD5\u89E3\u6790 ISO 8601 \u65F6\u95F4: "${datetime}"\u3002\u683C\u5F0F\u793A\u4F8B: 2026-02-27T14:30:00+08:00`);
28
+ }
29
+ return Math.floor(d.getTime() / 1e3);
30
+ }
31
+ function dateTimeToSecondsString(datetime) {
32
+ return dateTimeToSeconds(datetime).toString();
33
+ }
34
+ function dateTimeToMillis(datetime) {
35
+ const d = new Date(datetime);
36
+ if (isNaN(d.getTime())) {
37
+ throw new Error(`\u65E0\u6CD5\u89E3\u6790 ISO 8601 \u65F6\u95F4: "${datetime}"\u3002\u683C\u5F0F\u793A\u4F8B: 2026-02-27T14:30:00+08:00`);
38
+ }
39
+ return d.getTime();
40
+ }
41
+ function parseTimeRange(input) {
42
+ const now = /* @__PURE__ */ new Date();
43
+ const bjNow = toBeijingDate(now);
44
+ let start;
45
+ let end;
46
+ switch (input) {
47
+ case "today":
48
+ start = beijingStartOfDay(bjNow);
49
+ end = now;
50
+ break;
51
+ case "yesterday": {
52
+ const d = new Date(bjNow);
53
+ d.setUTCDate(d.getUTCDate() - 1);
54
+ start = beijingStartOfDay(d);
55
+ end = beijingEndOfDay(d);
56
+ break;
57
+ }
58
+ case "day_before_yesterday": {
59
+ const d = new Date(bjNow);
60
+ d.setUTCDate(d.getUTCDate() - 2);
61
+ start = beijingStartOfDay(d);
62
+ end = beijingEndOfDay(d);
63
+ break;
64
+ }
65
+ case "this_week": {
66
+ const day = bjNow.getUTCDay();
67
+ const diffToMon = day === 0 ? 6 : day - 1;
68
+ const monday = new Date(bjNow);
69
+ monday.setUTCDate(monday.getUTCDate() - diffToMon);
70
+ start = beijingStartOfDay(monday);
71
+ end = now;
72
+ break;
73
+ }
74
+ case "last_week": {
75
+ const day = bjNow.getUTCDay();
76
+ const diffToMon = day === 0 ? 6 : day - 1;
77
+ const thisMonday = new Date(bjNow);
78
+ thisMonday.setUTCDate(thisMonday.getUTCDate() - diffToMon);
79
+ const lastMonday = new Date(thisMonday);
80
+ lastMonday.setUTCDate(lastMonday.getUTCDate() - 7);
81
+ const lastSunday = new Date(thisMonday);
82
+ lastSunday.setUTCDate(lastSunday.getUTCDate() - 1);
83
+ start = beijingStartOfDay(lastMonday);
84
+ end = beijingEndOfDay(lastSunday);
85
+ break;
86
+ }
87
+ case "this_month": {
88
+ const firstDay = new Date(Date.UTC(bjNow.getUTCFullYear(), bjNow.getUTCMonth(), 1));
89
+ start = beijingStartOfDay(firstDay);
90
+ end = now;
91
+ break;
92
+ }
93
+ case "last_month": {
94
+ const firstDayThisMonth = new Date(Date.UTC(bjNow.getUTCFullYear(), bjNow.getUTCMonth(), 1));
95
+ const lastDayPrevMonth = new Date(firstDayThisMonth);
96
+ lastDayPrevMonth.setUTCDate(lastDayPrevMonth.getUTCDate() - 1);
97
+ const firstDayPrevMonth = new Date(
98
+ Date.UTC(lastDayPrevMonth.getUTCFullYear(), lastDayPrevMonth.getUTCMonth(), 1)
99
+ );
100
+ start = beijingStartOfDay(firstDayPrevMonth);
101
+ end = beijingEndOfDay(lastDayPrevMonth);
102
+ break;
103
+ }
104
+ default: {
105
+ const match = input.match(/^last_(\d+)_(minutes?|hours?|days?)$/);
106
+ if (!match) {
107
+ throw new Error(
108
+ `\u4E0D\u652F\u6301\u7684 relative_time \u683C\u5F0F: "${input}"\u3002\u652F\u6301: today, yesterday, day_before_yesterday, this_week, last_week, this_month, last_month, last_{N}_{unit}\uFF08unit: minutes/hours/days\uFF09`
109
+ );
110
+ }
111
+ const n = parseInt(match[1], 10);
112
+ const unit = match[2].replace(/s$/, "");
113
+ start = subtractFromNow(now, n, unit);
114
+ end = now;
115
+ break;
116
+ }
117
+ }
118
+ return {
119
+ start: formatBeijingISO(start),
120
+ end: formatBeijingISO(end)
121
+ };
122
+ }
123
+ function parseTimeRangeToSeconds(input) {
124
+ const range = parseTimeRange(input);
125
+ return {
126
+ start: dateTimeToSecondsString(range.start),
127
+ end: dateTimeToSecondsString(range.end)
128
+ };
129
+ }
130
+ function toBeijingDate(d) {
131
+ return new Date(d.getTime() + BJ_OFFSET_MS);
132
+ }
133
+ function beijingStartOfDay(bjDate) {
134
+ return new Date(Date.UTC(bjDate.getUTCFullYear(), bjDate.getUTCMonth(), bjDate.getUTCDate()) - BJ_OFFSET_MS);
135
+ }
136
+ function beijingEndOfDay(bjDate) {
137
+ return new Date(
138
+ Date.UTC(bjDate.getUTCFullYear(), bjDate.getUTCMonth(), bjDate.getUTCDate(), 23, 59, 59) - BJ_OFFSET_MS
139
+ );
140
+ }
141
+ function subtractFromNow(now, n, unit) {
142
+ const d = new Date(now);
143
+ switch (unit) {
144
+ case "minute":
145
+ d.setMinutes(d.getMinutes() - n);
146
+ break;
147
+ case "hour":
148
+ d.setHours(d.getHours() - n);
149
+ break;
150
+ case "day":
151
+ d.setDate(d.getDate() - n);
152
+ break;
153
+ default:
154
+ throw new Error(`\u4E0D\u652F\u6301\u7684\u65F6\u95F4\u5355\u4F4D: ${unit}`);
155
+ }
156
+ return d;
157
+ }
158
+ export {
159
+ dateTimeToMillis,
160
+ dateTimeToSeconds,
161
+ dateTimeToSecondsString,
162
+ millisStringToDateTime,
163
+ millisToDateTime,
164
+ parseTimeRange,
165
+ parseTimeRangeToSeconds,
166
+ secondsStringToDateTime,
167
+ secondsToDateTime
168
+ };
169
+ //# sourceMappingURL=time-utils.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/tools/oapi/im/time-utils.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * \u65F6\u95F4\u5DE5\u5177\u51FD\u6570 \u2014 \u5BF9\u9F50 Go \u5B9E\u73B0 (time.go + timerange.go)\n *\n * \u4EE5 ISO 8601 (RFC 3339) \u4F5C\u4E3A\u6807\u51C6\u65F6\u95F4\u4EA4\u6362\u683C\u5F0F\uFF0C\n * \u63D0\u4F9B ISO 8601 \u2194 Unix \u8F6C\u6362\u5DE5\u5177\u53CA\u65F6\u95F4\u8303\u56F4\u89E3\u6790\u3002\n */\n\nconst BJ_OFFSET_MS = 8 * 60 * 60 * 1000;\n\n// ===========================================================================\n// ISO 8601 \u2194 Unix \u8F6C\u6362\u5DE5\u5177\uFF08\u5BF9\u9F50 time.go\uFF09\n// ===========================================================================\n\n/** \u5C06 Date \u683C\u5F0F\u5316\u4E3A\u5317\u4EAC\u65F6\u95F4 ISO 8601 \u5B57\u7B26\u4E32 */\nfunction formatBeijingISO(d: Date): string {\n const bj = new Date(d.getTime() + BJ_OFFSET_MS);\n const y = bj.getUTCFullYear();\n const mo = String(bj.getUTCMonth() + 1).padStart(2, '0');\n const da = String(bj.getUTCDate()).padStart(2, '0');\n const h = String(bj.getUTCHours()).padStart(2, '0');\n const mi = String(bj.getUTCMinutes()).padStart(2, '0');\n const s = String(bj.getUTCSeconds()).padStart(2, '0');\n return `${y}-${mo}-${da}T${h}:${mi}:${s}+08:00`;\n}\n\n// ---------------------------------------------------------------------------\n// Unix \u79D2 \u2192 ISO 8601\n// ---------------------------------------------------------------------------\n\n/** Unix \u79D2\uFF08\u6570\u5B57\uFF09\u2192 ISO 8601 \u5317\u4EAC\u65F6\u95F4 */\nexport function secondsToDateTime(seconds: number): string {\n return formatBeijingISO(new Date(seconds * 1000));\n}\n\n/** Unix \u79D2\uFF08\u5B57\u7B26\u4E32\uFF09\u2192 ISO 8601 \u5317\u4EAC\u65F6\u95F4 */\nexport function secondsStringToDateTime(seconds: string): string {\n return secondsToDateTime(parseInt(seconds, 10));\n}\n\n// ---------------------------------------------------------------------------\n// Unix \u6BEB\u79D2 \u2192 ISO 8601\n// ---------------------------------------------------------------------------\n\n/** Unix \u6BEB\u79D2\uFF08\u6570\u5B57\uFF09\u2192 ISO 8601 \u5317\u4EAC\u65F6\u95F4 */\nexport function millisToDateTime(millis: number): string {\n return formatBeijingISO(new Date(millis));\n}\n\n/** Unix \u6BEB\u79D2\uFF08\u5B57\u7B26\u4E32\uFF09\u2192 ISO 8601 \u5317\u4EAC\u65F6\u95F4 */\nexport function millisStringToDateTime(millis: string): string {\n return millisToDateTime(parseInt(millis, 10));\n}\n\n// ---------------------------------------------------------------------------\n// ISO 8601 \u2192 Unix\n// ---------------------------------------------------------------------------\n\n/** ISO 8601 \u2192 Unix \u79D2\uFF08\u6570\u5B57\uFF09 */\nexport function dateTimeToSeconds(datetime: string): number {\n const d = new Date(datetime);\n if (isNaN(d.getTime())) {\n throw new Error(`\u65E0\u6CD5\u89E3\u6790 ISO 8601 \u65F6\u95F4: \"${datetime}\"\u3002\u683C\u5F0F\u793A\u4F8B: 2026-02-27T14:30:00+08:00`);\n }\n return Math.floor(d.getTime() / 1000);\n}\n\n/** ISO 8601 \u2192 Unix \u79D2\uFF08\u5B57\u7B26\u4E32\uFF09 */\nexport function dateTimeToSecondsString(datetime: string): string {\n return dateTimeToSeconds(datetime).toString();\n}\n\n/** ISO 8601 \u2192 Unix \u6BEB\u79D2\uFF08\u6570\u5B57\uFF09 */\nexport function dateTimeToMillis(datetime: string): number {\n const d = new Date(datetime);\n if (isNaN(d.getTime())) {\n throw new Error(`\u65E0\u6CD5\u89E3\u6790 ISO 8601 \u65F6\u95F4: \"${datetime}\"\u3002\u683C\u5F0F\u793A\u4F8B: 2026-02-27T14:30:00+08:00`);\n }\n return d.getTime();\n}\n\n// ===========================================================================\n// \u65F6\u95F4\u8303\u56F4\u89E3\u6790\uFF08\u5BF9\u9F50 timerange.go\uFF09\n// ===========================================================================\n\n/** ISO 8601 \u65F6\u95F4\u8303\u56F4 */\nexport interface TimeRange {\n start: string;\n end: string;\n}\n\n/**\n * \u89E3\u6790\u65F6\u95F4\u8303\u56F4\u6807\u8BC6\uFF0C\u8FD4\u56DE ISO 8601 \u5B57\u7B26\u4E32\u5BF9\u3002\n *\n * \u652F\u6301\u7684\u683C\u5F0F\uFF1A\n * - `today` / `yesterday` / `day_before_yesterday`\n * - `this_week` / `last_week` / `this_month` / `last_month`\n * - `last_{N}_{unit}` \u2014 unit: minutes / hours / days\n *\n * \u6240\u6709\u8BA1\u7B97\u57FA\u4E8E\u5317\u4EAC\u65F6\u95F4 (UTC+8)\u3002\n */\nexport function parseTimeRange(input: string): TimeRange {\n const now = new Date();\n const bjNow = toBeijingDate(now);\n\n let start: Date;\n let end: Date;\n\n switch (input) {\n case 'today':\n start = beijingStartOfDay(bjNow);\n end = now;\n break;\n\n case 'yesterday': {\n const d = new Date(bjNow);\n d.setUTCDate(d.getUTCDate() - 1);\n start = beijingStartOfDay(d);\n end = beijingEndOfDay(d);\n break;\n }\n\n case 'day_before_yesterday': {\n const d = new Date(bjNow);\n d.setUTCDate(d.getUTCDate() - 2);\n start = beijingStartOfDay(d);\n end = beijingEndOfDay(d);\n break;\n }\n\n case 'this_week': {\n const day = bjNow.getUTCDay(); // 0=Sun .. 6=Sat\n const diffToMon = day === 0 ? 6 : day - 1;\n const monday = new Date(bjNow);\n monday.setUTCDate(monday.getUTCDate() - diffToMon);\n start = beijingStartOfDay(monday);\n end = now;\n break;\n }\n\n case 'last_week': {\n const day = bjNow.getUTCDay();\n const diffToMon = day === 0 ? 6 : day - 1;\n const thisMonday = new Date(bjNow);\n thisMonday.setUTCDate(thisMonday.getUTCDate() - diffToMon);\n const lastMonday = new Date(thisMonday);\n lastMonday.setUTCDate(lastMonday.getUTCDate() - 7);\n const lastSunday = new Date(thisMonday);\n lastSunday.setUTCDate(lastSunday.getUTCDate() - 1);\n start = beijingStartOfDay(lastMonday);\n end = beijingEndOfDay(lastSunday);\n break;\n }\n\n case 'this_month': {\n const firstDay = new Date(Date.UTC(bjNow.getUTCFullYear(), bjNow.getUTCMonth(), 1));\n start = beijingStartOfDay(firstDay);\n end = now;\n break;\n }\n\n case 'last_month': {\n const firstDayThisMonth = new Date(Date.UTC(bjNow.getUTCFullYear(), bjNow.getUTCMonth(), 1));\n const lastDayPrevMonth = new Date(firstDayThisMonth);\n lastDayPrevMonth.setUTCDate(lastDayPrevMonth.getUTCDate() - 1);\n const firstDayPrevMonth = new Date(\n Date.UTC(lastDayPrevMonth.getUTCFullYear(), lastDayPrevMonth.getUTCMonth(), 1),\n );\n start = beijingStartOfDay(firstDayPrevMonth);\n end = beijingEndOfDay(lastDayPrevMonth);\n break;\n }\n\n default: {\n // last_{N}_{unit} \u2014 \u53EA\u652F\u6301 minutes / hours / days\uFF08\u5BF9\u9F50 Go\uFF09\n const match = input.match(/^last_(\\d+)_(minutes?|hours?|days?)$/);\n if (!match) {\n throw new Error(\n `\u4E0D\u652F\u6301\u7684 relative_time \u683C\u5F0F: \"${input}\"\u3002` +\n '\u652F\u6301: today, yesterday, day_before_yesterday, this_week, last_week, this_month, last_month, last_{N}_{unit}\uFF08unit: minutes/hours/days\uFF09',\n );\n }\n const n = parseInt(match[1], 10);\n const unit = match[2].replace(/s$/, ''); // normalize plural\n start = subtractFromNow(now, n, unit);\n end = now;\n break;\n }\n }\n\n return {\n start: formatBeijingISO(start),\n end: formatBeijingISO(end),\n };\n}\n\n/**\n * \u89E3\u6790\u65F6\u95F4\u8303\u56F4\u6807\u8BC6\uFF0C\u8FD4\u56DE Unix \u79D2\u5B57\u7B26\u4E32\u5BF9\uFF08\u4F9B SDK \u8C03\u7528\uFF09\u3002\n */\nexport function parseTimeRangeToSeconds(input: string): { start: string; end: string } {\n const range = parseTimeRange(input);\n return {\n start: dateTimeToSecondsString(range.start),\n end: dateTimeToSecondsString(range.end),\n };\n}\n\n// ===========================================================================\n// Internal helpers\n// ===========================================================================\n\n/** \u5C06 UTC Date \u8F6C\u4E3A\u300C\u5317\u4EAC\u65F6\u95F4\u5404\u90E8\u5206\u5B58\u5728 UTC \u5B57\u6BB5\u4E0A\u300D\u7684 Date */\nfunction toBeijingDate(d: Date): Date {\n return new Date(d.getTime() + BJ_OFFSET_MS);\n}\n\n/** \u5317\u4EAC\u65F6\u95F4\u5F53\u5929 00:00:00 \u5BF9\u5E94\u7684\u771F\u5B9E UTC Date */\nfunction beijingStartOfDay(bjDate: Date): Date {\n return new Date(Date.UTC(bjDate.getUTCFullYear(), bjDate.getUTCMonth(), bjDate.getUTCDate()) - BJ_OFFSET_MS);\n}\n\n/** \u5317\u4EAC\u65F6\u95F4\u5F53\u5929 23:59:59 \u5BF9\u5E94\u7684\u771F\u5B9E UTC Date */\nfunction beijingEndOfDay(bjDate: Date): Date {\n return new Date(\n Date.UTC(bjDate.getUTCFullYear(), bjDate.getUTCMonth(), bjDate.getUTCDate(), 23, 59, 59) - BJ_OFFSET_MS,\n );\n}\n\nfunction subtractFromNow(now: Date, n: number, unit: string): Date {\n const d = new Date(now);\n switch (unit) {\n case 'minute':\n d.setMinutes(d.getMinutes() - n);\n break;\n case 'hour':\n d.setHours(d.getHours() - n);\n break;\n case 'day':\n d.setDate(d.getDate() - n);\n break;\n default:\n throw new Error(`\u4E0D\u652F\u6301\u7684\u65F6\u95F4\u5355\u4F4D: ${unit}`);\n }\n return d;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }