ForcomeBot 2.2.3__tar.gz → 2.2.4__tar.gz

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 (454) hide show
  1. {forcomebot-2.2.3 → forcomebot-2.2.4}/PKG-INFO +1 -1
  2. {forcomebot-2.2.3 → forcomebot-2.2.4}/config.example.yaml +13 -0
  3. {forcomebot-2.2.3 → forcomebot-2.2.4}/pyproject.toml +1 -1
  4. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/api/routes.py +77 -0
  5. forcomebot-2.2.4/src/auth/__init__.py +33 -0
  6. forcomebot-2.2.4/src/auth/database.py +87 -0
  7. forcomebot-2.2.4/src/auth/dingtalk.py +373 -0
  8. forcomebot-2.2.4/src/auth/jwt_handler.py +129 -0
  9. forcomebot-2.2.4/src/auth/middleware.py +260 -0
  10. forcomebot-2.2.4/src/auth/models.py +107 -0
  11. forcomebot-2.2.4/src/auth/routes.py +385 -0
  12. forcomebot-2.2.4/src/clients/qianxun.py +388 -0
  13. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/core/config_manager.py +145 -41
  14. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/core/state_store.py +82 -222
  15. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/handlers/message_handler.py +106 -29
  16. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/handlers/scheduler.py +338 -4
  17. forcomebot-2.2.4/web/node_modules/@babel/runtime/README.md +19 -0
  18. forcomebot-2.2.4/web/node_modules/@babel/types/LICENSE +22 -0
  19. forcomebot-2.2.4/web/node_modules/@popperjs/core/README.md +376 -0
  20. forcomebot-2.2.4/web/node_modules/@restart/hooks/LICENSE +21 -0
  21. forcomebot-2.2.4/web/node_modules/@restart/hooks/README.md +20 -0
  22. forcomebot-2.2.4/web/node_modules/@types/date-arithmetic/README.md +15 -0
  23. forcomebot-2.2.4/web/node_modules/@types/prop-types/README.md +15 -0
  24. forcomebot-2.2.4/web/node_modules/@types/react/LICENSE +21 -0
  25. forcomebot-2.2.4/web/node_modules/@types/react-big-calendar/LICENSE +21 -0
  26. forcomebot-2.2.4/web/node_modules/@types/react-big-calendar/README.md +15 -0
  27. forcomebot-2.2.4/web/node_modules/@types/react-dom/LICENSE +21 -0
  28. forcomebot-2.2.4/web/node_modules/@types/warning/LICENSE +21 -0
  29. forcomebot-2.2.4/web/node_modules/@types/warning/README.md +21 -0
  30. forcomebot-2.2.4/web/node_modules/date-arithmetic/README.md +65 -0
  31. forcomebot-2.2.4/web/node_modules/date-fns/README.md +58 -0
  32. forcomebot-2.2.4/web/node_modules/dayjs/LICENSE +21 -0
  33. forcomebot-2.2.4/web/node_modules/dayjs/README.md +202 -0
  34. forcomebot-2.2.4/web/node_modules/dom-helpers/LICENSE +21 -0
  35. forcomebot-2.2.4/web/node_modules/dom-helpers/README.md +70 -0
  36. forcomebot-2.2.4/web/node_modules/globalize/LICENSE +21 -0
  37. forcomebot-2.2.4/web/node_modules/globalize/README.md +865 -0
  38. forcomebot-2.2.4/web/node_modules/invariant/LICENSE +21 -0
  39. forcomebot-2.2.4/web/node_modules/invariant/README.md +37 -0
  40. forcomebot-2.2.4/web/node_modules/lodash/LICENSE +47 -0
  41. forcomebot-2.2.4/web/node_modules/lodash/README.md +39 -0
  42. forcomebot-2.2.4/web/node_modules/lodash-es/README.md +10 -0
  43. forcomebot-2.2.4/web/node_modules/lodash.merge/LICENSE +47 -0
  44. forcomebot-2.2.4/web/node_modules/loose-envify/LICENSE +21 -0
  45. forcomebot-2.2.4/web/node_modules/loose-envify/README.md +45 -0
  46. forcomebot-2.2.4/web/node_modules/luxon/README.md +55 -0
  47. forcomebot-2.2.4/web/node_modules/memoize-one/LICENSE +21 -0
  48. forcomebot-2.2.4/web/node_modules/memoize-one/README.md +630 -0
  49. forcomebot-2.2.4/web/node_modules/moment/LICENSE +22 -0
  50. forcomebot-2.2.4/web/node_modules/moment/README.md +55 -0
  51. forcomebot-2.2.4/web/node_modules/moment-timezone/LICENSE +20 -0
  52. forcomebot-2.2.4/web/node_modules/moment-timezone/README.md +64 -0
  53. forcomebot-2.2.4/web/node_modules/prop-types/LICENSE +21 -0
  54. forcomebot-2.2.4/web/node_modules/prop-types/README.md +302 -0
  55. forcomebot-2.2.4/web/node_modules/react-big-calendar/LICENSE +21 -0
  56. forcomebot-2.2.4/web/node_modules/react-big-calendar/README.md +174 -0
  57. forcomebot-2.2.4/web/node_modules/react-is/LICENSE +21 -0
  58. forcomebot-2.2.4/web/node_modules/react-is/README.md +104 -0
  59. forcomebot-2.2.4/web/node_modules/react-lifecycles-compat/README.md +57 -0
  60. forcomebot-2.2.4/web/node_modules/react-overlays/LICENSE +22 -0
  61. forcomebot-2.2.4/web/node_modules/react-overlays/README.md +30 -0
  62. forcomebot-2.2.4/web/node_modules/uncontrollable/LICENSE +21 -0
  63. forcomebot-2.2.4/web/node_modules/uncontrollable/README.md +146 -0
  64. forcomebot-2.2.4/web/node_modules/warning/README.md +69 -0
  65. forcomebot-2.2.3/src/clients/qianxun.py +0 -678
  66. forcomebot-2.2.3/src/web.py +0 -257
  67. {forcomebot-2.2.3 → forcomebot-2.2.4}/.gitignore +0 -0
  68. {forcomebot-2.2.3 → forcomebot-2.2.4}/README.md +0 -0
  69. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/__init__.py +0 -0
  70. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/__main__.py +0 -0
  71. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/api/__init__.py +0 -0
  72. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/api/websocket.py +0 -0
  73. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/clients/__init__.py +0 -0
  74. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/clients/langbot.py +0 -0
  75. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/core/__init__.py +0 -0
  76. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/core/log_collector.py +0 -0
  77. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/core/message_queue.py +0 -0
  78. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/handlers/__init__.py +0 -0
  79. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/handlers/message_parser.py +0 -0
  80. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/models.py +0 -0
  81. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/static/assets/index-B4i68B5_.js +0 -0
  82. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/static/assets/index-BPXisDkw.css +0 -0
  83. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/static/index.html +0 -0
  84. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/static/vite.svg +0 -0
  85. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/utils/__init__.py +0 -0
  86. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/utils/text_processor.py +0 -0
  87. {forcomebot-2.2.3 → forcomebot-2.2.4}/src/utils/xml_parser.py +0 -0
  88. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/README.md +0 -0
  89. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/code-frame/LICENSE +0 -0
  90. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/code-frame/README.md +0 -0
  91. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/compat-data/LICENSE +0 -0
  92. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/compat-data/README.md +0 -0
  93. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/core/LICENSE +0 -0
  94. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/core/README.md +0 -0
  95. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/generator/LICENSE +0 -0
  96. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/generator/README.md +0 -0
  97. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-compilation-targets/LICENSE +0 -0
  98. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-compilation-targets/README.md +0 -0
  99. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-globals/LICENSE +0 -0
  100. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-globals/README.md +0 -0
  101. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-module-imports/LICENSE +0 -0
  102. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-module-imports/README.md +0 -0
  103. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-module-transforms/LICENSE +0 -0
  104. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-module-transforms/README.md +0 -0
  105. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-plugin-utils/LICENSE +0 -0
  106. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-plugin-utils/README.md +0 -0
  107. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-string-parser/LICENSE +0 -0
  108. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-string-parser/README.md +0 -0
  109. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-validator-identifier/LICENSE +0 -0
  110. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-validator-identifier/README.md +0 -0
  111. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-validator-option/LICENSE +0 -0
  112. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helper-validator-option/README.md +0 -0
  113. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helpers/LICENSE +0 -0
  114. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/helpers/README.md +0 -0
  115. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/parser/LICENSE +0 -0
  116. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/parser/README.md +0 -0
  117. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/plugin-transform-react-jsx-self/LICENSE +0 -0
  118. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/plugin-transform-react-jsx-self/README.md +0 -0
  119. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/plugin-transform-react-jsx-source/LICENSE +0 -0
  120. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/plugin-transform-react-jsx-source/README.md +0 -0
  121. {forcomebot-2.2.3/web/node_modules/@babel/template → forcomebot-2.2.4/web/node_modules/@babel/runtime}/LICENSE +0 -0
  122. {forcomebot-2.2.3/web/node_modules/@babel/traverse → forcomebot-2.2.4/web/node_modules/@babel/template}/LICENSE +0 -0
  123. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/template/README.md +0 -0
  124. {forcomebot-2.2.3/web/node_modules/@babel/types → forcomebot-2.2.4/web/node_modules/@babel/traverse}/LICENSE +0 -0
  125. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/traverse/README.md +0 -0
  126. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@babel/types/README.md +0 -0
  127. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@emnapi/core/LICENSE +0 -0
  128. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@emnapi/core/README.md +0 -0
  129. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@emnapi/runtime/LICENSE +0 -0
  130. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@emnapi/runtime/README.md +0 -0
  131. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@emnapi/wasi-threads/LICENSE +0 -0
  132. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@emnapi/wasi-threads/README.md +0 -0
  133. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/config-array/LICENSE +0 -0
  134. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/config-array/README.md +0 -0
  135. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/config-helpers/LICENSE +0 -0
  136. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/config-helpers/README.md +0 -0
  137. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/core/LICENSE +0 -0
  138. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/core/README.md +0 -0
  139. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/eslintrc/LICENSE +0 -0
  140. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/eslintrc/README.md +0 -0
  141. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/js/LICENSE +0 -0
  142. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/js/README.md +0 -0
  143. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/object-schema/LICENSE +0 -0
  144. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/object-schema/README.md +0 -0
  145. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/plugin-kit/LICENSE +0 -0
  146. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint/plugin-kit/README.md +0 -0
  147. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint-community/eslint-utils/LICENSE +0 -0
  148. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint-community/eslint-utils/README.md +0 -0
  149. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys/LICENSE +0 -0
  150. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys/README.md +0 -0
  151. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint-community/regexpp/LICENSE +0 -0
  152. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@eslint-community/regexpp/README.md +0 -0
  153. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@humanfs/core/LICENSE +0 -0
  154. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@humanfs/core/README.md +0 -0
  155. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@humanfs/node/LICENSE +0 -0
  156. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@humanfs/node/README.md +0 -0
  157. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@humanwhocodes/module-importer/LICENSE +0 -0
  158. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@humanwhocodes/module-importer/README.md +0 -0
  159. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@humanwhocodes/retry/LICENSE +0 -0
  160. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@humanwhocodes/retry/README.md +0 -0
  161. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@jridgewell/gen-mapping/LICENSE +0 -0
  162. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@jridgewell/gen-mapping/README.md +0 -0
  163. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@jridgewell/remapping/LICENSE +0 -0
  164. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@jridgewell/remapping/README.md +0 -0
  165. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@jridgewell/resolve-uri/LICENSE +0 -0
  166. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@jridgewell/resolve-uri/README.md +0 -0
  167. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@jridgewell/sourcemap-codec/LICENSE +0 -0
  168. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@jridgewell/sourcemap-codec/README.md +0 -0
  169. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@jridgewell/trace-mapping/LICENSE +0 -0
  170. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@jridgewell/trace-mapping/README.md +0 -0
  171. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@oxc-project/runtime/LICENSE +0 -0
  172. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@oxc-project/runtime/README.md +0 -0
  173. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@oxc-project/types/LICENSE +0 -0
  174. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@oxc-project/types/README.md +0 -0
  175. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@rolldown/binding-win32-x64-msvc/README.md +0 -0
  176. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@rolldown/pluginutils/LICENSE +0 -0
  177. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@rolldown/pluginutils/README.md +0 -0
  178. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@tailwindcss/node/LICENSE +0 -0
  179. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@tailwindcss/node/README.md +0 -0
  180. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@tailwindcss/oxide/LICENSE +0 -0
  181. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@tailwindcss/oxide-win32-x64-msvc/LICENSE +0 -0
  182. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@tailwindcss/oxide-win32-x64-msvc/README.md +0 -0
  183. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@tailwindcss/vite/LICENSE +0 -0
  184. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@tailwindcss/vite/README.md +0 -0
  185. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@tanstack/query-core/LICENSE +0 -0
  186. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@tanstack/react-query/LICENSE +0 -0
  187. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@tanstack/react-query/README.md +0 -0
  188. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@tybys/wasm-util/README.md +0 -0
  189. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/babel__core/LICENSE +0 -0
  190. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/babel__core/README.md +0 -0
  191. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/babel__generator/LICENSE +0 -0
  192. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/babel__generator/README.md +0 -0
  193. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/babel__template/LICENSE +0 -0
  194. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/babel__template/README.md +0 -0
  195. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/babel__traverse/LICENSE +0 -0
  196. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/babel__traverse/README.md +0 -0
  197. {forcomebot-2.2.3/web/node_modules/@types/estree → forcomebot-2.2.4/web/node_modules/@types/date-arithmetic}/LICENSE +0 -0
  198. {forcomebot-2.2.3/web/node_modules/@types/json-schema → forcomebot-2.2.4/web/node_modules/@types/estree}/LICENSE +0 -0
  199. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/estree/README.md +0 -0
  200. {forcomebot-2.2.3/web/node_modules/@types/node → forcomebot-2.2.4/web/node_modules/@types/json-schema}/LICENSE +0 -0
  201. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/json-schema/README.md +0 -0
  202. {forcomebot-2.2.3/web/node_modules/@types/react-dom → forcomebot-2.2.4/web/node_modules/@types/node}/LICENSE +0 -0
  203. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/node/README.md +0 -0
  204. {forcomebot-2.2.3/web/node_modules/@types/react → forcomebot-2.2.4/web/node_modules/@types/prop-types}/LICENSE +0 -0
  205. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/react/README.md +0 -0
  206. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@types/react-dom/README.md +0 -0
  207. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/eslint-plugin/LICENSE +0 -0
  208. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/eslint-plugin/README.md +0 -0
  209. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore/README.md +0 -0
  210. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/parser/LICENSE +0 -0
  211. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/parser/README.md +0 -0
  212. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/project-service/LICENSE +0 -0
  213. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/project-service/README.md +0 -0
  214. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/scope-manager/LICENSE +0 -0
  215. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/scope-manager/README.md +0 -0
  216. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/tsconfig-utils/LICENSE +0 -0
  217. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/tsconfig-utils/README.md +0 -0
  218. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/type-utils/LICENSE +0 -0
  219. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/type-utils/README.md +0 -0
  220. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/types/LICENSE +0 -0
  221. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/types/README.md +0 -0
  222. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/typescript-estree/LICENSE +0 -0
  223. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/typescript-estree/README.md +0 -0
  224. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion/LICENSE +0 -0
  225. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion/README.md +0 -0
  226. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch/LICENSE +0 -0
  227. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch/README.md +0 -0
  228. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/typescript-estree/node_modules/semver/LICENSE +0 -0
  229. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/typescript-estree/node_modules/semver/README.md +0 -0
  230. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/utils/LICENSE +0 -0
  231. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/utils/README.md +0 -0
  232. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/visitor-keys/LICENSE +0 -0
  233. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@typescript-eslint/visitor-keys/README.md +0 -0
  234. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@vitejs/plugin-react/LICENSE +0 -0
  235. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/@vitejs/plugin-react/README.md +0 -0
  236. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/acorn/LICENSE +0 -0
  237. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/acorn/README.md +0 -0
  238. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/acorn-jsx/LICENSE +0 -0
  239. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/acorn-jsx/README.md +0 -0
  240. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/ajv/LICENSE +0 -0
  241. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/ajv/README.md +0 -0
  242. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/argparse/LICENSE +0 -0
  243. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/argparse/README.md +0 -0
  244. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/asynckit/LICENSE +0 -0
  245. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/asynckit/README.md +0 -0
  246. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/axios/LICENSE +0 -0
  247. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/axios/README.md +0 -0
  248. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/balanced-match/README.md +0 -0
  249. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/baseline-browser-mapping/README.md +0 -0
  250. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/brace-expansion/LICENSE +0 -0
  251. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/brace-expansion/README.md +0 -0
  252. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/browserslist/LICENSE +0 -0
  253. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/browserslist/README.md +0 -0
  254. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/call-bind-apply-helpers/LICENSE +0 -0
  255. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/call-bind-apply-helpers/README.md +0 -0
  256. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/caniuse-lite/LICENSE +0 -0
  257. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/caniuse-lite/README.md +0 -0
  258. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/color-convert/LICENSE +0 -0
  259. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/color-convert/README.md +0 -0
  260. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/color-name/LICENSE +0 -0
  261. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/color-name/README.md +0 -0
  262. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/concat-map/LICENSE +0 -0
  263. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/convert-source-map/LICENSE +0 -0
  264. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/convert-source-map/README.md +0 -0
  265. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/cookie/LICENSE +0 -0
  266. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/cookie/README.md +0 -0
  267. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/cross-spawn/LICENSE +0 -0
  268. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/cross-spawn/README.md +0 -0
  269. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/csstype/LICENSE +0 -0
  270. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/csstype/README.md +0 -0
  271. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/debug/LICENSE +0 -0
  272. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/debug/README.md +0 -0
  273. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/deep-is/LICENSE +0 -0
  274. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/detect-libc/LICENSE +0 -0
  275. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/detect-libc/README.md +0 -0
  276. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/dunder-proto/LICENSE +0 -0
  277. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/dunder-proto/README.md +0 -0
  278. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/electron-to-chromium/LICENSE +0 -0
  279. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/electron-to-chromium/README.md +0 -0
  280. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/enhanced-resolve/LICENSE +0 -0
  281. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/enhanced-resolve/README.md +0 -0
  282. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/es-define-property/LICENSE +0 -0
  283. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/es-define-property/README.md +0 -0
  284. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/es-errors/LICENSE +0 -0
  285. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/es-errors/README.md +0 -0
  286. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/es-object-atoms/LICENSE +0 -0
  287. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/es-object-atoms/README.md +0 -0
  288. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/es-set-tostringtag/LICENSE +0 -0
  289. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/es-set-tostringtag/README.md +0 -0
  290. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/eslint/LICENSE +0 -0
  291. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/eslint/README.md +0 -0
  292. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/eslint-plugin-react-hooks/LICENSE +0 -0
  293. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/eslint-plugin-react-hooks/README.md +0 -0
  294. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/eslint-plugin-react-refresh/LICENSE +0 -0
  295. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/eslint-plugin-react-refresh/README.md +0 -0
  296. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/eslint-scope/LICENSE +0 -0
  297. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/eslint-scope/README.md +0 -0
  298. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/eslint-visitor-keys/LICENSE +0 -0
  299. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/eslint-visitor-keys/README.md +0 -0
  300. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/espree/LICENSE +0 -0
  301. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/espree/README.md +0 -0
  302. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/esquery/README.md +0 -0
  303. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/esrecurse/README.md +0 -0
  304. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/estraverse/README.md +0 -0
  305. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/esutils/README.md +0 -0
  306. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/fast-deep-equal/LICENSE +0 -0
  307. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/fast-deep-equal/README.md +0 -0
  308. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/fast-json-stable-stringify/LICENSE +0 -0
  309. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/fast-json-stable-stringify/README.md +0 -0
  310. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/fast-levenshtein/README.md +0 -0
  311. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/fdir/LICENSE +0 -0
  312. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/fdir/README.md +0 -0
  313. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/file-entry-cache/LICENSE +0 -0
  314. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/file-entry-cache/README.md +0 -0
  315. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/flat-cache/LICENSE +0 -0
  316. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/flat-cache/README.md +0 -0
  317. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/flatted/LICENSE +0 -0
  318. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/flatted/README.md +0 -0
  319. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/follow-redirects/LICENSE +0 -0
  320. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/follow-redirects/README.md +0 -0
  321. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/form-data/README.md +0 -0
  322. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/function-bind/LICENSE +0 -0
  323. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/function-bind/README.md +0 -0
  324. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/gensync/LICENSE +0 -0
  325. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/gensync/README.md +0 -0
  326. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/get-intrinsic/LICENSE +0 -0
  327. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/get-intrinsic/README.md +0 -0
  328. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/get-proto/LICENSE +0 -0
  329. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/get-proto/README.md +0 -0
  330. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/glob-parent/LICENSE +0 -0
  331. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/glob-parent/README.md +0 -0
  332. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/gopd/LICENSE +0 -0
  333. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/gopd/README.md +0 -0
  334. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/graceful-fs/LICENSE +0 -0
  335. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/graceful-fs/README.md +0 -0
  336. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/has-symbols/LICENSE +0 -0
  337. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/has-symbols/README.md +0 -0
  338. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/has-tostringtag/LICENSE +0 -0
  339. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/has-tostringtag/README.md +0 -0
  340. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/hasown/LICENSE +0 -0
  341. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/hasown/README.md +0 -0
  342. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/hermes-estree/LICENSE +0 -0
  343. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/hermes-estree/README.md +0 -0
  344. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/hermes-parser/LICENSE +0 -0
  345. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/hermes-parser/README.md +0 -0
  346. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/ignore/README.md +0 -0
  347. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/imurmurhash/README.md +0 -0
  348. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/is-extglob/LICENSE +0 -0
  349. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/is-extglob/README.md +0 -0
  350. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/is-glob/LICENSE +0 -0
  351. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/is-glob/README.md +0 -0
  352. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/isexe/LICENSE +0 -0
  353. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/isexe/README.md +0 -0
  354. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/jiti/LICENSE +0 -0
  355. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/jiti/README.md +0 -0
  356. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/js-tokens/LICENSE +0 -0
  357. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/js-tokens/README.md +0 -0
  358. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/js-yaml/LICENSE +0 -0
  359. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/js-yaml/README.md +0 -0
  360. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/jsesc/README.md +0 -0
  361. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/json-buffer/LICENSE +0 -0
  362. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/json-buffer/README.md +0 -0
  363. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/json-schema-traverse/LICENSE +0 -0
  364. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/json-schema-traverse/README.md +0 -0
  365. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/json-stable-stringify-without-jsonify/LICENSE +0 -0
  366. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/json5/README.md +0 -0
  367. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/keyv/README.md +0 -0
  368. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/levn/LICENSE +0 -0
  369. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/levn/README.md +0 -0
  370. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/lightningcss/LICENSE +0 -0
  371. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/lightningcss/README.md +0 -0
  372. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/lightningcss-win32-x64-msvc/LICENSE +0 -0
  373. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/lightningcss-win32-x64-msvc/README.md +0 -0
  374. {forcomebot-2.2.3/web/node_modules/lodash.merge → forcomebot-2.2.4/web/node_modules/lodash-es}/LICENSE +0 -0
  375. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/lodash.merge/README.md +0 -0
  376. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/lru-cache/LICENSE +0 -0
  377. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/lru-cache/README.md +0 -0
  378. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/magic-string/LICENSE +0 -0
  379. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/magic-string/README.md +0 -0
  380. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/math-intrinsics/LICENSE +0 -0
  381. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/math-intrinsics/README.md +0 -0
  382. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/mime-db/LICENSE +0 -0
  383. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/mime-db/README.md +0 -0
  384. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/mime-types/LICENSE +0 -0
  385. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/mime-types/README.md +0 -0
  386. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/minimatch/LICENSE +0 -0
  387. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/minimatch/README.md +0 -0
  388. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/nanoid/LICENSE +0 -0
  389. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/nanoid/README.md +0 -0
  390. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/natural-compare/README.md +0 -0
  391. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/node-releases/LICENSE +0 -0
  392. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/node-releases/README.md +0 -0
  393. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/optionator/LICENSE +0 -0
  394. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/optionator/README.md +0 -0
  395. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/picocolors/LICENSE +0 -0
  396. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/picocolors/README.md +0 -0
  397. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/picomatch/LICENSE +0 -0
  398. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/picomatch/README.md +0 -0
  399. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/postcss/LICENSE +0 -0
  400. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/postcss/README.md +0 -0
  401. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/prelude-ls/LICENSE +0 -0
  402. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/prelude-ls/README.md +0 -0
  403. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/proxy-from-env/LICENSE +0 -0
  404. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/proxy-from-env/README.md +0 -0
  405. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/punycode/README.md +0 -0
  406. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/react/LICENSE +0 -0
  407. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/react/README.md +0 -0
  408. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/react-dom/LICENSE +0 -0
  409. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/react-dom/README.md +0 -0
  410. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/react-refresh/LICENSE +0 -0
  411. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/react-refresh/README.md +0 -0
  412. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/react-router/README.md +0 -0
  413. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/react-router-dom/README.md +0 -0
  414. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/rolldown/LICENSE +0 -0
  415. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/rolldown/node_modules/@rolldown/pluginutils/LICENSE +0 -0
  416. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/rolldown/node_modules/@rolldown/pluginutils/README.md +0 -0
  417. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/scheduler/LICENSE +0 -0
  418. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/scheduler/README.md +0 -0
  419. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/semver/LICENSE +0 -0
  420. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/semver/README.md +0 -0
  421. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/set-cookie-parser/LICENSE +0 -0
  422. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/set-cookie-parser/README.md +0 -0
  423. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/source-map-js/LICENSE +0 -0
  424. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/source-map-js/README.md +0 -0
  425. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/tailwindcss/LICENSE +0 -0
  426. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/tailwindcss/README.md +0 -0
  427. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/tapable/LICENSE +0 -0
  428. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/tapable/README.md +0 -0
  429. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/tinyglobby/LICENSE +0 -0
  430. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/tinyglobby/README.md +0 -0
  431. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/ts-api-utils/README.md +0 -0
  432. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/tslib/README.md +0 -0
  433. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/type-check/LICENSE +0 -0
  434. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/type-check/README.md +0 -0
  435. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/typescript/README.md +0 -0
  436. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/typescript-eslint/LICENSE +0 -0
  437. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/typescript-eslint/README.md +0 -0
  438. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/undici-types/LICENSE +0 -0
  439. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/undici-types/README.md +0 -0
  440. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/update-browserslist-db/LICENSE +0 -0
  441. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/update-browserslist-db/README.md +0 -0
  442. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/uri-js/LICENSE +0 -0
  443. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/uri-js/README.md +0 -0
  444. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/vite/README.md +0 -0
  445. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/which/LICENSE +0 -0
  446. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/which/README.md +0 -0
  447. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/word-wrap/LICENSE +0 -0
  448. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/word-wrap/README.md +0 -0
  449. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/yallist/LICENSE +0 -0
  450. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/yallist/README.md +0 -0
  451. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/zod/LICENSE +0 -0
  452. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/zod/README.md +0 -0
  453. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/zod-validation-error/LICENSE +0 -0
  454. {forcomebot-2.2.3 → forcomebot-2.2.4}/web/node_modules/zod-validation-error/README.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ForcomeBot
3
- Version: 2.2.3
3
+ Version: 2.2.4
4
4
  Summary: FORCOME 康康 - 千寻微信框架Pro与LangBot的中间件
5
5
  Project-URL: Homepage, https://github.com/yourname/ForcomeBot
6
6
  Project-URL: Documentation, https://github.com/yourname/ForcomeBot#readme
@@ -5,6 +5,19 @@ server:
5
5
  host: "0.0.0.0"
6
6
  port: 789
7
7
 
8
+ # 认证配置
9
+ auth:
10
+ enabled: false # 是否启用认证(false时所有API无需登录)
11
+ jwt_secret: "your-jwt-secret-key-change-in-production" # JWT密钥(生产环境请修改)
12
+ jwt_expire_hours: 24 # Token过期时间(小时)
13
+
14
+ # 钉钉配置(启用认证时需要配置)
15
+ dingtalk:
16
+ app_key: "" # 钉钉应用AppKey
17
+ app_secret: "" # 钉钉应用AppSecret
18
+ corp_id: "" # 企业CorpId
19
+ agent_id: "" # 应用AgentId(工作台应用需要)
20
+
8
21
  # 千寻框架配置
9
22
  qianxun:
10
23
  # 千寻框架HTTP API地址
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "ForcomeBot"
7
- version = "2.2.3"
7
+ version = "2.2.4"
8
8
  description = "FORCOME 康康 - 千寻微信框架Pro与LangBot的中间件"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -696,3 +696,80 @@ async def broadcast_applet(data: BroadcastAppletRequest):
696
696
  "message_ids": message_ids,
697
697
  "message": f"已将 {len(data.targets)} 条消息加入发送队列"
698
698
  }
699
+
700
+
701
+ # ============ 节假日API ============
702
+
703
+ # 尝试导入中国节假日库
704
+ try:
705
+ import chinese_calendar
706
+ HAS_CHINESE_CALENDAR = True
707
+ except ImportError:
708
+ HAS_CHINESE_CALENDAR = False
709
+
710
+
711
+ @router.get("/holidays/{year}")
712
+ async def get_holidays(year: int):
713
+ """获取指定年份的中国法定节假日列表
714
+
715
+ Args:
716
+ year: 年份,如 2026
717
+
718
+ Returns:
719
+ {
720
+ "year": 2026,
721
+ "holidays": ["2026-01-01", "2026-01-28", ...], # 节假日列表
722
+ "workdays": ["2026-01-25", ...], # 调休补班日列表
723
+ "available": true # 是否有节假日数据
724
+ }
725
+ """
726
+ if not HAS_CHINESE_CALENDAR:
727
+ return {
728
+ "year": year,
729
+ "holidays": [],
730
+ "workdays": [],
731
+ "available": False,
732
+ "error": "chinese-calendar 库未安装"
733
+ }
734
+
735
+ try:
736
+ from datetime import date, timedelta
737
+
738
+ holidays: List[str] = []
739
+ workdays: List[str] = []
740
+
741
+ # 遍历全年每一天
742
+ start_date = date(year, 1, 1)
743
+ end_date = date(year, 12, 31)
744
+ current = start_date
745
+
746
+ while current <= end_date:
747
+ try:
748
+ is_holiday = chinese_calendar.is_holiday(current)
749
+ is_workday = chinese_calendar.is_workday(current)
750
+ weekday = current.weekday()
751
+
752
+ if is_holiday:
753
+ holidays.append(current.isoformat())
754
+ elif is_workday and weekday >= 5:
755
+ # 周末但是工作日 = 调休补班
756
+ workdays.append(current.isoformat())
757
+ except Exception:
758
+ pass
759
+ current += timedelta(days=1)
760
+
761
+ return {
762
+ "year": year,
763
+ "holidays": holidays,
764
+ "workdays": workdays,
765
+ "available": True
766
+ }
767
+ except Exception as e:
768
+ logger.error(f"获取节假日数据失败: {e}")
769
+ return {
770
+ "year": year,
771
+ "holidays": [],
772
+ "workdays": [],
773
+ "available": False,
774
+ "error": str(e)
775
+ }
@@ -0,0 +1,33 @@
1
+ """认证模块"""
2
+ from .database import Database, get_db, init_database
3
+ from .models import User, OperationLog
4
+ from .jwt_handler import JWTHandler
5
+ from .dingtalk import DingTalkClient, init_dingtalk_client, get_dingtalk_client
6
+ from .middleware import (
7
+ AuthMiddleware,
8
+ get_current_user,
9
+ get_optional_user,
10
+ init_auth,
11
+ is_auth_enabled,
12
+ log_operation
13
+ )
14
+ from .routes import router as auth_router
15
+
16
+ __all__ = [
17
+ "Database",
18
+ "get_db",
19
+ "init_database",
20
+ "User",
21
+ "OperationLog",
22
+ "JWTHandler",
23
+ "DingTalkClient",
24
+ "init_dingtalk_client",
25
+ "get_dingtalk_client",
26
+ "AuthMiddleware",
27
+ "get_current_user",
28
+ "get_optional_user",
29
+ "init_auth",
30
+ "is_auth_enabled",
31
+ "log_operation",
32
+ "auth_router",
33
+ ]
@@ -0,0 +1,87 @@
1
+ """数据库连接管理"""
2
+ import logging
3
+ from pathlib import Path
4
+ from typing import AsyncGenerator
5
+
6
+ from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
7
+ from sqlalchemy.orm import DeclarativeBase
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ class Base(DeclarativeBase):
13
+ """SQLAlchemy 基类"""
14
+ pass
15
+
16
+
17
+ class Database:
18
+ """数据库管理器"""
19
+
20
+ def __init__(self, db_path: str = "data/app.db"):
21
+ self.db_path = db_path
22
+ self.engine = None
23
+ self.session_factory = None
24
+
25
+ async def init(self):
26
+ """初始化数据库连接"""
27
+ # 确保目录存在
28
+ Path(self.db_path).parent.mkdir(parents=True, exist_ok=True)
29
+
30
+ # 创建异步引擎
31
+ self.engine = create_async_engine(
32
+ f"sqlite+aiosqlite:///{self.db_path}",
33
+ echo=False,
34
+ future=True
35
+ )
36
+
37
+ # 创建会话工厂
38
+ self.session_factory = async_sessionmaker(
39
+ self.engine,
40
+ class_=AsyncSession,
41
+ expire_on_commit=False
42
+ )
43
+
44
+ # 创建表
45
+ async with self.engine.begin() as conn:
46
+ from .models import User, OperationLog # 导入模型以注册
47
+ await conn.run_sync(Base.metadata.create_all)
48
+
49
+ logger.info(f"数据库初始化完成: {self.db_path}")
50
+
51
+ async def close(self):
52
+ """关闭数据库连接"""
53
+ if self.engine:
54
+ await self.engine.dispose()
55
+ logger.info("数据库连接已关闭")
56
+
57
+ async def get_session(self) -> AsyncGenerator[AsyncSession, None]:
58
+ """获取数据库会话"""
59
+ if not self.session_factory:
60
+ raise RuntimeError("数据库未初始化")
61
+
62
+ async with self.session_factory() as session:
63
+ try:
64
+ yield session
65
+ await session.commit()
66
+ except Exception:
67
+ await session.rollback()
68
+ raise
69
+
70
+
71
+ # 全局数据库实例
72
+ _database: Database = None
73
+
74
+
75
+ async def init_database(db_path: str = "data/app.db") -> Database:
76
+ """初始化全局数据库实例"""
77
+ global _database
78
+ _database = Database(db_path)
79
+ await _database.init()
80
+ return _database
81
+
82
+
83
+ def get_db() -> Database:
84
+ """获取全局数据库实例"""
85
+ if _database is None:
86
+ raise RuntimeError("数据库未初始化,请先调用 init_database()")
87
+ return _database
@@ -0,0 +1,373 @@
1
+ """钉钉API客户端"""
2
+ import logging
3
+ import time
4
+ from typing import Optional, Dict, Any
5
+
6
+ import httpx
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ class DingTalkClient:
12
+ """钉钉开放平台API客户端"""
13
+
14
+ # API基础地址
15
+ BASE_URL = "https://oapi.dingtalk.com"
16
+ NEW_API_URL = "https://api.dingtalk.com"
17
+
18
+ def __init__(
19
+ self,
20
+ app_key: str,
21
+ app_secret: str,
22
+ corp_id: str = "",
23
+ agent_id: str = ""
24
+ ):
25
+ """
26
+ 初始化钉钉客户端
27
+
28
+ Args:
29
+ app_key: 应用AppKey
30
+ app_secret: 应用AppSecret
31
+ corp_id: 企业CorpId(工作台免登需要)
32
+ agent_id: 应用AgentId(工作台免登需要)
33
+ """
34
+ self.app_key = app_key
35
+ self.app_secret = app_secret
36
+ self.corp_id = corp_id
37
+ self.agent_id = agent_id
38
+
39
+ # Access Token缓存
40
+ self._access_token: Optional[str] = None
41
+ self._token_expire_time: float = 0
42
+
43
+ # HTTP客户端
44
+ self._client = httpx.AsyncClient(timeout=30.0)
45
+
46
+ async def close(self):
47
+ """关闭HTTP客户端"""
48
+ await self._client.aclose()
49
+
50
+ async def get_access_token(self) -> str:
51
+ """
52
+ 获取企业内部应用的Access Token
53
+
54
+ Returns:
55
+ Access Token字符串
56
+ """
57
+ # 检查缓存
58
+ if self._access_token and time.time() < self._token_expire_time - 60:
59
+ return self._access_token
60
+
61
+ # 请求新Token
62
+ url = f"{self.BASE_URL}/gettoken"
63
+ params = {
64
+ "appkey": self.app_key,
65
+ "appsecret": self.app_secret
66
+ }
67
+
68
+ try:
69
+ response = await self._client.get(url, params=params)
70
+ data = response.json()
71
+
72
+ if data.get("errcode") == 0:
73
+ self._access_token = data["access_token"]
74
+ # Token有效期7200秒
75
+ self._token_expire_time = time.time() + data.get("expires_in", 7200)
76
+ logger.info("获取钉钉Access Token成功")
77
+ return self._access_token
78
+ else:
79
+ logger.error(f"获取钉钉Access Token失败: {data}")
80
+ raise Exception(f"获取Access Token失败: {data.get('errmsg')}")
81
+ except Exception as e:
82
+ logger.error(f"请求钉钉API异常: {e}")
83
+ raise
84
+
85
+ async def get_user_info_by_code(self, auth_code: str) -> Dict[str, Any]:
86
+ """
87
+ 通过授权码获取用户信息(新版OAuth2扫码登录)
88
+
89
+ Args:
90
+ auth_code: 授权码
91
+
92
+ Returns:
93
+ 用户信息字典
94
+ """
95
+ try:
96
+ # 1. 通过授权码获取用户access_token(新版OAuth2 API)
97
+ url = f"{self.NEW_API_URL}/v1.0/oauth2/userAccessToken"
98
+ body = {
99
+ "clientId": self.app_key,
100
+ "clientSecret": self.app_secret,
101
+ "code": auth_code,
102
+ "grantType": "authorization_code"
103
+ }
104
+
105
+ response = await self._client.post(url, json=body)
106
+ data = response.json()
107
+
108
+ if "accessToken" not in data:
109
+ logger.error(f"获取用户Token失败: {data}")
110
+ raise Exception(f"获取用户Token失败: {data.get('message', data)}")
111
+
112
+ user_access_token = data["accessToken"]
113
+ logger.info("获取用户access_token成功")
114
+
115
+ # 2. 使用用户access_token获取用户信息
116
+ user_info_url = f"{self.NEW_API_URL}/v1.0/contact/users/me"
117
+ headers = {"x-acs-dingtalk-access-token": user_access_token}
118
+
119
+ user_response = await self._client.get(user_info_url, headers=headers)
120
+ user_data = user_response.json()
121
+
122
+ if "unionId" not in user_data:
123
+ logger.error(f"获取用户信息失败: {user_data}")
124
+ raise Exception(f"获取用户信息失败: {user_data.get('message', user_data)}")
125
+
126
+ unionid = user_data.get("unionId")
127
+ logger.info(f"获取用户信息成功: unionId={unionid}")
128
+
129
+ # 3. 通过unionId获取企业内用户userid
130
+ userid = await self.get_userid_by_unionid(unionid)
131
+
132
+ if userid:
133
+ # 获取企业内用户详细信息
134
+ user_detail = await self.get_user_detail(userid)
135
+ return {
136
+ "userid": userid,
137
+ "unionid": unionid,
138
+ "name": user_detail.get("name", user_data.get("nick", "")),
139
+ "avatar": user_detail.get("avatar", user_data.get("avatarUrl", "")),
140
+ "mobile": user_detail.get("mobile", user_data.get("mobile", "")),
141
+ "email": user_detail.get("email", user_data.get("email", "")),
142
+ "department": self._format_department(user_detail.get("dept_id_list", [])),
143
+ "title": user_detail.get("title", ""),
144
+ }
145
+ else:
146
+ # 非企业内用户,使用OAuth返回的基本信息
147
+ return {
148
+ "userid": user_data.get("openId", unionid),
149
+ "unionid": unionid,
150
+ "name": user_data.get("nick", ""),
151
+ "avatar": user_data.get("avatarUrl", ""),
152
+ "mobile": user_data.get("mobile", ""),
153
+ "email": user_data.get("email", ""),
154
+ "department": "",
155
+ "title": "",
156
+ }
157
+
158
+ except Exception as e:
159
+ logger.error(f"通过授权码获取用户信息异常: {e}")
160
+ raise
161
+
162
+ async def get_user_info_by_code_internal(self, auth_code: str) -> Dict[str, Any]:
163
+ """
164
+ 通过免登授权码获取用户信息(企业内部应用/H5免登)
165
+
166
+ Args:
167
+ auth_code: 免登授权码(通过钉钉JSAPI获取)
168
+
169
+ Returns:
170
+ 用户信息字典
171
+ """
172
+ access_token = await self.get_access_token()
173
+
174
+ # 通过免登授权码获取用户userid
175
+ url = f"{self.BASE_URL}/topapi/v2/user/getuserinfo"
176
+ params = {"access_token": access_token}
177
+ body = {"code": auth_code}
178
+
179
+ try:
180
+ response = await self._client.post(url, params=params, json=body)
181
+ data = response.json()
182
+
183
+ if data.get("errcode") != 0:
184
+ logger.error(f"获取用户信息失败: {data}")
185
+ raise Exception(f"获取用户信息失败: {data.get('errmsg')}")
186
+
187
+ result = data.get("result", {})
188
+ userid = result.get("userid")
189
+ unionid = result.get("unionid")
190
+
191
+ if not userid:
192
+ raise Exception("未获取到用户userid")
193
+
194
+ # 获取用户详细信息
195
+ user_detail = await self.get_user_detail(userid)
196
+
197
+ return {
198
+ "userid": userid,
199
+ "unionid": unionid,
200
+ "name": user_detail.get("name", ""),
201
+ "avatar": user_detail.get("avatar", ""),
202
+ "mobile": user_detail.get("mobile", ""),
203
+ "email": user_detail.get("email", ""),
204
+ "department": self._format_department(user_detail.get("dept_id_list", [])),
205
+ "title": user_detail.get("title", ""),
206
+ }
207
+
208
+ except Exception as e:
209
+ logger.error(f"通过免登授权码获取用户信息异常: {e}")
210
+ raise
211
+
212
+ async def get_user_detail(self, userid: str) -> Dict[str, Any]:
213
+ """
214
+ 获取用户详细信息
215
+
216
+ Args:
217
+ userid: 用户ID
218
+
219
+ Returns:
220
+ 用户详细信息
221
+ """
222
+ access_token = await self.get_access_token()
223
+
224
+ url = f"{self.BASE_URL}/topapi/v2/user/get"
225
+ params = {"access_token": access_token}
226
+ body = {"userid": userid}
227
+
228
+ try:
229
+ response = await self._client.post(url, params=params, json=body)
230
+ data = response.json()
231
+
232
+ if data.get("errcode") != 0:
233
+ logger.error(f"获取用户详情失败: {data}")
234
+ raise Exception(f"获取用户详情失败: {data.get('errmsg')}")
235
+
236
+ return data.get("result", {})
237
+
238
+ except Exception as e:
239
+ logger.error(f"获取用户详情异常: {e}")
240
+ raise
241
+
242
+ async def get_userid_by_unionid(self, unionid: str) -> Optional[str]:
243
+ """
244
+ 通过UnionId获取UserId
245
+
246
+ Args:
247
+ unionid: 用户UnionId
248
+
249
+ Returns:
250
+ 用户UserId
251
+ """
252
+ access_token = await self.get_access_token()
253
+
254
+ url = f"{self.BASE_URL}/topapi/user/getbyunionid"
255
+ params = {"access_token": access_token}
256
+ body = {"unionid": unionid}
257
+
258
+ try:
259
+ response = await self._client.post(url, params=params, json=body)
260
+ data = response.json()
261
+
262
+ if data.get("errcode") != 0:
263
+ logger.warning(f"通过UnionId获取UserId失败: {data}")
264
+ return None
265
+
266
+ return data.get("result", {}).get("userid")
267
+
268
+ except Exception as e:
269
+ logger.error(f"通过UnionId获取UserId异常: {e}")
270
+ return None
271
+
272
+ async def get_jsapi_ticket(self) -> str:
273
+ """
274
+ 获取JSAPI Ticket(H5页面调用钉钉JS API需要)
275
+
276
+ Returns:
277
+ JSAPI Ticket
278
+ """
279
+ access_token = await self.get_access_token()
280
+
281
+ url = f"{self.BASE_URL}/get_jsapi_ticket"
282
+ params = {"access_token": access_token}
283
+
284
+ try:
285
+ response = await self._client.get(url, params=params)
286
+ data = response.json()
287
+
288
+ if data.get("errcode") != 0:
289
+ logger.error(f"获取JSAPI Ticket失败: {data}")
290
+ raise Exception(f"获取JSAPI Ticket失败: {data.get('errmsg')}")
291
+
292
+ return data.get("ticket", "")
293
+
294
+ except Exception as e:
295
+ logger.error(f"获取JSAPI Ticket异常: {e}")
296
+ raise
297
+
298
+ def _format_department(self, dept_ids: list) -> str:
299
+ """格式化部门信息"""
300
+ if not dept_ids:
301
+ return ""
302
+ # 简单返回部门ID列表,实际可以查询部门名称
303
+ return ",".join(str(d) for d in dept_ids)
304
+
305
+ def generate_qrcode_url(self, redirect_uri: str, state: str = "") -> str:
306
+ """
307
+ 生成钉钉扫码登录URL(新版OAuth2)
308
+
309
+ Args:
310
+ redirect_uri: 回调地址
311
+ state: 状态参数
312
+
313
+ Returns:
314
+ 扫码登录URL
315
+ """
316
+ import urllib.parse
317
+
318
+ params = {
319
+ "client_id": self.app_key,
320
+ "response_type": "code",
321
+ "scope": "openid",
322
+ "redirect_uri": redirect_uri,
323
+ "state": state or "dingtalk_login",
324
+ "prompt": "consent"
325
+ }
326
+
327
+ query = urllib.parse.urlencode(params)
328
+ return f"https://login.dingtalk.com/oauth2/auth?{query}"
329
+
330
+ def generate_h5_auth_url(self, redirect_uri: str, state: str = "") -> str:
331
+ """
332
+ 生成H5页面授权URL(用于钉钉内H5应用)
333
+
334
+ Args:
335
+ redirect_uri: 回调地址
336
+ state: 状态参数
337
+
338
+ Returns:
339
+ H5授权URL
340
+ """
341
+ import urllib.parse
342
+
343
+ params = {
344
+ "appid": self.app_key,
345
+ "response_type": "code",
346
+ "scope": "snsapi_auth",
347
+ "redirect_uri": redirect_uri,
348
+ "state": state or "dingtalk_h5"
349
+ }
350
+
351
+ query = urllib.parse.urlencode(params)
352
+ return f"https://login.dingtalk.com/oauth2/auth?{query}"
353
+
354
+
355
+ # 全局客户端实例
356
+ _dingtalk_client: Optional[DingTalkClient] = None
357
+
358
+
359
+ def init_dingtalk_client(
360
+ app_key: str,
361
+ app_secret: str,
362
+ corp_id: str = "",
363
+ agent_id: str = ""
364
+ ) -> DingTalkClient:
365
+ """初始化全局钉钉客户端"""
366
+ global _dingtalk_client
367
+ _dingtalk_client = DingTalkClient(app_key, app_secret, corp_id, agent_id)
368
+ return _dingtalk_client
369
+
370
+
371
+ def get_dingtalk_client() -> Optional[DingTalkClient]:
372
+ """获取全局钉钉客户端"""
373
+ return _dingtalk_client