@colinlu50/openclaw-lark-stream 2026.3.17

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 (361) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/README.zh.md +70 -0
  4. package/bin/openclaw-lark.js +48 -0
  5. package/index.d.ts +36 -0
  6. package/index.js +118 -0
  7. package/openclaw.plugin.json +10 -0
  8. package/package.json +66 -0
  9. package/skills/feishu-bitable/SKILL.md +248 -0
  10. package/skills/feishu-bitable/references/examples.md +813 -0
  11. package/skills/feishu-bitable/references/field-properties.md +763 -0
  12. package/skills/feishu-bitable/references/record-values.md +911 -0
  13. package/skills/feishu-calendar/SKILL.md +244 -0
  14. package/skills/feishu-channel-rules/SKILL.md +24 -0
  15. package/skills/feishu-channel-rules/references/markdown-syntax.md +138 -0
  16. package/skills/feishu-create-doc/SKILL.md +719 -0
  17. package/skills/feishu-fetch-doc/SKILL.md +93 -0
  18. package/skills/feishu-im-read/SKILL.md +163 -0
  19. package/skills/feishu-task/SKILL.md +293 -0
  20. package/skills/feishu-troubleshoot/SKILL.md +70 -0
  21. package/skills/feishu-update-doc/SKILL.md +285 -0
  22. package/src/card/builder.d.ts +106 -0
  23. package/src/card/builder.js +443 -0
  24. package/src/card/cardkit.d.ts +90 -0
  25. package/src/card/cardkit.js +181 -0
  26. package/src/card/flush-controller.d.ts +45 -0
  27. package/src/card/flush-controller.js +134 -0
  28. package/src/card/image-resolver.d.ts +45 -0
  29. package/src/card/image-resolver.js +112 -0
  30. package/src/card/markdown-style.d.ts +16 -0
  31. package/src/card/markdown-style.js +97 -0
  32. package/src/card/reply-dispatcher-types.d.ts +120 -0
  33. package/src/card/reply-dispatcher-types.js +57 -0
  34. package/src/card/reply-dispatcher.d.ts +15 -0
  35. package/src/card/reply-dispatcher.js +299 -0
  36. package/src/card/reply-mode.d.ts +38 -0
  37. package/src/card/reply-mode.js +65 -0
  38. package/src/card/streaming-card-controller.d.ts +101 -0
  39. package/src/card/streaming-card-controller.js +810 -0
  40. package/src/card/unavailable-guard.d.ts +35 -0
  41. package/src/card/unavailable-guard.js +83 -0
  42. package/src/channel/abort-detect.d.ts +34 -0
  43. package/src/channel/abort-detect.js +124 -0
  44. package/src/channel/chat-queue.d.ts +41 -0
  45. package/src/channel/chat-queue.js +58 -0
  46. package/src/channel/config-adapter.d.ts +23 -0
  47. package/src/channel/config-adapter.js +101 -0
  48. package/src/channel/directory.d.ts +57 -0
  49. package/src/channel/directory.js +191 -0
  50. package/src/channel/event-handlers.d.ts +15 -0
  51. package/src/channel/event-handlers.js +221 -0
  52. package/src/channel/monitor.d.ts +17 -0
  53. package/src/channel/monitor.js +129 -0
  54. package/src/channel/onboarding-config.d.ts +17 -0
  55. package/src/channel/onboarding-config.js +88 -0
  56. package/src/channel/onboarding-migrate.d.ts +25 -0
  57. package/src/channel/onboarding-migrate.js +67 -0
  58. package/src/channel/onboarding.d.ts +12 -0
  59. package/src/channel/onboarding.js +296 -0
  60. package/src/channel/plugin.d.ts +13 -0
  61. package/src/channel/plugin.js +278 -0
  62. package/src/channel/probe.d.ts +14 -0
  63. package/src/channel/probe.js +21 -0
  64. package/src/channel/types.d.ts +36 -0
  65. package/src/channel/types.js +7 -0
  66. package/src/commands/auth.d.ts +21 -0
  67. package/src/commands/auth.js +161 -0
  68. package/src/commands/diagnose.d.ts +69 -0
  69. package/src/commands/diagnose.js +807 -0
  70. package/src/commands/doctor.d.ts +26 -0
  71. package/src/commands/doctor.js +584 -0
  72. package/src/commands/index.d.ts +25 -0
  73. package/src/commands/index.js +212 -0
  74. package/src/commands/locale.d.ts +7 -0
  75. package/src/commands/locale.js +7 -0
  76. package/src/core/accounts.d.ts +37 -0
  77. package/src/core/accounts.js +163 -0
  78. package/src/core/agent-config.d.ts +100 -0
  79. package/src/core/agent-config.js +139 -0
  80. package/src/core/api-error.d.ts +48 -0
  81. package/src/core/api-error.js +112 -0
  82. package/src/core/app-owner-fallback.d.ts +21 -0
  83. package/src/core/app-owner-fallback.js +38 -0
  84. package/src/core/app-scope-checker.d.ts +87 -0
  85. package/src/core/app-scope-checker.js +190 -0
  86. package/src/core/auth-errors.d.ts +144 -0
  87. package/src/core/auth-errors.js +154 -0
  88. package/src/core/chat-info-cache.d.ts +57 -0
  89. package/src/core/chat-info-cache.js +152 -0
  90. package/src/core/config-schema.d.ts +448 -0
  91. package/src/core/config-schema.js +200 -0
  92. package/src/core/device-flow.d.ts +77 -0
  93. package/src/core/device-flow.js +212 -0
  94. package/src/core/domains.d.ts +18 -0
  95. package/src/core/domains.js +28 -0
  96. package/src/core/feishu-fetch.d.ts +18 -0
  97. package/src/core/feishu-fetch.js +25 -0
  98. package/src/core/footer-config.d.ts +24 -0
  99. package/src/core/footer-config.js +39 -0
  100. package/src/core/lark-client.d.ts +108 -0
  101. package/src/core/lark-client.js +353 -0
  102. package/src/core/lark-logger.d.ts +23 -0
  103. package/src/core/lark-logger.js +154 -0
  104. package/src/core/lark-ticket.d.ts +29 -0
  105. package/src/core/lark-ticket.js +35 -0
  106. package/src/core/message-unavailable.d.ts +53 -0
  107. package/src/core/message-unavailable.js +130 -0
  108. package/src/core/owner-policy.d.ts +31 -0
  109. package/src/core/owner-policy.js +52 -0
  110. package/src/core/permission-url.d.ts +22 -0
  111. package/src/core/permission-url.js +72 -0
  112. package/src/core/raw-request.d.ts +27 -0
  113. package/src/core/raw-request.js +62 -0
  114. package/src/core/scope-manager.d.ts +168 -0
  115. package/src/core/scope-manager.js +213 -0
  116. package/src/core/security-check.d.ts +72 -0
  117. package/src/core/security-check.js +174 -0
  118. package/src/core/shutdown-hooks.d.ts +22 -0
  119. package/src/core/shutdown-hooks.js +56 -0
  120. package/src/core/targets.d.ts +60 -0
  121. package/src/core/targets.js +164 -0
  122. package/src/core/token-store.d.ts +54 -0
  123. package/src/core/token-store.js +314 -0
  124. package/src/core/tool-client.d.ts +176 -0
  125. package/src/core/tool-client.js +380 -0
  126. package/src/core/tool-scopes.d.ts +153 -0
  127. package/src/core/tool-scopes.js +326 -0
  128. package/src/core/tools-config.d.ts +55 -0
  129. package/src/core/tools-config.js +137 -0
  130. package/src/core/types.d.ts +87 -0
  131. package/src/core/types.js +11 -0
  132. package/src/core/uat-client.d.ts +46 -0
  133. package/src/core/uat-client.js +187 -0
  134. package/src/core/version.d.ts +25 -0
  135. package/src/core/version.js +49 -0
  136. package/src/messaging/converters/audio.d.ts +8 -0
  137. package/src/messaging/converters/audio.js +21 -0
  138. package/src/messaging/converters/calendar.d.ts +13 -0
  139. package/src/messaging/converters/calendar.js +50 -0
  140. package/src/messaging/converters/content-converter.d.ts +41 -0
  141. package/src/messaging/converters/content-converter.js +106 -0
  142. package/src/messaging/converters/file.d.ts +8 -0
  143. package/src/messaging/converters/file.js +20 -0
  144. package/src/messaging/converters/folder.d.ts +8 -0
  145. package/src/messaging/converters/folder.js +20 -0
  146. package/src/messaging/converters/hongbao.d.ts +8 -0
  147. package/src/messaging/converters/hongbao.js +16 -0
  148. package/src/messaging/converters/image.d.ts +8 -0
  149. package/src/messaging/converters/image.js +18 -0
  150. package/src/messaging/converters/index.d.ts +8 -0
  151. package/src/messaging/converters/index.js +50 -0
  152. package/src/messaging/converters/interactive/card-converter.d.ts +76 -0
  153. package/src/messaging/converters/interactive/card-converter.js +1173 -0
  154. package/src/messaging/converters/interactive/card-utils.d.ts +9 -0
  155. package/src/messaging/converters/interactive/card-utils.js +42 -0
  156. package/src/messaging/converters/interactive/index.d.ts +8 -0
  157. package/src/messaging/converters/interactive/index.js +21 -0
  158. package/src/messaging/converters/interactive/legacy.d.ts +11 -0
  159. package/src/messaging/converters/interactive/legacy.js +57 -0
  160. package/src/messaging/converters/interactive/types.d.ts +23 -0
  161. package/src/messaging/converters/interactive/types.js +24 -0
  162. package/src/messaging/converters/location.d.ts +8 -0
  163. package/src/messaging/converters/location.js +19 -0
  164. package/src/messaging/converters/merge-forward.d.ts +32 -0
  165. package/src/messaging/converters/merge-forward.js +225 -0
  166. package/src/messaging/converters/post.d.ts +11 -0
  167. package/src/messaging/converters/post.js +135 -0
  168. package/src/messaging/converters/share.d.ts +9 -0
  169. package/src/messaging/converters/share.js +23 -0
  170. package/src/messaging/converters/sticker.d.ts +8 -0
  171. package/src/messaging/converters/sticker.js +18 -0
  172. package/src/messaging/converters/system.d.ts +12 -0
  173. package/src/messaging/converters/system.js +32 -0
  174. package/src/messaging/converters/text.d.ts +8 -0
  175. package/src/messaging/converters/text.js +14 -0
  176. package/src/messaging/converters/todo.d.ts +8 -0
  177. package/src/messaging/converters/todo.js +41 -0
  178. package/src/messaging/converters/types.d.ts +107 -0
  179. package/src/messaging/converters/types.js +7 -0
  180. package/src/messaging/converters/unknown.d.ts +8 -0
  181. package/src/messaging/converters/unknown.js +16 -0
  182. package/src/messaging/converters/utils.d.ts +22 -0
  183. package/src/messaging/converters/utils.js +51 -0
  184. package/src/messaging/converters/video-chat.d.ts +8 -0
  185. package/src/messaging/converters/video-chat.js +23 -0
  186. package/src/messaging/converters/video.d.ts +8 -0
  187. package/src/messaging/converters/video.js +32 -0
  188. package/src/messaging/converters/vote.d.ts +8 -0
  189. package/src/messaging/converters/vote.js +24 -0
  190. package/src/messaging/inbound/dedup.d.ts +59 -0
  191. package/src/messaging/inbound/dedup.js +116 -0
  192. package/src/messaging/inbound/dispatch-builders.d.ts +84 -0
  193. package/src/messaging/inbound/dispatch-builders.js +152 -0
  194. package/src/messaging/inbound/dispatch-commands.d.ts +27 -0
  195. package/src/messaging/inbound/dispatch-commands.js +112 -0
  196. package/src/messaging/inbound/dispatch-context.d.ts +67 -0
  197. package/src/messaging/inbound/dispatch-context.js +136 -0
  198. package/src/messaging/inbound/dispatch.d.ts +47 -0
  199. package/src/messaging/inbound/dispatch.js +264 -0
  200. package/src/messaging/inbound/enrich.d.ts +102 -0
  201. package/src/messaging/inbound/enrich.js +227 -0
  202. package/src/messaging/inbound/gate-effects.d.ts +23 -0
  203. package/src/messaging/inbound/gate-effects.js +43 -0
  204. package/src/messaging/inbound/gate.d.ts +60 -0
  205. package/src/messaging/inbound/gate.js +233 -0
  206. package/src/messaging/inbound/handler.d.ts +35 -0
  207. package/src/messaging/inbound/handler.js +173 -0
  208. package/src/messaging/inbound/media-resolver.d.ts +32 -0
  209. package/src/messaging/inbound/media-resolver.js +87 -0
  210. package/src/messaging/inbound/mention.d.ts +39 -0
  211. package/src/messaging/inbound/mention.js +81 -0
  212. package/src/messaging/inbound/parse-io.d.ts +50 -0
  213. package/src/messaging/inbound/parse-io.js +81 -0
  214. package/src/messaging/inbound/parse.d.ts +28 -0
  215. package/src/messaging/inbound/parse.js +106 -0
  216. package/src/messaging/inbound/permission.d.ts +17 -0
  217. package/src/messaging/inbound/permission.js +40 -0
  218. package/src/messaging/inbound/policy.d.ts +94 -0
  219. package/src/messaging/inbound/policy.js +160 -0
  220. package/src/messaging/inbound/reaction-handler.d.ts +61 -0
  221. package/src/messaging/inbound/reaction-handler.js +221 -0
  222. package/src/messaging/inbound/user-name-cache.d.ts +82 -0
  223. package/src/messaging/inbound/user-name-cache.js +241 -0
  224. package/src/messaging/outbound/actions.d.ts +16 -0
  225. package/src/messaging/outbound/actions.js +309 -0
  226. package/src/messaging/outbound/chat-manage.d.ts +64 -0
  227. package/src/messaging/outbound/chat-manage.js +111 -0
  228. package/src/messaging/outbound/deliver.d.ts +155 -0
  229. package/src/messaging/outbound/deliver.js +298 -0
  230. package/src/messaging/outbound/fetch.d.ts +12 -0
  231. package/src/messaging/outbound/fetch.js +12 -0
  232. package/src/messaging/outbound/forward.d.ts +26 -0
  233. package/src/messaging/outbound/forward.js +48 -0
  234. package/src/messaging/outbound/media-url-utils.d.ts +29 -0
  235. package/src/messaging/outbound/media-url-utils.js +130 -0
  236. package/src/messaging/outbound/media.d.ts +260 -0
  237. package/src/messaging/outbound/media.js +758 -0
  238. package/src/messaging/outbound/outbound.d.ts +89 -0
  239. package/src/messaging/outbound/outbound.js +121 -0
  240. package/src/messaging/outbound/reactions.d.ts +124 -0
  241. package/src/messaging/outbound/reactions.js +378 -0
  242. package/src/messaging/outbound/send.d.ts +152 -0
  243. package/src/messaging/outbound/send.js +355 -0
  244. package/src/messaging/outbound/typing.d.ts +71 -0
  245. package/src/messaging/outbound/typing.js +179 -0
  246. package/src/messaging/shared/message-lookup.d.ts +54 -0
  247. package/src/messaging/shared/message-lookup.js +117 -0
  248. package/src/messaging/types.d.ts +176 -0
  249. package/src/messaging/types.js +10 -0
  250. package/src/tools/auto-auth.d.ts +56 -0
  251. package/src/tools/auto-auth.js +919 -0
  252. package/src/tools/helpers.d.ts +260 -0
  253. package/src/tools/helpers.js +364 -0
  254. package/src/tools/mcp/doc/create.d.ts +12 -0
  255. package/src/tools/mcp/doc/create.js +44 -0
  256. package/src/tools/mcp/doc/fetch.d.ts +12 -0
  257. package/src/tools/mcp/doc/fetch.js +36 -0
  258. package/src/tools/mcp/doc/index.d.ts +12 -0
  259. package/src/tools/mcp/doc/index.js +41 -0
  260. package/src/tools/mcp/doc/update.d.ts +12 -0
  261. package/src/tools/mcp/doc/update.js +61 -0
  262. package/src/tools/mcp/shared.d.ts +59 -0
  263. package/src/tools/mcp/shared.js +226 -0
  264. package/src/tools/oapi/bitable/app-table-field.d.ts +16 -0
  265. package/src/tools/oapi/bitable/app-table-field.js +222 -0
  266. package/src/tools/oapi/bitable/app-table-record.d.ts +20 -0
  267. package/src/tools/oapi/bitable/app-table-record.js +436 -0
  268. package/src/tools/oapi/bitable/app-table-view.d.ts +17 -0
  269. package/src/tools/oapi/bitable/app-table-view.js +195 -0
  270. package/src/tools/oapi/bitable/app-table.d.ts +19 -0
  271. package/src/tools/oapi/bitable/app-table.js +247 -0
  272. package/src/tools/oapi/bitable/app.d.ts +18 -0
  273. package/src/tools/oapi/bitable/app.js +186 -0
  274. package/src/tools/oapi/bitable/index.d.ts +9 -0
  275. package/src/tools/oapi/bitable/index.js +9 -0
  276. package/src/tools/oapi/calendar/calendar.d.ts +15 -0
  277. package/src/tools/oapi/calendar/calendar.js +122 -0
  278. package/src/tools/oapi/calendar/event-attendee.d.ts +16 -0
  279. package/src/tools/oapi/calendar/event-attendee.js +263 -0
  280. package/src/tools/oapi/calendar/event.d.ts +16 -0
  281. package/src/tools/oapi/calendar/event.js +709 -0
  282. package/src/tools/oapi/calendar/freebusy.d.ts +13 -0
  283. package/src/tools/oapi/calendar/freebusy.js +111 -0
  284. package/src/tools/oapi/calendar/index.d.ts +8 -0
  285. package/src/tools/oapi/calendar/index.js +8 -0
  286. package/src/tools/oapi/chat/chat.d.ts +16 -0
  287. package/src/tools/oapi/chat/chat.js +124 -0
  288. package/src/tools/oapi/chat/index.d.ts +10 -0
  289. package/src/tools/oapi/chat/index.js +15 -0
  290. package/src/tools/oapi/chat/members.d.ts +11 -0
  291. package/src/tools/oapi/chat/members.js +81 -0
  292. package/src/tools/oapi/common/get-user.d.ts +12 -0
  293. package/src/tools/oapi/common/get-user.js +106 -0
  294. package/src/tools/oapi/common/index.d.ts +6 -0
  295. package/src/tools/oapi/common/index.js +6 -0
  296. package/src/tools/oapi/common/search-user.d.ts +11 -0
  297. package/src/tools/oapi/common/search-user.js +73 -0
  298. package/src/tools/oapi/drive/doc-comments.d.ts +15 -0
  299. package/src/tools/oapi/drive/doc-comments.js +279 -0
  300. package/src/tools/oapi/drive/doc-media.d.ts +19 -0
  301. package/src/tools/oapi/drive/doc-media.js +335 -0
  302. package/src/tools/oapi/drive/file.d.ts +19 -0
  303. package/src/tools/oapi/drive/file.js +483 -0
  304. package/src/tools/oapi/drive/index.d.ts +12 -0
  305. package/src/tools/oapi/drive/index.js +36 -0
  306. package/src/tools/oapi/helpers.d.ts +182 -0
  307. package/src/tools/oapi/helpers.js +354 -0
  308. package/src/tools/oapi/im/format-messages.d.ts +50 -0
  309. package/src/tools/oapi/im/format-messages.js +165 -0
  310. package/src/tools/oapi/im/index.d.ts +10 -0
  311. package/src/tools/oapi/im/index.js +17 -0
  312. package/src/tools/oapi/im/message-read.d.ts +13 -0
  313. package/src/tools/oapi/im/message-read.js +411 -0
  314. package/src/tools/oapi/im/message.d.ts +16 -0
  315. package/src/tools/oapi/im/message.js +149 -0
  316. package/src/tools/oapi/im/resource.d.ts +13 -0
  317. package/src/tools/oapi/im/resource.js +150 -0
  318. package/src/tools/oapi/im/time-utils.d.ts +46 -0
  319. package/src/tools/oapi/im/time-utils.js +201 -0
  320. package/src/tools/oapi/im/user-name-uat.d.ts +26 -0
  321. package/src/tools/oapi/im/user-name-uat.js +140 -0
  322. package/src/tools/oapi/index.d.ts +11 -0
  323. package/src/tools/oapi/index.js +58 -0
  324. package/src/tools/oapi/sdk-types.d.ts +96 -0
  325. package/src/tools/oapi/sdk-types.js +12 -0
  326. package/src/tools/oapi/search/doc-search.d.ts +13 -0
  327. package/src/tools/oapi/search/doc-search.js +191 -0
  328. package/src/tools/oapi/search/index.d.ts +12 -0
  329. package/src/tools/oapi/search/index.js +33 -0
  330. package/src/tools/oapi/sheets/index.d.ts +12 -0
  331. package/src/tools/oapi/sheets/index.js +31 -0
  332. package/src/tools/oapi/sheets/sheet.d.ts +16 -0
  333. package/src/tools/oapi/sheets/sheet.js +652 -0
  334. package/src/tools/oapi/task/comment.d.ts +15 -0
  335. package/src/tools/oapi/task/comment.js +140 -0
  336. package/src/tools/oapi/task/index.d.ts +8 -0
  337. package/src/tools/oapi/task/index.js +8 -0
  338. package/src/tools/oapi/task/subtask.d.ts +14 -0
  339. package/src/tools/oapi/task/subtask.js +162 -0
  340. package/src/tools/oapi/task/task.d.ts +16 -0
  341. package/src/tools/oapi/task/task.js +344 -0
  342. package/src/tools/oapi/task/tasklist.d.ts +21 -0
  343. package/src/tools/oapi/task/tasklist.js +321 -0
  344. package/src/tools/oapi/wiki/index.d.ts +12 -0
  345. package/src/tools/oapi/wiki/index.js +34 -0
  346. package/src/tools/oapi/wiki/space-node.d.ts +17 -0
  347. package/src/tools/oapi/wiki/space-node.js +230 -0
  348. package/src/tools/oapi/wiki/space.d.ts +15 -0
  349. package/src/tools/oapi/wiki/space.js +130 -0
  350. package/src/tools/oauth-batch-auth.d.ts +11 -0
  351. package/src/tools/oauth-batch-auth.js +142 -0
  352. package/src/tools/oauth-cards.d.ts +39 -0
  353. package/src/tools/oauth-cards.js +315 -0
  354. package/src/tools/oauth.d.ts +47 -0
  355. package/src/tools/oauth.js +620 -0
  356. package/src/tools/onboarding-auth.d.ts +27 -0
  357. package/src/tools/onboarding-auth.js +130 -0
  358. package/src/tools/tat/im/index.d.ts +15 -0
  359. package/src/tools/tat/im/index.js +18 -0
  360. package/src/tools/tat/im/resource.d.ts +15 -0
  361. package/src/tools/tat/im/resource.js +157 -0
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * feishu_calendar_freebusy tool -- Query user/room calendar free/busy status.
6
+ *
7
+ * P0 Actions: list
8
+ *
9
+ * Uses the Feishu Calendar API:
10
+ * - list: POST /open-apis/calendar/v4/freebusy/batch (批量查询接口)
11
+ */
12
+ import type { OpenClawPluginApi } from 'openclaw/plugin-sdk';
13
+ export declare function registerFeishuCalendarFreebusyTool(api: OpenClawPluginApi): void;
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * feishu_calendar_freebusy tool -- Query user/room calendar free/busy status.
6
+ *
7
+ * P0 Actions: list
8
+ *
9
+ * Uses the Feishu Calendar API:
10
+ * - list: POST /open-apis/calendar/v4/freebusy/batch (批量查询接口)
11
+ */
12
+ import { Type } from '@sinclair/typebox';
13
+ import { json, createToolContext, parseTimeToRFC3339, assertLarkOk, handleInvokeErrorWithAutoAuth, registerTool } from '../helpers';
14
+ // ---------------------------------------------------------------------------
15
+ // Schema
16
+ // ---------------------------------------------------------------------------
17
+ const FeishuCalendarFreebusySchema = Type.Object({
18
+ action: Type.Literal('list'),
19
+ time_min: Type.String({
20
+ description: "查询起始时间(ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00')",
21
+ }),
22
+ time_max: Type.String({
23
+ description: "查询结束时间(ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00')",
24
+ }),
25
+ user_ids: Type.Array(Type.String({
26
+ description: '用户 open_id',
27
+ }), {
28
+ description: '要查询忙闲的用户 ID 列表(1-10 个用户)',
29
+ minItems: 1,
30
+ maxItems: 10,
31
+ }),
32
+ });
33
+ // ---------------------------------------------------------------------------
34
+ // Registration
35
+ // ---------------------------------------------------------------------------
36
+ export function registerFeishuCalendarFreebusyTool(api) {
37
+ if (!api.config)
38
+ return;
39
+ const cfg = api.config;
40
+ const { toolClient, log } = createToolContext(api, 'feishu_calendar_freebusy');
41
+ registerTool(api, {
42
+ name: 'feishu_calendar_freebusy',
43
+ label: 'Feishu Calendar Free/Busy Status',
44
+ description: '【以用户身份】飞书日历忙闲查询工具。当用户要求查询某时间段内某人是否空闲、查看忙闲状态时使用。支持批量查询 1-10 个用户的主日历忙闲信息,用于安排会议时间。',
45
+ parameters: FeishuCalendarFreebusySchema,
46
+ async execute(_toolCallId, params) {
47
+ const p = params;
48
+ log.info(`[FREEBUSY] Execute called with params: ${JSON.stringify(p)}`);
49
+ try {
50
+ const client = toolClient();
51
+ if (p.action !== 'list') {
52
+ log.warn(`[FREEBUSY] Unknown action: ${p.action}`);
53
+ return json({ error: `Unknown action: ${p.action}` });
54
+ }
55
+ // Validate user_ids (batch API requires 1-10 users)
56
+ if (!p.user_ids || p.user_ids.length === 0) {
57
+ log.warn(`[FREEBUSY] user_ids is empty`);
58
+ return json({
59
+ error: 'user_ids is required (1-10 user IDs)',
60
+ });
61
+ }
62
+ if (p.user_ids.length > 10) {
63
+ log.warn(`[FREEBUSY] user_ids exceeds limit: ${p.user_ids.length}`);
64
+ return json({
65
+ error: `user_ids count exceeds limit, maximum 10 users (current: ${p.user_ids.length})`,
66
+ });
67
+ }
68
+ log.info(`[FREEBUSY] Validation passed, user_ids count: ${p.user_ids.length}`);
69
+ // Convert time strings to RFC 3339 format (required by freebusy API)
70
+ const timeMin = parseTimeToRFC3339(p.time_min);
71
+ const timeMax = parseTimeToRFC3339(p.time_max);
72
+ if (!timeMin || !timeMax) {
73
+ log.warn(`[FREEBUSY] Time format error: time_min=${p.time_min}, time_max=${p.time_max}`);
74
+ return json({
75
+ error: "Invalid time format. Must use ISO 8601 / RFC 3339 with timezone, e.g. '2024-01-01T00:00:00+08:00' or '2026-02-25 14:00:00'.",
76
+ received_time_min: p.time_min,
77
+ received_time_max: p.time_max,
78
+ });
79
+ }
80
+ log.info(`[FREEBUSY] Calling batch API: time_min=${p.time_min} -> ${timeMin}, time_max=${p.time_max} -> ${timeMax}, user_ids=${p.user_ids.length}`);
81
+ const res = await client.invoke('feishu_calendar_freebusy.list', (sdk, opts) => sdk.calendar.freebusy.batch({
82
+ data: {
83
+ time_min: timeMin,
84
+ time_max: timeMax,
85
+ user_ids: p.user_ids,
86
+ include_external_calendar: true,
87
+ only_busy: true,
88
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
+ }, // SDK 类型定义可能未包含所有字段
90
+ }, opts), { as: 'user' });
91
+ assertLarkOk(res);
92
+ const data = res.data;
93
+ const freebusyLists = data?.freebusy_lists ?? [];
94
+ log.info(`[FREEBUSY] Success: returned ${freebusyLists.length} user(s) freebusy data`);
95
+ return json({
96
+ freebusy_lists: freebusyLists,
97
+ _debug: {
98
+ time_min_input: p.time_min,
99
+ time_min_rfc3339: timeMin,
100
+ time_max_input: p.time_max,
101
+ time_max_rfc3339: timeMax,
102
+ user_count: p.user_ids.length,
103
+ },
104
+ });
105
+ }
106
+ catch (err) {
107
+ return await handleInvokeErrorWithAutoAuth(err, cfg);
108
+ }
109
+ },
110
+ }, { name: 'feishu_calendar_freebusy' });
111
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+ export { registerFeishuCalendarCalendarTool } from './calendar';
6
+ export { registerFeishuCalendarEventTool } from './event';
7
+ export { registerFeishuCalendarEventAttendeeTool } from './event-attendee';
8
+ export { registerFeishuCalendarFreebusyTool } from './freebusy';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+ export { registerFeishuCalendarCalendarTool } from './calendar';
6
+ export { registerFeishuCalendarEventTool } from './event';
7
+ export { registerFeishuCalendarEventAttendeeTool } from './event-attendee';
8
+ export { registerFeishuCalendarFreebusyTool } from './freebusy';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * feishu_chat tool -- 管理飞书群聊
6
+ *
7
+ * Actions:
8
+ * - search: 搜索对用户或机器人可见的群列表
9
+ * - get: 获取指定群的详细信息
10
+ *
11
+ * Uses the Feishu IM v1 API:
12
+ * - search: GET /open-apis/im/v1/chats/search
13
+ * - get: GET /open-apis/im/v1/chats/:chat_id
14
+ */
15
+ import type { OpenClawPluginApi } from 'openclaw/plugin-sdk';
16
+ export declare function registerChatSearchTool(api: OpenClawPluginApi): void;
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * feishu_chat tool -- 管理飞书群聊
6
+ *
7
+ * Actions:
8
+ * - search: 搜索对用户或机器人可见的群列表
9
+ * - get: 获取指定群的详细信息
10
+ *
11
+ * Uses the Feishu IM v1 API:
12
+ * - search: GET /open-apis/im/v1/chats/search
13
+ * - get: GET /open-apis/im/v1/chats/:chat_id
14
+ */
15
+ import { Type } from '@sinclair/typebox';
16
+ import { json, createToolContext, assertLarkOk, handleInvokeErrorWithAutoAuth, registerTool, StringEnum } from '../helpers';
17
+ // ---------------------------------------------------------------------------
18
+ // Schema
19
+ // ---------------------------------------------------------------------------
20
+ const FeishuChatSchema = Type.Union([
21
+ // SEARCH
22
+ Type.Object({
23
+ action: Type.Literal('search'),
24
+ query: Type.String({
25
+ description: '搜索关键词(必填)。支持匹配群名称、群成员名称。' + '支持多语种、拼音、前缀等模糊搜索。',
26
+ }),
27
+ page_size: Type.Optional(Type.Integer({
28
+ description: '分页大小(默认20)',
29
+ minimum: 1,
30
+ })),
31
+ page_token: Type.Optional(Type.String({
32
+ description: '分页标记。首次请求无需填写',
33
+ })),
34
+ user_id_type: Type.Optional(StringEnum(['open_id', 'union_id', 'user_id'], {
35
+ description: '用户 ID 类型(默认 open_id)',
36
+ })),
37
+ }),
38
+ // GET
39
+ Type.Object({
40
+ action: Type.Literal('get'),
41
+ chat_id: Type.String({
42
+ description: '群 ID(格式如 oc_xxx)',
43
+ }),
44
+ user_id_type: Type.Optional(StringEnum(['open_id', 'union_id', 'user_id'], {
45
+ description: '用户 ID 类型(默认 open_id)',
46
+ })),
47
+ }),
48
+ ]);
49
+ // ---------------------------------------------------------------------------
50
+ // Registration
51
+ // ---------------------------------------------------------------------------
52
+ export function registerChatSearchTool(api) {
53
+ if (!api.config)
54
+ return;
55
+ const cfg = api.config;
56
+ const { toolClient, log } = createToolContext(api, 'feishu_chat');
57
+ registerTool(api, {
58
+ name: 'feishu_chat',
59
+ label: 'Feishu: Chat Management',
60
+ description: '以用户身份调用飞书群聊管理工具。Actions: search(搜索群列表,支持关键词匹配群名称、群成员), get(获取指定群的详细信息,包括群名称、描述、头像、群主、权限配置等)。',
61
+ parameters: FeishuChatSchema,
62
+ async execute(_toolCallId, params) {
63
+ const p = params;
64
+ try {
65
+ const client = toolClient();
66
+ switch (p.action) {
67
+ // -----------------------------------------------------------------
68
+ // SEARCH
69
+ // -----------------------------------------------------------------
70
+ case 'search': {
71
+ log.info(`search: query="${p.query}", page_size=${p.page_size ?? 20}`);
72
+ const res = await client.invoke('feishu_chat.search', (sdk, opts) => sdk.im.v1.chat.search({
73
+ params: {
74
+ user_id_type: p.user_id_type || 'open_id',
75
+ query: p.query,
76
+ page_size: p.page_size,
77
+ page_token: p.page_token,
78
+ },
79
+ }, opts), { as: 'user' });
80
+ assertLarkOk(res);
81
+ const data = res.data;
82
+ const chatCount = data?.items?.length ?? 0;
83
+ log.info(`search: found ${chatCount} chats`);
84
+ return json({
85
+ items: data?.items,
86
+ has_more: data?.has_more ?? false,
87
+ page_token: data?.page_token,
88
+ });
89
+ }
90
+ // -----------------------------------------------------------------
91
+ // GET
92
+ // -----------------------------------------------------------------
93
+ case 'get': {
94
+ log.info(`get: chat_id=${p.chat_id}, user_id_type=${p.user_id_type ?? 'open_id'}`);
95
+ const res = await client.invoke('feishu_chat.get', (sdk, opts) => sdk.im.v1.chat.get({
96
+ path: {
97
+ chat_id: p.chat_id,
98
+ },
99
+ params: {
100
+ user_id_type: p.user_id_type || 'open_id',
101
+ },
102
+ }, {
103
+ ...(opts ?? {}),
104
+ headers: {
105
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
106
+ ...(opts?.headers ?? {}),
107
+ 'X-Chat-Custom-Header': 'enable_chat_list_security_check',
108
+ },
109
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
+ }), { as: 'user' });
111
+ assertLarkOk(res);
112
+ log.info(`get: retrieved chat info for ${p.chat_id}`);
113
+ return json({
114
+ chat: res.data,
115
+ });
116
+ }
117
+ }
118
+ }
119
+ catch (err) {
120
+ return await handleInvokeErrorWithAutoAuth(err, cfg);
121
+ }
122
+ },
123
+ }, { name: 'feishu_chat' });
124
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Chat Tools Index
6
+ *
7
+ * 群组相关工具
8
+ */
9
+ import type { OpenClawPluginApi } from 'openclaw/plugin-sdk';
10
+ export declare function registerFeishuChatTools(api: OpenClawPluginApi): void;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Chat Tools Index
6
+ *
7
+ * 群组相关工具
8
+ */
9
+ import { registerChatSearchTool } from './chat';
10
+ import { registerChatMembersTool } from './members';
11
+ export function registerFeishuChatTools(api) {
12
+ registerChatSearchTool(api);
13
+ registerChatMembersTool(api);
14
+ api.logger.info?.('feishu_chat: Registered feishu_chat, feishu_chat_members');
15
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * feishu_chat_members tool -- 获取群成员列表
6
+ *
7
+ * 获取指定群组的成员信息,包括成员名字与 ID
8
+ * 使用 sdk.im.v1.chatMembers.get 接口
9
+ */
10
+ import type { OpenClawPluginApi } from 'openclaw/plugin-sdk';
11
+ export declare function registerChatMembersTool(api: OpenClawPluginApi): void;
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * feishu_chat_members tool -- 获取群成员列表
6
+ *
7
+ * 获取指定群组的成员信息,包括成员名字与 ID
8
+ * 使用 sdk.im.v1.chatMembers.get 接口
9
+ */
10
+ import { Type } from '@sinclair/typebox';
11
+ import { json, createToolContext, assertLarkOk, handleInvokeErrorWithAutoAuth, registerTool, StringEnum } from '../helpers';
12
+ // ---------------------------------------------------------------------------
13
+ // Schema
14
+ // ---------------------------------------------------------------------------
15
+ const ChatMembersSchema = Type.Object({
16
+ chat_id: Type.String({
17
+ description: '群 ID(格式如 oc_xxx)。' + '可以通过 feishu_chat_search 工具搜索获取',
18
+ }),
19
+ member_id_type: Type.Optional(StringEnum(['open_id', 'union_id', 'user_id'])),
20
+ page_size: Type.Optional(Type.Integer({
21
+ description: '分页大小(默认20)',
22
+ minimum: 1,
23
+ })),
24
+ page_token: Type.Optional(Type.String({
25
+ description: '分页标记。首次请求无需填写',
26
+ })),
27
+ });
28
+ // ---------------------------------------------------------------------------
29
+ // Registration
30
+ // ---------------------------------------------------------------------------
31
+ export function registerChatMembersTool(api) {
32
+ if (!api.config)
33
+ return;
34
+ const cfg = api.config;
35
+ const { toolClient, log } = createToolContext(api, 'feishu_chat_members');
36
+ registerTool(api, {
37
+ name: 'feishu_chat_members',
38
+ label: 'Feishu: Get Chat Members',
39
+ description: '以用户的身份获取指定群组的成员列表。' +
40
+ '返回成员信息,包含成员 ID、姓名等。' +
41
+ '注意:不会返回群组内的机器人成员。',
42
+ parameters: ChatMembersSchema,
43
+ async execute(_toolCallId, params) {
44
+ const p = params;
45
+ try {
46
+ const client = toolClient();
47
+ log.info(`chat_members: chat_id="${p.chat_id}", page_size=${p.page_size ?? 20}`);
48
+ const res = await client.invoke('feishu_chat_members.default', (sdk, opts) => sdk.im.v1.chatMembers.get({
49
+ path: { chat_id: p.chat_id },
50
+ params: {
51
+ member_id_type: p.member_id_type || 'open_id',
52
+ page_size: p.page_size,
53
+ page_token: p.page_token,
54
+ },
55
+ }, {
56
+ ...(opts ?? {}),
57
+ headers: {
58
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
+ ...(opts?.headers ?? {}),
60
+ 'X-Chat-Custom-Header': 'enable_chat_list_security_check',
61
+ },
62
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
+ }), { as: 'user' });
64
+ assertLarkOk(res);
65
+ const data = res.data;
66
+ const memberCount = data?.items?.length ?? 0;
67
+ const memberTotal = data?.member_total ?? 0;
68
+ log.info(`chat_members: found ${memberCount} members (total: ${memberTotal})`);
69
+ return json({
70
+ items: data?.items,
71
+ has_more: data?.has_more ?? false,
72
+ page_token: data?.page_token,
73
+ member_total: memberTotal,
74
+ });
75
+ }
76
+ catch (err) {
77
+ return await handleInvokeErrorWithAutoAuth(err, cfg);
78
+ }
79
+ },
80
+ }, { name: 'feishu_chat_members' });
81
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * feishu_get_user tool -- 获取用户信息
6
+ *
7
+ * 支持两种模式:
8
+ * 1. 不传 user_id: 获取当前用户自己的信息 (sdk.authen.userInfo.get)
9
+ * 2. 传 user_id: 获取指定用户的信息 (sdk.contact.v3.user.get)
10
+ */
11
+ import type { OpenClawPluginApi } from 'openclaw/plugin-sdk';
12
+ export declare function registerGetUserTool(api: OpenClawPluginApi): void;
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * feishu_get_user tool -- 获取用户信息
6
+ *
7
+ * 支持两种模式:
8
+ * 1. 不传 user_id: 获取当前用户自己的信息 (sdk.authen.userInfo.get)
9
+ * 2. 传 user_id: 获取指定用户的信息 (sdk.contact.v3.user.get)
10
+ */
11
+ import { Type } from '@sinclair/typebox';
12
+ import { json, createToolContext, assertLarkOk, handleInvokeErrorWithAutoAuth, registerTool, StringEnum } from '../helpers';
13
+ // ---------------------------------------------------------------------------
14
+ // Schema
15
+ // ---------------------------------------------------------------------------
16
+ const GetUserSchema = Type.Object({
17
+ user_id: Type.Optional(Type.String({
18
+ description: '用户 ID(格式如 ou_xxx)。若不传入,则获取当前用户自己的信息',
19
+ })),
20
+ user_id_type: Type.Optional(StringEnum(['open_id', 'union_id', 'user_id'])),
21
+ });
22
+ // ---------------------------------------------------------------------------
23
+ // Registration
24
+ // ---------------------------------------------------------------------------
25
+ export function registerGetUserTool(api) {
26
+ if (!api.config)
27
+ return;
28
+ const cfg = api.config;
29
+ const { toolClient, log } = createToolContext(api, 'feishu_get_user');
30
+ registerTool(api, {
31
+ name: 'feishu_get_user',
32
+ label: 'Feishu: Get User Info',
33
+ description: '获取用户信息。不传 user_id 时获取当前用户自己的信息;传 user_id 时获取指定用户的信息。' +
34
+ '返回用户姓名、头像、邮箱、手机号、部门等信息。',
35
+ parameters: GetUserSchema,
36
+ async execute(_toolCallId, params) {
37
+ const p = params;
38
+ try {
39
+ const client = toolClient();
40
+ // 模式 1: 获取当前用户自己的信息
41
+ if (!p.user_id) {
42
+ log.info('get_user: fetching current user info');
43
+ try {
44
+ const res = await client.invoke('feishu_get_user.default', (sdk, opts) => sdk.authen.userInfo.get({}, opts), { as: 'user' });
45
+ assertLarkOk(res);
46
+ log.info('get_user: current user fetched successfully');
47
+ return json({
48
+ user: res.data,
49
+ });
50
+ }
51
+ catch (invokeErr) {
52
+ // 特殊处理错误码 41050:用户组织架构可见范围限制
53
+ if (invokeErr && typeof invokeErr === 'object') {
54
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
+ const e = invokeErr;
56
+ if (e.response?.data?.code === 41050) {
57
+ return json({
58
+ error: '无权限查询该用户信息。\n\n' +
59
+ '说明:使用用户身份调用通讯录 API 时,可操作的权限范围不受应用的通讯录权限范围影响,' +
60
+ '而是受当前用户的组织架构可见范围影响。该范围限制了用户在企业内可见的组织架构数据范围。',
61
+ });
62
+ }
63
+ }
64
+ throw invokeErr;
65
+ }
66
+ }
67
+ // 模式 2: 获取指定用户的信息
68
+ log.info(`get_user: fetching user ${p.user_id}`);
69
+ const userIdType = p.user_id_type || 'open_id';
70
+ try {
71
+ const res = await client.invoke('feishu_get_user.default', (sdk, opts) => sdk.contact.v3.user.get({
72
+ path: { user_id: p.user_id },
73
+ params: {
74
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
+ user_id_type: userIdType,
76
+ },
77
+ }, opts), { as: 'user' });
78
+ assertLarkOk(res);
79
+ log.info(`get_user: user ${p.user_id} fetched successfully`);
80
+ return json({
81
+ user: res.data?.user,
82
+ });
83
+ }
84
+ catch (invokeErr) {
85
+ // 特殊处理错误码 41050:用户组织架构可见范围限制
86
+ if (invokeErr && typeof invokeErr === 'object') {
87
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
88
+ const e = invokeErr;
89
+ if (e.response?.data?.code === 41050) {
90
+ return json({
91
+ error: '无权限查询该用户信息。\n\n' +
92
+ '说明:使用用户身份调用通讯录 API 时,可操作的权限范围不受应用的通讯录权限范围影响,' +
93
+ '而是受当前用户的组织架构可见范围影响。该范围限制了用户在企业内可见的组织架构数据范围。\n\n' +
94
+ '建议:请联系管理员调整当前用户的组织架构可见范围,或使用应用身份(tenant_access_token)调用 API。',
95
+ });
96
+ }
97
+ }
98
+ throw invokeErr;
99
+ }
100
+ }
101
+ catch (err) {
102
+ return await handleInvokeErrorWithAutoAuth(err, cfg);
103
+ }
104
+ },
105
+ }, { name: 'feishu_get_user' });
106
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+ export { registerGetUserTool } from './get-user';
6
+ export { registerSearchUserTool } from './search-user';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+ export { registerGetUserTool } from './get-user';
6
+ export { registerSearchUserTool } from './search-user';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * feishu_search_user tool -- 搜索员工
6
+ *
7
+ * 通过关键词搜索员工,结果按亲密度排序
8
+ * 使用搜索接口(/open-apis/search/v1/user)
9
+ */
10
+ import type { OpenClawPluginApi } from 'openclaw/plugin-sdk';
11
+ export declare function registerSearchUserTool(api: OpenClawPluginApi): void;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * feishu_search_user tool -- 搜索员工
6
+ *
7
+ * 通过关键词搜索员工,结果按亲密度排序
8
+ * 使用搜索接口(/open-apis/search/v1/user)
9
+ */
10
+ import { Type } from '@sinclair/typebox';
11
+ import { json, createToolContext, assertLarkOk, handleInvokeErrorWithAutoAuth, registerTool } from '../helpers';
12
+ // ---------------------------------------------------------------------------
13
+ // Schema
14
+ // ---------------------------------------------------------------------------
15
+ const SearchUserSchema = Type.Object({
16
+ query: Type.String({
17
+ description: '搜索关键词,用于匹配用户名(必填)',
18
+ }),
19
+ page_size: Type.Optional(Type.Integer({
20
+ description: '分页大小,控制每次返回的用户数量(默认20,最大200)',
21
+ minimum: 1,
22
+ maximum: 200,
23
+ })),
24
+ page_token: Type.Optional(Type.String({
25
+ description: '分页标识。首次请求无需填写;当返回结果中包含 page_token 时,可传入该值继续请求下一页',
26
+ })),
27
+ });
28
+ // ---------------------------------------------------------------------------
29
+ // Registration
30
+ // ---------------------------------------------------------------------------
31
+ export function registerSearchUserTool(api) {
32
+ if (!api.config)
33
+ return;
34
+ const cfg = api.config;
35
+ const { toolClient, log } = createToolContext(api, 'feishu_search_user');
36
+ registerTool(api, {
37
+ name: 'feishu_search_user',
38
+ label: 'Feishu: Search User',
39
+ description: '搜索员工信息(通过关键词搜索姓名、手机号、邮箱)。' + '返回匹配的员工列表,包含姓名、部门、open_id 等信息。',
40
+ parameters: SearchUserSchema,
41
+ async execute(_toolCallId, params) {
42
+ const p = params;
43
+ try {
44
+ const client = toolClient();
45
+ log.info(`search_user: query="${p.query}", page_size=${p.page_size ?? 20}`);
46
+ const requestQuery = {
47
+ query: p.query,
48
+ page_size: String(p.page_size ?? 20),
49
+ };
50
+ if (p.page_token)
51
+ requestQuery.page_token = p.page_token;
52
+ const res = await client.invokeByPath('feishu_search_user.default', '/open-apis/search/v1/user', {
53
+ method: 'GET',
54
+ query: requestQuery,
55
+ as: 'user',
56
+ });
57
+ assertLarkOk(res);
58
+ const data = res.data;
59
+ const users = data?.users ?? [];
60
+ const userCount = users.length;
61
+ log.info(`search_user: found ${userCount} users`);
62
+ return json({
63
+ users,
64
+ has_more: data?.has_more ?? false,
65
+ page_token: data?.page_token,
66
+ });
67
+ }
68
+ catch (err) {
69
+ return await handleInvokeErrorWithAutoAuth(err, cfg);
70
+ }
71
+ },
72
+ }, { name: 'feishu_search_user' });
73
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * feishu_doc_comments tool -- 云文档评论管理
6
+ *
7
+ * 支持获取、创建、解决/恢复云文档评论
8
+ * 使用以下 SDK 接口:
9
+ * - sdk.drive.v1.fileComment.list - 获取评论列表
10
+ * - sdk.drive.v1.fileComment.create - 创建全文评论
11
+ * - sdk.drive.v1.fileComment.patch - 解决/恢复评论
12
+ * - sdk.drive.v1.fileCommentReply.list - 获取回复列表
13
+ */
14
+ import type { OpenClawPluginApi } from 'openclaw/plugin-sdk';
15
+ export declare function registerDocCommentsTool(api: OpenClawPluginApi): void;