machinaos 0.0.1 → 0.0.7

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 (422) hide show
  1. package/.env.template +71 -71
  2. package/LICENSE +21 -21
  3. package/README.md +163 -87
  4. package/bin/cli.js +62 -106
  5. package/client/.dockerignore +45 -45
  6. package/client/Dockerfile +68 -68
  7. package/client/dist/assets/index-DFSC53FP.css +1 -0
  8. package/client/dist/assets/index-fJ-1gTf5.js +613 -0
  9. package/client/dist/index.html +14 -0
  10. package/client/eslint.config.js +34 -16
  11. package/client/nginx.conf +66 -66
  12. package/client/package.json +61 -48
  13. package/client/src/App.tsx +27 -27
  14. package/client/src/Dashboard.tsx +1200 -1172
  15. package/client/src/ParameterPanel.tsx +302 -300
  16. package/client/src/components/AIAgentNode.tsx +315 -321
  17. package/client/src/components/APIKeyValidator.tsx +117 -117
  18. package/client/src/components/ClaudeChatModelNode.tsx +17 -17
  19. package/client/src/components/CredentialsModal.tsx +1200 -306
  20. package/client/src/components/GeminiChatModelNode.tsx +17 -17
  21. package/client/src/components/GenericNode.tsx +356 -356
  22. package/client/src/components/LocationParameterPanel.tsx +153 -153
  23. package/client/src/components/ModelNode.tsx +285 -285
  24. package/client/src/components/OpenAIChatModelNode.tsx +17 -17
  25. package/client/src/components/OutputPanel.tsx +470 -470
  26. package/client/src/components/ParameterRenderer.tsx +1873 -1873
  27. package/client/src/components/SkillEditorModal.tsx +3 -3
  28. package/client/src/components/SquareNode.tsx +812 -796
  29. package/client/src/components/ToolkitNode.tsx +365 -365
  30. package/client/src/components/auth/LoginPage.tsx +247 -247
  31. package/client/src/components/auth/ProtectedRoute.tsx +59 -59
  32. package/client/src/components/base/BaseChatModelNode.tsx +270 -270
  33. package/client/src/components/icons/AIProviderIcons.tsx +50 -50
  34. package/client/src/components/maps/GoogleMapsPicker.tsx +136 -136
  35. package/client/src/components/maps/MapsPreviewPanel.tsx +109 -109
  36. package/client/src/components/maps/index.ts +25 -25
  37. package/client/src/components/parameterPanel/InputSection.tsx +1094 -1094
  38. package/client/src/components/parameterPanel/LocationPanelLayout.tsx +64 -64
  39. package/client/src/components/parameterPanel/MapsSection.tsx +91 -91
  40. package/client/src/components/parameterPanel/MiddleSection.tsx +867 -571
  41. package/client/src/components/parameterPanel/OutputSection.tsx +80 -80
  42. package/client/src/components/parameterPanel/ParameterPanelLayout.tsx +81 -81
  43. package/client/src/components/parameterPanel/ToolSchemaEditor.tsx +436 -436
  44. package/client/src/components/parameterPanel/index.ts +41 -41
  45. package/client/src/components/shared/DataPanel.tsx +142 -142
  46. package/client/src/components/shared/JSONTreeRenderer.tsx +105 -105
  47. package/client/src/components/ui/AIResultModal.tsx +203 -203
  48. package/client/src/components/ui/ApiKeyInput.tsx +93 -0
  49. package/client/src/components/ui/CodeEditor.tsx +81 -81
  50. package/client/src/components/ui/CollapsibleSection.tsx +87 -87
  51. package/client/src/components/ui/ComponentItem.tsx +153 -153
  52. package/client/src/components/ui/ComponentPalette.tsx +320 -320
  53. package/client/src/components/ui/ConsolePanel.tsx +151 -43
  54. package/client/src/components/ui/ErrorBoundary.tsx +195 -195
  55. package/client/src/components/ui/InputNodesPanel.tsx +203 -203
  56. package/client/src/components/ui/MapSelector.tsx +313 -313
  57. package/client/src/components/ui/Modal.tsx +151 -148
  58. package/client/src/components/ui/NodeOutputPanel.tsx +1150 -1150
  59. package/client/src/components/ui/OutputDisplayPanel.tsx +381 -381
  60. package/client/src/components/ui/QRCodeDisplay.tsx +182 -0
  61. package/client/src/components/ui/TopToolbar.tsx +736 -736
  62. package/client/src/components/ui/WorkflowSidebar.tsx +293 -293
  63. package/client/src/config/antdTheme.ts +186 -186
  64. package/client/src/contexts/AuthContext.tsx +221 -221
  65. package/client/src/contexts/ThemeContext.tsx +42 -42
  66. package/client/src/contexts/WebSocketContext.tsx +2144 -1971
  67. package/client/src/factories/baseChatModelFactory.ts +255 -255
  68. package/client/src/hooks/useAndroidOperations.ts +118 -164
  69. package/client/src/hooks/useApiKeyValidation.ts +106 -106
  70. package/client/src/hooks/useApiKeys.ts +238 -238
  71. package/client/src/hooks/useAppTheme.ts +17 -17
  72. package/client/src/hooks/useComponentPalette.ts +50 -50
  73. package/client/src/hooks/useDragAndDrop.ts +123 -123
  74. package/client/src/hooks/useDragVariable.ts +88 -88
  75. package/client/src/hooks/useExecution.ts +319 -313
  76. package/client/src/hooks/useParameterPanel.ts +176 -176
  77. package/client/src/hooks/useReactFlowNodes.ts +188 -188
  78. package/client/src/hooks/useToolSchema.ts +209 -209
  79. package/client/src/hooks/useWhatsApp.ts +196 -196
  80. package/client/src/hooks/useWorkflowManagement.ts +45 -45
  81. package/client/src/index.css +314 -314
  82. package/client/src/nodeDefinitions/aiAgentNodes.ts +335 -335
  83. package/client/src/nodeDefinitions/aiModelNodes.ts +340 -340
  84. package/client/src/nodeDefinitions/androidServiceNodes.ts +383 -383
  85. package/client/src/nodeDefinitions/chatNodes.ts +135 -135
  86. package/client/src/nodeDefinitions/codeNodes.ts +54 -54
  87. package/client/src/nodeDefinitions/index.ts +14 -14
  88. package/client/src/nodeDefinitions/locationNodes.ts +462 -462
  89. package/client/src/nodeDefinitions/schedulerNodes.ts +220 -220
  90. package/client/src/nodeDefinitions/skillNodes.ts +17 -5
  91. package/client/src/nodeDefinitions/utilityNodes.ts +284 -284
  92. package/client/src/nodeDefinitions/whatsappNodes.ts +821 -865
  93. package/client/src/nodeDefinitions.ts +101 -103
  94. package/client/src/services/dynamicParameterService.ts +95 -95
  95. package/client/src/services/execution/aiAgentExecutionService.ts +34 -34
  96. package/client/src/services/executionService.ts +227 -231
  97. package/client/src/services/workflowApi.ts +91 -91
  98. package/client/src/store/useAppStore.ts +578 -581
  99. package/client/src/styles/theme.ts +513 -508
  100. package/client/src/styles/zIndex.ts +16 -16
  101. package/client/src/types/ComponentTypes.ts +38 -38
  102. package/client/src/types/INodeProperties.ts +287 -287
  103. package/client/src/types/NodeTypes.ts +27 -27
  104. package/client/src/utils/formatters.ts +32 -32
  105. package/client/src/utils/googleMapsLoader.ts +139 -139
  106. package/client/src/utils/locationUtils.ts +84 -84
  107. package/client/src/utils/nodeUtils.ts +30 -30
  108. package/client/src/utils/workflow.ts +29 -29
  109. package/client/src/vite-env.d.ts +12 -12
  110. package/client/tailwind.config.js +59 -59
  111. package/client/tsconfig.json +25 -25
  112. package/client/vite.config.js +35 -35
  113. package/install.ps1 +308 -0
  114. package/install.sh +343 -0
  115. package/package.json +81 -70
  116. package/scripts/build.js +174 -51
  117. package/scripts/clean.js +40 -40
  118. package/scripts/start.js +234 -210
  119. package/scripts/stop.js +301 -325
  120. package/server/.dockerignore +44 -44
  121. package/server/Dockerfile +45 -45
  122. package/server/constants.py +244 -249
  123. package/server/core/cache.py +460 -460
  124. package/server/core/config.py +127 -127
  125. package/server/core/container.py +98 -98
  126. package/server/core/database.py +1296 -1210
  127. package/server/core/logging.py +313 -313
  128. package/server/main.py +288 -288
  129. package/server/middleware/__init__.py +5 -5
  130. package/server/middleware/auth.py +89 -89
  131. package/server/models/auth.py +52 -52
  132. package/server/models/cache.py +24 -24
  133. package/server/models/database.py +235 -210
  134. package/server/models/nodes.py +435 -455
  135. package/server/pyproject.toml +75 -72
  136. package/server/requirements.txt +83 -83
  137. package/server/routers/android.py +294 -294
  138. package/server/routers/auth.py +203 -203
  139. package/server/routers/database.py +150 -150
  140. package/server/routers/maps.py +141 -141
  141. package/server/routers/nodejs_compat.py +288 -288
  142. package/server/routers/webhook.py +90 -90
  143. package/server/routers/websocket.py +2239 -2127
  144. package/server/routers/whatsapp.py +761 -761
  145. package/server/routers/workflow.py +199 -199
  146. package/server/services/ai.py +2444 -2414
  147. package/server/services/android_service.py +588 -588
  148. package/server/services/auth.py +130 -130
  149. package/server/services/chat_client.py +160 -160
  150. package/server/services/deployment/manager.py +706 -706
  151. package/server/services/event_waiter.py +675 -785
  152. package/server/services/execution/executor.py +1351 -1351
  153. package/server/services/execution/models.py +1 -1
  154. package/server/services/handlers/__init__.py +122 -126
  155. package/server/services/handlers/ai.py +390 -355
  156. package/server/services/handlers/android.py +69 -260
  157. package/server/services/handlers/code.py +278 -278
  158. package/server/services/handlers/http.py +193 -193
  159. package/server/services/handlers/tools.py +146 -32
  160. package/server/services/handlers/triggers.py +107 -107
  161. package/server/services/handlers/utility.py +822 -822
  162. package/server/services/handlers/whatsapp.py +423 -476
  163. package/server/services/maps.py +288 -288
  164. package/server/services/memory_store.py +103 -103
  165. package/server/services/node_executor.py +372 -375
  166. package/server/services/scheduler.py +155 -155
  167. package/server/services/skill_loader.py +1 -1
  168. package/server/services/status_broadcaster.py +834 -826
  169. package/server/services/temporal/__init__.py +23 -23
  170. package/server/services/temporal/activities.py +344 -344
  171. package/server/services/temporal/client.py +76 -76
  172. package/server/services/temporal/executor.py +147 -147
  173. package/server/services/temporal/worker.py +251 -251
  174. package/server/services/temporal/workflow.py +355 -355
  175. package/server/services/temporal/ws_client.py +236 -236
  176. package/server/services/text.py +110 -110
  177. package/server/services/user_auth.py +172 -172
  178. package/server/services/websocket_client.py +29 -29
  179. package/server/services/workflow.py +597 -597
  180. package/server/skills/android-skill/SKILL.md +4 -4
  181. package/server/skills/code-skill/SKILL.md +123 -89
  182. package/server/skills/maps-skill/SKILL.md +3 -3
  183. package/server/skills/memory-skill/SKILL.md +1 -1
  184. package/server/skills/web-search-skill/SKILL.md +154 -0
  185. package/server/skills/whatsapp-skill/SKILL.md +3 -3
  186. package/server/uv.lock +461 -100
  187. package/server/whatsapp-rpc/.dockerignore +30 -30
  188. package/server/whatsapp-rpc/Dockerfile +44 -44
  189. package/server/whatsapp-rpc/Dockerfile.web +17 -17
  190. package/server/whatsapp-rpc/README.md +139 -139
  191. package/server/whatsapp-rpc/bin/whatsapp-rpc-server +0 -0
  192. package/server/whatsapp-rpc/cli.js +95 -95
  193. package/server/whatsapp-rpc/configs/config.yaml +6 -6
  194. package/server/whatsapp-rpc/docker-compose.yml +35 -35
  195. package/server/whatsapp-rpc/docs/API.md +410 -410
  196. package/server/whatsapp-rpc/node_modules/.package-lock.json +259 -0
  197. package/server/whatsapp-rpc/node_modules/chalk/license +9 -0
  198. package/server/whatsapp-rpc/node_modules/chalk/package.json +83 -0
  199. package/server/whatsapp-rpc/node_modules/chalk/readme.md +297 -0
  200. package/server/whatsapp-rpc/node_modules/chalk/source/index.d.ts +325 -0
  201. package/server/whatsapp-rpc/node_modules/chalk/source/index.js +225 -0
  202. package/server/whatsapp-rpc/node_modules/chalk/source/utilities.js +33 -0
  203. package/server/whatsapp-rpc/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
  204. package/server/whatsapp-rpc/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
  205. package/server/whatsapp-rpc/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
  206. package/server/whatsapp-rpc/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
  207. package/server/whatsapp-rpc/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
  208. package/server/whatsapp-rpc/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
  209. package/server/whatsapp-rpc/node_modules/commander/LICENSE +22 -0
  210. package/server/whatsapp-rpc/node_modules/commander/Readme.md +1148 -0
  211. package/server/whatsapp-rpc/node_modules/commander/esm.mjs +16 -0
  212. package/server/whatsapp-rpc/node_modules/commander/index.js +26 -0
  213. package/server/whatsapp-rpc/node_modules/commander/lib/argument.js +145 -0
  214. package/server/whatsapp-rpc/node_modules/commander/lib/command.js +2179 -0
  215. package/server/whatsapp-rpc/node_modules/commander/lib/error.js +43 -0
  216. package/server/whatsapp-rpc/node_modules/commander/lib/help.js +462 -0
  217. package/server/whatsapp-rpc/node_modules/commander/lib/option.js +329 -0
  218. package/server/whatsapp-rpc/node_modules/commander/lib/suggestSimilar.js +100 -0
  219. package/server/whatsapp-rpc/node_modules/commander/package-support.json +16 -0
  220. package/server/whatsapp-rpc/node_modules/commander/package.json +80 -0
  221. package/server/whatsapp-rpc/node_modules/commander/typings/esm.d.mts +3 -0
  222. package/server/whatsapp-rpc/node_modules/commander/typings/index.d.ts +884 -0
  223. package/server/whatsapp-rpc/node_modules/cross-spawn/LICENSE +21 -0
  224. package/server/whatsapp-rpc/node_modules/cross-spawn/README.md +89 -0
  225. package/server/whatsapp-rpc/node_modules/cross-spawn/index.js +39 -0
  226. package/server/whatsapp-rpc/node_modules/cross-spawn/lib/enoent.js +59 -0
  227. package/server/whatsapp-rpc/node_modules/cross-spawn/lib/parse.js +91 -0
  228. package/server/whatsapp-rpc/node_modules/cross-spawn/lib/util/escape.js +47 -0
  229. package/server/whatsapp-rpc/node_modules/cross-spawn/lib/util/readShebang.js +23 -0
  230. package/server/whatsapp-rpc/node_modules/cross-spawn/lib/util/resolveCommand.js +52 -0
  231. package/server/whatsapp-rpc/node_modules/cross-spawn/package.json +73 -0
  232. package/server/whatsapp-rpc/node_modules/execa/index.d.ts +955 -0
  233. package/server/whatsapp-rpc/node_modules/execa/index.js +309 -0
  234. package/server/whatsapp-rpc/node_modules/execa/lib/command.js +119 -0
  235. package/server/whatsapp-rpc/node_modules/execa/lib/error.js +87 -0
  236. package/server/whatsapp-rpc/node_modules/execa/lib/kill.js +102 -0
  237. package/server/whatsapp-rpc/node_modules/execa/lib/pipe.js +42 -0
  238. package/server/whatsapp-rpc/node_modules/execa/lib/promise.js +36 -0
  239. package/server/whatsapp-rpc/node_modules/execa/lib/stdio.js +49 -0
  240. package/server/whatsapp-rpc/node_modules/execa/lib/stream.js +133 -0
  241. package/server/whatsapp-rpc/node_modules/execa/lib/verbose.js +19 -0
  242. package/server/whatsapp-rpc/node_modules/execa/license +9 -0
  243. package/server/whatsapp-rpc/node_modules/execa/package.json +90 -0
  244. package/server/whatsapp-rpc/node_modules/execa/readme.md +822 -0
  245. package/server/whatsapp-rpc/node_modules/get-stream/license +9 -0
  246. package/server/whatsapp-rpc/node_modules/get-stream/package.json +53 -0
  247. package/server/whatsapp-rpc/node_modules/get-stream/readme.md +291 -0
  248. package/server/whatsapp-rpc/node_modules/get-stream/source/array-buffer.js +84 -0
  249. package/server/whatsapp-rpc/node_modules/get-stream/source/array.js +32 -0
  250. package/server/whatsapp-rpc/node_modules/get-stream/source/buffer.js +20 -0
  251. package/server/whatsapp-rpc/node_modules/get-stream/source/contents.js +101 -0
  252. package/server/whatsapp-rpc/node_modules/get-stream/source/index.d.ts +119 -0
  253. package/server/whatsapp-rpc/node_modules/get-stream/source/index.js +5 -0
  254. package/server/whatsapp-rpc/node_modules/get-stream/source/string.js +36 -0
  255. package/server/whatsapp-rpc/node_modules/get-stream/source/utils.js +11 -0
  256. package/server/whatsapp-rpc/node_modules/get-them-args/LICENSE +21 -0
  257. package/server/whatsapp-rpc/node_modules/get-them-args/README.md +95 -0
  258. package/server/whatsapp-rpc/node_modules/get-them-args/index.js +97 -0
  259. package/server/whatsapp-rpc/node_modules/get-them-args/package.json +36 -0
  260. package/server/whatsapp-rpc/node_modules/human-signals/LICENSE +201 -0
  261. package/server/whatsapp-rpc/node_modules/human-signals/README.md +168 -0
  262. package/server/whatsapp-rpc/node_modules/human-signals/build/src/core.js +273 -0
  263. package/server/whatsapp-rpc/node_modules/human-signals/build/src/main.d.ts +73 -0
  264. package/server/whatsapp-rpc/node_modules/human-signals/build/src/main.js +70 -0
  265. package/server/whatsapp-rpc/node_modules/human-signals/build/src/realtime.js +16 -0
  266. package/server/whatsapp-rpc/node_modules/human-signals/build/src/signals.js +34 -0
  267. package/server/whatsapp-rpc/node_modules/human-signals/package.json +61 -0
  268. package/server/whatsapp-rpc/node_modules/is-stream/index.d.ts +81 -0
  269. package/server/whatsapp-rpc/node_modules/is-stream/index.js +29 -0
  270. package/server/whatsapp-rpc/node_modules/is-stream/license +9 -0
  271. package/server/whatsapp-rpc/node_modules/is-stream/package.json +44 -0
  272. package/server/whatsapp-rpc/node_modules/is-stream/readme.md +60 -0
  273. package/server/whatsapp-rpc/node_modules/isexe/LICENSE +15 -0
  274. package/server/whatsapp-rpc/node_modules/isexe/README.md +51 -0
  275. package/server/whatsapp-rpc/node_modules/isexe/index.js +57 -0
  276. package/server/whatsapp-rpc/node_modules/isexe/mode.js +41 -0
  277. package/server/whatsapp-rpc/node_modules/isexe/package.json +31 -0
  278. package/server/whatsapp-rpc/node_modules/isexe/test/basic.js +221 -0
  279. package/server/whatsapp-rpc/node_modules/isexe/windows.js +42 -0
  280. package/server/whatsapp-rpc/node_modules/kill-port/.editorconfig +12 -0
  281. package/server/whatsapp-rpc/node_modules/kill-port/.gitattributes +1 -0
  282. package/server/whatsapp-rpc/node_modules/kill-port/LICENSE +21 -0
  283. package/server/whatsapp-rpc/node_modules/kill-port/README.md +140 -0
  284. package/server/whatsapp-rpc/node_modules/kill-port/cli.js +25 -0
  285. package/server/whatsapp-rpc/node_modules/kill-port/example.js +21 -0
  286. package/server/whatsapp-rpc/node_modules/kill-port/index.js +46 -0
  287. package/server/whatsapp-rpc/node_modules/kill-port/logo.png +0 -0
  288. package/server/whatsapp-rpc/node_modules/kill-port/package.json +41 -0
  289. package/server/whatsapp-rpc/node_modules/kill-port/pnpm-lock.yaml +4606 -0
  290. package/server/whatsapp-rpc/node_modules/kill-port/test.js +16 -0
  291. package/server/whatsapp-rpc/node_modules/merge-stream/LICENSE +21 -0
  292. package/server/whatsapp-rpc/node_modules/merge-stream/README.md +78 -0
  293. package/server/whatsapp-rpc/node_modules/merge-stream/index.js +41 -0
  294. package/server/whatsapp-rpc/node_modules/merge-stream/package.json +19 -0
  295. package/server/whatsapp-rpc/node_modules/mimic-fn/index.d.ts +52 -0
  296. package/server/whatsapp-rpc/node_modules/mimic-fn/index.js +71 -0
  297. package/server/whatsapp-rpc/node_modules/mimic-fn/license +9 -0
  298. package/server/whatsapp-rpc/node_modules/mimic-fn/package.json +45 -0
  299. package/server/whatsapp-rpc/node_modules/mimic-fn/readme.md +90 -0
  300. package/server/whatsapp-rpc/node_modules/npm-run-path/index.d.ts +90 -0
  301. package/server/whatsapp-rpc/node_modules/npm-run-path/index.js +52 -0
  302. package/server/whatsapp-rpc/node_modules/npm-run-path/license +9 -0
  303. package/server/whatsapp-rpc/node_modules/npm-run-path/node_modules/path-key/index.d.ts +31 -0
  304. package/server/whatsapp-rpc/node_modules/npm-run-path/node_modules/path-key/index.js +12 -0
  305. package/server/whatsapp-rpc/node_modules/npm-run-path/node_modules/path-key/license +9 -0
  306. package/server/whatsapp-rpc/node_modules/npm-run-path/node_modules/path-key/package.json +41 -0
  307. package/server/whatsapp-rpc/node_modules/npm-run-path/node_modules/path-key/readme.md +57 -0
  308. package/server/whatsapp-rpc/node_modules/npm-run-path/package.json +49 -0
  309. package/server/whatsapp-rpc/node_modules/npm-run-path/readme.md +104 -0
  310. package/server/whatsapp-rpc/node_modules/onetime/index.d.ts +59 -0
  311. package/server/whatsapp-rpc/node_modules/onetime/index.js +41 -0
  312. package/server/whatsapp-rpc/node_modules/onetime/license +9 -0
  313. package/server/whatsapp-rpc/node_modules/onetime/package.json +45 -0
  314. package/server/whatsapp-rpc/node_modules/onetime/readme.md +94 -0
  315. package/server/whatsapp-rpc/node_modules/path-key/index.d.ts +40 -0
  316. package/server/whatsapp-rpc/node_modules/path-key/index.js +16 -0
  317. package/server/whatsapp-rpc/node_modules/path-key/license +9 -0
  318. package/server/whatsapp-rpc/node_modules/path-key/package.json +39 -0
  319. package/server/whatsapp-rpc/node_modules/path-key/readme.md +61 -0
  320. package/server/whatsapp-rpc/node_modules/shebang-command/index.js +19 -0
  321. package/server/whatsapp-rpc/node_modules/shebang-command/license +9 -0
  322. package/server/whatsapp-rpc/node_modules/shebang-command/package.json +34 -0
  323. package/server/whatsapp-rpc/node_modules/shebang-command/readme.md +34 -0
  324. package/server/whatsapp-rpc/node_modules/shebang-regex/index.d.ts +22 -0
  325. package/server/whatsapp-rpc/node_modules/shebang-regex/index.js +2 -0
  326. package/server/whatsapp-rpc/node_modules/shebang-regex/license +9 -0
  327. package/server/whatsapp-rpc/node_modules/shebang-regex/package.json +35 -0
  328. package/server/whatsapp-rpc/node_modules/shebang-regex/readme.md +33 -0
  329. package/server/whatsapp-rpc/node_modules/shell-exec/LICENSE +21 -0
  330. package/server/whatsapp-rpc/node_modules/shell-exec/README.md +60 -0
  331. package/server/whatsapp-rpc/node_modules/shell-exec/index.js +47 -0
  332. package/server/whatsapp-rpc/node_modules/shell-exec/package.json +29 -0
  333. package/server/whatsapp-rpc/node_modules/signal-exit/LICENSE.txt +16 -0
  334. package/server/whatsapp-rpc/node_modules/signal-exit/README.md +74 -0
  335. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/browser.d.ts +12 -0
  336. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/browser.d.ts.map +1 -0
  337. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/browser.js +10 -0
  338. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/browser.js.map +1 -0
  339. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/index.d.ts +48 -0
  340. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/index.d.ts.map +1 -0
  341. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/index.js +279 -0
  342. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/index.js.map +1 -0
  343. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/package.json +3 -0
  344. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/signals.d.ts +29 -0
  345. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/signals.d.ts.map +1 -0
  346. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/signals.js +42 -0
  347. package/server/whatsapp-rpc/node_modules/signal-exit/dist/cjs/signals.js.map +1 -0
  348. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/browser.d.ts +12 -0
  349. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/browser.d.ts.map +1 -0
  350. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/browser.js +4 -0
  351. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/browser.js.map +1 -0
  352. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/index.d.ts +48 -0
  353. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/index.d.ts.map +1 -0
  354. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/index.js +275 -0
  355. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/index.js.map +1 -0
  356. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/package.json +3 -0
  357. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/signals.d.ts +29 -0
  358. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/signals.d.ts.map +1 -0
  359. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/signals.js +39 -0
  360. package/server/whatsapp-rpc/node_modules/signal-exit/dist/mjs/signals.js.map +1 -0
  361. package/server/whatsapp-rpc/node_modules/signal-exit/package.json +106 -0
  362. package/server/whatsapp-rpc/node_modules/strip-final-newline/index.js +14 -0
  363. package/server/whatsapp-rpc/node_modules/strip-final-newline/license +9 -0
  364. package/server/whatsapp-rpc/node_modules/strip-final-newline/package.json +43 -0
  365. package/server/whatsapp-rpc/node_modules/strip-final-newline/readme.md +35 -0
  366. package/server/whatsapp-rpc/node_modules/which/CHANGELOG.md +166 -0
  367. package/server/whatsapp-rpc/node_modules/which/LICENSE +15 -0
  368. package/server/whatsapp-rpc/node_modules/which/README.md +54 -0
  369. package/server/whatsapp-rpc/node_modules/which/bin/node-which +52 -0
  370. package/server/whatsapp-rpc/node_modules/which/package.json +43 -0
  371. package/server/whatsapp-rpc/node_modules/which/which.js +125 -0
  372. package/server/whatsapp-rpc/package-lock.json +272 -0
  373. package/server/whatsapp-rpc/package.json +30 -30
  374. package/server/whatsapp-rpc/schema.json +1294 -1294
  375. package/server/whatsapp-rpc/scripts/clean.cjs +66 -66
  376. package/server/whatsapp-rpc/scripts/cli.js +162 -162
  377. package/server/whatsapp-rpc/src/go/whatsapp/history.go +166 -166
  378. package/server/whatsapp-rpc/src/python/pyproject.toml +15 -15
  379. package/server/whatsapp-rpc/src/python/whatsapp_rpc/__init__.py +4 -4
  380. package/server/whatsapp-rpc/src/python/whatsapp_rpc/client.py +427 -427
  381. package/server/whatsapp-rpc/web/app.py +609 -609
  382. package/server/whatsapp-rpc/web/requirements.txt +6 -6
  383. package/server/whatsapp-rpc/web/rpc_client.py +427 -427
  384. package/server/whatsapp-rpc/web/static/openapi.yaml +59 -59
  385. package/server/whatsapp-rpc/web/templates/base.html +149 -149
  386. package/server/whatsapp-rpc/web/templates/contacts.html +240 -240
  387. package/server/whatsapp-rpc/web/templates/dashboard.html +319 -319
  388. package/server/whatsapp-rpc/web/templates/groups.html +328 -328
  389. package/server/whatsapp-rpc/web/templates/messages.html +465 -465
  390. package/server/whatsapp-rpc/web/templates/messaging.html +680 -680
  391. package/server/whatsapp-rpc/web/templates/send.html +258 -258
  392. package/server/whatsapp-rpc/web/templates/settings.html +459 -459
  393. package/client/src/components/ui/AndroidSettingsPanel.tsx +0 -401
  394. package/client/src/components/ui/WhatsAppSettingsPanel.tsx +0 -345
  395. package/client/src/nodeDefinitions/androidDeviceNodes.ts +0 -140
  396. package/docker-compose.prod.yml +0 -107
  397. package/docker-compose.yml +0 -104
  398. package/docs-MachinaOs/README.md +0 -85
  399. package/docs-MachinaOs/deployment/docker.mdx +0 -228
  400. package/docs-MachinaOs/deployment/production.mdx +0 -345
  401. package/docs-MachinaOs/docs.json +0 -75
  402. package/docs-MachinaOs/faq.mdx +0 -309
  403. package/docs-MachinaOs/favicon.svg +0 -5
  404. package/docs-MachinaOs/installation.mdx +0 -160
  405. package/docs-MachinaOs/introduction.mdx +0 -114
  406. package/docs-MachinaOs/logo/dark.svg +0 -6
  407. package/docs-MachinaOs/logo/light.svg +0 -6
  408. package/docs-MachinaOs/nodes/ai-agent.mdx +0 -216
  409. package/docs-MachinaOs/nodes/ai-models.mdx +0 -240
  410. package/docs-MachinaOs/nodes/android.mdx +0 -411
  411. package/docs-MachinaOs/nodes/overview.mdx +0 -181
  412. package/docs-MachinaOs/nodes/schedulers.mdx +0 -316
  413. package/docs-MachinaOs/nodes/webhooks.mdx +0 -330
  414. package/docs-MachinaOs/nodes/whatsapp.mdx +0 -305
  415. package/docs-MachinaOs/quickstart.mdx +0 -119
  416. package/docs-MachinaOs/tutorials/ai-agent-workflow.mdx +0 -177
  417. package/docs-MachinaOs/tutorials/android-automation.mdx +0 -242
  418. package/docs-MachinaOs/tutorials/first-workflow.mdx +0 -134
  419. package/docs-MachinaOs/tutorials/whatsapp-automation.mdx +0 -185
  420. package/nul +0 -0
  421. package/scripts/check-ports.ps1 +0 -33
  422. package/scripts/kill-port.ps1 +0 -154
@@ -1,459 +1,459 @@
1
- {% extends "base.html" %}
2
-
3
- {% block title %}Settings - WhatsApp Controller{% endblock %}
4
-
5
- {% block content %}
6
- <div class="space-y-6">
7
- <!-- Page Header -->
8
- <div class="flex items-center justify-between">
9
- <div>
10
- <h1 class="text-2xl font-bold text-gray-900">Settings</h1>
11
- <p class="text-gray-600">Configure rate limiting and anti-ban protection</p>
12
- </div>
13
- <button id="refresh-stats" class="bg-gray-600 text-white px-4 py-2 rounded-lg hover:bg-gray-700 flex items-center">
14
- <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
15
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
16
- </svg>
17
- Refresh
18
- </button>
19
- </div>
20
-
21
- <!-- Status Alert -->
22
- <div id="status-alert" class="hidden"></div>
23
-
24
- <!-- Stats Cards -->
25
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
26
- <!-- Messages Last Minute -->
27
- <div class="bg-white rounded-lg shadow p-6">
28
- <div class="flex items-center">
29
- <div class="p-3 rounded-full bg-blue-100 text-blue-600">
30
- <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
31
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"></path>
32
- </svg>
33
- </div>
34
- <div class="ml-4">
35
- <p class="text-sm text-gray-500">Messages/Min</p>
36
- <p class="text-2xl font-semibold text-gray-900"><span id="stat-messages-minute">-</span><span class="text-sm text-gray-400" id="stat-messages-minute-limit"></span></p>
37
- </div>
38
- </div>
39
- </div>
40
-
41
- <!-- Messages Last Hour -->
42
- <div class="bg-white rounded-lg shadow p-6">
43
- <div class="flex items-center">
44
- <div class="p-3 rounded-full bg-green-100 text-green-600">
45
- <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
46
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
47
- </svg>
48
- </div>
49
- <div class="ml-4">
50
- <p class="text-sm text-gray-500">Messages/Hour</p>
51
- <p class="text-2xl font-semibold text-gray-900"><span id="stat-messages-hour">-</span><span class="text-sm text-gray-400" id="stat-messages-hour-limit"></span></p>
52
- </div>
53
- </div>
54
- </div>
55
-
56
- <!-- New Contacts Today -->
57
- <div class="bg-white rounded-lg shadow p-6">
58
- <div class="flex items-center">
59
- <div class="p-3 rounded-full bg-purple-100 text-purple-600">
60
- <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
61
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z"></path>
62
- </svg>
63
- </div>
64
- <div class="ml-4">
65
- <p class="text-sm text-gray-500">New Contacts Today</p>
66
- <p class="text-2xl font-semibold text-gray-900"><span id="stat-new-contacts">-</span><span class="text-sm text-gray-400" id="stat-new-contacts-limit"></span></p>
67
- </div>
68
- </div>
69
- </div>
70
-
71
- <!-- Response Rate -->
72
- <div class="bg-white rounded-lg shadow p-6">
73
- <div class="flex items-center">
74
- <div class="p-3 rounded-full bg-yellow-100 text-yellow-600">
75
- <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
76
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
77
- </svg>
78
- </div>
79
- <div class="ml-4">
80
- <p class="text-sm text-gray-500">Response Rate</p>
81
- <p class="text-2xl font-semibold text-gray-900"><span id="stat-response-rate">-</span>%</p>
82
- </div>
83
- </div>
84
- </div>
85
- </div>
86
-
87
- <!-- Pause Status -->
88
- <div id="pause-alert" class="hidden bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg">
89
- <div class="flex items-center justify-between">
90
- <div class="flex items-center">
91
- <svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
92
- <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path>
93
- </svg>
94
- <span><strong>Rate Limiting Paused:</strong> <span id="pause-reason"></span></span>
95
- </div>
96
- <button id="unpause-btn" class="bg-red-600 text-white px-4 py-1 rounded hover:bg-red-700">
97
- Unpause
98
- </button>
99
- </div>
100
- </div>
101
-
102
- <!-- Configuration Section -->
103
- <div class="bg-white rounded-lg shadow">
104
- <div class="px-6 py-4 border-b border-gray-200">
105
- <h2 class="text-lg font-semibold text-gray-900">Rate Limiting Configuration</h2>
106
- <p class="text-sm text-gray-500">Configure delays and limits to avoid WhatsApp detection and bans</p>
107
- </div>
108
-
109
- <form id="config-form" class="p-6 space-y-6">
110
- <!-- Enable/Disable -->
111
- <div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
112
- <div>
113
- <h3 class="font-medium text-gray-900">Enable Rate Limiting</h3>
114
- <p class="text-sm text-gray-500">Master switch for all rate limiting features</p>
115
- </div>
116
- <label class="relative inline-flex items-center cursor-pointer">
117
- <input type="checkbox" id="config-enabled" class="sr-only peer" checked>
118
- <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-green-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-green-600"></div>
119
- </label>
120
- </div>
121
-
122
- <!-- Delays Section -->
123
- <div class="border-t pt-6">
124
- <h3 class="text-md font-medium text-gray-900 mb-4">Message Delays (milliseconds)</h3>
125
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
126
- <div>
127
- <label class="block text-sm font-medium text-gray-700 mb-1">Minimum Delay</label>
128
- <input type="number" id="config-min-delay" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0" step="100">
129
- <p class="text-xs text-gray-500 mt-1">Minimum time between messages (default: 3000ms)</p>
130
- </div>
131
- <div>
132
- <label class="block text-sm font-medium text-gray-700 mb-1">Maximum Delay</label>
133
- <input type="number" id="config-max-delay" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0" step="100">
134
- <p class="text-xs text-gray-500 mt-1">Maximum for randomization (default: 8000ms)</p>
135
- </div>
136
- <div>
137
- <label class="block text-sm font-medium text-gray-700 mb-1">Typing Indicator Duration</label>
138
- <input type="number" id="config-typing-delay" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0" step="100">
139
- <p class="text-xs text-gray-500 mt-1">How long to show typing (default: 2000ms)</p>
140
- </div>
141
- <div>
142
- <label class="block text-sm font-medium text-gray-700 mb-1">Extra Delay for Links</label>
143
- <input type="number" id="config-link-delay" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0" step="100">
144
- <p class="text-xs text-gray-500 mt-1">Additional delay for messages with URLs (default: 5000ms)</p>
145
- </div>
146
- </div>
147
- </div>
148
-
149
- <!-- Rate Limits Section -->
150
- <div class="border-t pt-6">
151
- <h3 class="text-md font-medium text-gray-900 mb-4">Rate Limits</h3>
152
- <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
153
- <div>
154
- <label class="block text-sm font-medium text-gray-700 mb-1">Messages per Minute</label>
155
- <input type="number" id="config-per-minute" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0">
156
- <p class="text-xs text-gray-500 mt-1">0 = unlimited (default: 10)</p>
157
- </div>
158
- <div>
159
- <label class="block text-sm font-medium text-gray-700 mb-1">Messages per Hour</label>
160
- <input type="number" id="config-per-hour" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0">
161
- <p class="text-xs text-gray-500 mt-1">0 = unlimited (default: 60)</p>
162
- </div>
163
- <div>
164
- <label class="block text-sm font-medium text-gray-700 mb-1">New Contacts per Day</label>
165
- <input type="number" id="config-new-contacts" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0">
166
- <p class="text-xs text-gray-500 mt-1">Critical for new accounts (default: 20)</p>
167
- </div>
168
- </div>
169
- </div>
170
-
171
- <!-- Human Simulation Section -->
172
- <div class="border-t pt-6">
173
- <h3 class="text-md font-medium text-gray-900 mb-4">Human Simulation</h3>
174
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
175
- <div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
176
- <div>
177
- <h4 class="font-medium text-gray-900">Simulate Typing</h4>
178
- <p class="text-sm text-gray-500">Send typing indicator before messages</p>
179
- </div>
180
- <label class="relative inline-flex items-center cursor-pointer">
181
- <input type="checkbox" id="config-simulate-typing" class="sr-only peer">
182
- <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-green-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-green-600"></div>
183
- </label>
184
- </div>
185
- <div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
186
- <div>
187
- <h4 class="font-medium text-gray-900">Randomize Delays</h4>
188
- <p class="text-sm text-gray-500">Add random variance to avoid patterns</p>
189
- </div>
190
- <label class="relative inline-flex items-center cursor-pointer">
191
- <input type="checkbox" id="config-randomize" class="sr-only peer">
192
- <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-green-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-green-600"></div>
193
- </label>
194
- </div>
195
- </div>
196
- </div>
197
-
198
- <!-- Safety Section -->
199
- <div class="border-t pt-6">
200
- <h3 class="text-md font-medium text-gray-900 mb-4">Safety Settings</h3>
201
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
202
- <div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
203
- <div>
204
- <h4 class="font-medium text-gray-900">Pause on Low Response</h4>
205
- <p class="text-sm text-gray-500">Auto-pause if response rate drops too low</p>
206
- </div>
207
- <label class="relative inline-flex items-center cursor-pointer">
208
- <input type="checkbox" id="config-pause-low-response" class="sr-only peer">
209
- <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-green-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-green-600"></div>
210
- </label>
211
- </div>
212
- <div>
213
- <label class="block text-sm font-medium text-gray-700 mb-1">Response Rate Threshold</label>
214
- <div class="flex items-center">
215
- <input type="number" id="config-response-threshold" class="w-24 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0" max="100" step="5">
216
- <span class="ml-2 text-gray-500">%</span>
217
- </div>
218
- <p class="text-xs text-gray-500 mt-1">Minimum acceptable response rate (default: 30%)</p>
219
- </div>
220
- </div>
221
- </div>
222
-
223
- <!-- Actions -->
224
- <div class="border-t pt-6 flex justify-between items-center">
225
- <button type="button" id="reset-defaults" class="text-gray-600 hover:text-gray-800">
226
- Reset to Defaults
227
- </button>
228
- <div class="flex gap-4">
229
- <button type="button" id="cancel-changes" class="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50">
230
- Cancel
231
- </button>
232
- <button type="submit" class="bg-green-600 text-white px-6 py-2 rounded-lg hover:bg-green-700">
233
- Save Configuration
234
- </button>
235
- </div>
236
- </div>
237
- </form>
238
- </div>
239
-
240
- <!-- Info Cards -->
241
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
242
- <!-- Tips Card -->
243
- <div class="bg-blue-50 border border-blue-200 rounded-lg p-6">
244
- <h3 class="font-semibold text-blue-800 mb-3">Anti-Ban Tips</h3>
245
- <ul class="text-sm text-blue-700 space-y-2">
246
- <li>- First 10 days have highest ban risk for new numbers</li>
247
- <li>- Keep new contacts under 20/day for new accounts</li>
248
- <li>- Always enable typing simulation</li>
249
- <li>- Use randomized delays to avoid patterns</li>
250
- <li>- Messages with links need extra delay for preview generation</li>
251
- <li>- Monitor response rate - low rates may indicate blocked messages</li>
252
- </ul>
253
- </div>
254
-
255
- <!-- Current Time Info -->
256
- <div class="bg-gray-50 border border-gray-200 rounded-lg p-6">
257
- <h3 class="font-semibold text-gray-800 mb-3">Timing Information</h3>
258
- <div class="text-sm text-gray-600 space-y-2">
259
- <p><strong>Last Message:</strong> <span id="info-last-message">-</span></p>
260
- <p><strong>Next Allowed:</strong> <span id="info-next-allowed">-</span></p>
261
- <p><strong>Messages Today:</strong> <span id="info-messages-today">-</span></p>
262
- <p><strong>Responses Received:</strong> <span id="info-responses">-</span></p>
263
- </div>
264
- </div>
265
- </div>
266
- </div>
267
- {% endblock %}
268
-
269
- {% block scripts %}
270
- <script>
271
- let currentConfig = {};
272
- let currentStats = {};
273
-
274
- document.addEventListener('DOMContentLoaded', function() {
275
- // Load initial data
276
- loadRateLimitData();
277
-
278
- // Event listeners
279
- document.getElementById('refresh-stats').addEventListener('click', loadRateLimitData);
280
- document.getElementById('config-form').addEventListener('submit', saveConfiguration);
281
- document.getElementById('unpause-btn').addEventListener('click', unpauseRateLimiting);
282
- document.getElementById('reset-defaults').addEventListener('click', resetToDefaults);
283
- document.getElementById('cancel-changes').addEventListener('click', loadRateLimitData);
284
-
285
- // Auto-refresh every 10 seconds
286
- setInterval(loadStats, 10000);
287
- });
288
-
289
- async function loadRateLimitData() {
290
- try {
291
- const response = await fetch('/api/rate-limit');
292
- const result = await response.json();
293
-
294
- if (result.success) {
295
- currentConfig = result.data.config;
296
- currentStats = result.data.stats;
297
- updateUI();
298
- } else {
299
- showAlert('Failed to load rate limit data: ' + result.error, 'error');
300
- }
301
- } catch (error) {
302
- showAlert('Error loading rate limit data: ' + error.message, 'error');
303
- }
304
- }
305
-
306
- async function loadStats() {
307
- try {
308
- const response = await fetch('/api/rate-limit/stats');
309
- const result = await response.json();
310
-
311
- if (result.success) {
312
- currentStats = result.data;
313
- updateStats();
314
- }
315
- } catch (error) {
316
- console.error('Error loading stats:', error);
317
- }
318
- }
319
-
320
- function updateUI() {
321
- updateStats();
322
- updateConfigForm();
323
- }
324
-
325
- function updateStats() {
326
- // Stats cards
327
- document.getElementById('stat-messages-minute').textContent = currentStats.messages_sent_last_minute || 0;
328
- document.getElementById('stat-messages-minute-limit').textContent = currentConfig.max_messages_per_minute ? ` / ${currentConfig.max_messages_per_minute}` : '';
329
-
330
- document.getElementById('stat-messages-hour').textContent = currentStats.messages_sent_last_hour || 0;
331
- document.getElementById('stat-messages-hour-limit').textContent = currentConfig.max_messages_per_hour ? ` / ${currentConfig.max_messages_per_hour}` : '';
332
-
333
- document.getElementById('stat-new-contacts').textContent = currentStats.new_contacts_today || 0;
334
- document.getElementById('stat-new-contacts-limit').textContent = currentConfig.max_new_contacts_per_day ? ` / ${currentConfig.max_new_contacts_per_day}` : '';
335
-
336
- document.getElementById('stat-response-rate').textContent = ((currentStats.response_rate || 0) * 100).toFixed(1);
337
-
338
- // Pause status
339
- const pauseAlert = document.getElementById('pause-alert');
340
- if (currentStats.is_paused) {
341
- pauseAlert.classList.remove('hidden');
342
- document.getElementById('pause-reason').textContent = currentStats.pause_reason || 'Unknown reason';
343
- } else {
344
- pauseAlert.classList.add('hidden');
345
- }
346
-
347
- // Timing info
348
- document.getElementById('info-last-message').textContent = currentStats.last_message_time ? formatTime(currentStats.last_message_time) : 'Never';
349
- document.getElementById('info-next-allowed').textContent = currentStats.next_allowed_time ? formatTime(currentStats.next_allowed_time) : '-';
350
- document.getElementById('info-messages-today').textContent = currentStats.messages_sent_today || 0;
351
- document.getElementById('info-responses').textContent = currentStats.responses_received || 0;
352
- }
353
-
354
- function updateConfigForm() {
355
- document.getElementById('config-enabled').checked = currentConfig.enabled !== false;
356
- document.getElementById('config-min-delay').value = currentConfig.min_delay_ms || 3000;
357
- document.getElementById('config-max-delay').value = currentConfig.max_delay_ms || 8000;
358
- document.getElementById('config-typing-delay').value = currentConfig.typing_delay_ms || 2000;
359
- document.getElementById('config-link-delay').value = currentConfig.link_extra_delay_ms || 5000;
360
- document.getElementById('config-per-minute').value = currentConfig.max_messages_per_minute || 10;
361
- document.getElementById('config-per-hour').value = currentConfig.max_messages_per_hour || 60;
362
- document.getElementById('config-new-contacts').value = currentConfig.max_new_contacts_per_day || 20;
363
- document.getElementById('config-simulate-typing').checked = currentConfig.simulate_typing !== false;
364
- document.getElementById('config-randomize').checked = currentConfig.randomize_delays !== false;
365
- document.getElementById('config-pause-low-response').checked = currentConfig.pause_on_low_response === true;
366
- document.getElementById('config-response-threshold').value = (currentConfig.response_rate_threshold || 0.3) * 100;
367
- }
368
-
369
- async function saveConfiguration(e) {
370
- e.preventDefault();
371
-
372
- const config = {
373
- enabled: document.getElementById('config-enabled').checked,
374
- min_delay_ms: parseInt(document.getElementById('config-min-delay').value) || 3000,
375
- max_delay_ms: parseInt(document.getElementById('config-max-delay').value) || 8000,
376
- typing_delay_ms: parseInt(document.getElementById('config-typing-delay').value) || 2000,
377
- link_extra_delay_ms: parseInt(document.getElementById('config-link-delay').value) || 5000,
378
- max_messages_per_minute: parseInt(document.getElementById('config-per-minute').value) || 0,
379
- max_messages_per_hour: parseInt(document.getElementById('config-per-hour').value) || 0,
380
- max_new_contacts_per_day: parseInt(document.getElementById('config-new-contacts').value) || 0,
381
- simulate_typing: document.getElementById('config-simulate-typing').checked,
382
- randomize_delays: document.getElementById('config-randomize').checked,
383
- pause_on_low_response: document.getElementById('config-pause-low-response').checked,
384
- response_rate_threshold: (parseInt(document.getElementById('config-response-threshold').value) || 30) / 100
385
- };
386
-
387
- try {
388
- const response = await fetch('/api/rate-limit', {
389
- method: 'POST',
390
- headers: { 'Content-Type': 'application/json' },
391
- body: JSON.stringify(config)
392
- });
393
-
394
- const result = await response.json();
395
-
396
- if (result.success) {
397
- currentConfig = result.data.config;
398
- showAlert('Configuration saved successfully', 'success');
399
- updateUI();
400
- } else {
401
- showAlert('Failed to save configuration: ' + result.error, 'error');
402
- }
403
- } catch (error) {
404
- showAlert('Error saving configuration: ' + error.message, 'error');
405
- }
406
- }
407
-
408
- async function unpauseRateLimiting() {
409
- try {
410
- const response = await fetch('/api/rate-limit/unpause', { method: 'POST' });
411
- const result = await response.json();
412
-
413
- if (result.success) {
414
- currentStats = result.data.stats;
415
- showAlert('Rate limiting unpaused', 'success');
416
- updateStats();
417
- } else {
418
- showAlert('Failed to unpause: ' + result.error, 'error');
419
- }
420
- } catch (error) {
421
- showAlert('Error unpausing: ' + error.message, 'error');
422
- }
423
- }
424
-
425
- function resetToDefaults() {
426
- document.getElementById('config-enabled').checked = true;
427
- document.getElementById('config-min-delay').value = 3000;
428
- document.getElementById('config-max-delay').value = 8000;
429
- document.getElementById('config-typing-delay').value = 2000;
430
- document.getElementById('config-link-delay').value = 5000;
431
- document.getElementById('config-per-minute').value = 10;
432
- document.getElementById('config-per-hour').value = 60;
433
- document.getElementById('config-new-contacts').value = 20;
434
- document.getElementById('config-simulate-typing').checked = true;
435
- document.getElementById('config-randomize').checked = true;
436
- document.getElementById('config-pause-low-response').checked = false;
437
- document.getElementById('config-response-threshold').value = 30;
438
- }
439
-
440
- function formatTime(isoString) {
441
- if (!isoString || isoString === '0001-01-01T00:00:00Z') return 'Never';
442
- const date = new Date(isoString);
443
- if (isNaN(date.getTime())) return '-';
444
- return date.toLocaleTimeString();
445
- }
446
-
447
- function showAlert(message, type) {
448
- const alertDiv = document.getElementById('status-alert');
449
- const bgColor = type === 'success' ? 'bg-green-100 border-green-400 text-green-700' : 'bg-red-100 border-red-400 text-red-700';
450
- alertDiv.className = `${bgColor} border px-4 py-3 rounded-lg mb-4`;
451
- alertDiv.textContent = message;
452
- alertDiv.classList.remove('hidden');
453
-
454
- setTimeout(() => {
455
- alertDiv.classList.add('hidden');
456
- }, 5000);
457
- }
458
- </script>
459
- {% endblock %}
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}Settings - WhatsApp Controller{% endblock %}
4
+
5
+ {% block content %}
6
+ <div class="space-y-6">
7
+ <!-- Page Header -->
8
+ <div class="flex items-center justify-between">
9
+ <div>
10
+ <h1 class="text-2xl font-bold text-gray-900">Settings</h1>
11
+ <p class="text-gray-600">Configure rate limiting and anti-ban protection</p>
12
+ </div>
13
+ <button id="refresh-stats" class="bg-gray-600 text-white px-4 py-2 rounded-lg hover:bg-gray-700 flex items-center">
14
+ <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
15
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
16
+ </svg>
17
+ Refresh
18
+ </button>
19
+ </div>
20
+
21
+ <!-- Status Alert -->
22
+ <div id="status-alert" class="hidden"></div>
23
+
24
+ <!-- Stats Cards -->
25
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
26
+ <!-- Messages Last Minute -->
27
+ <div class="bg-white rounded-lg shadow p-6">
28
+ <div class="flex items-center">
29
+ <div class="p-3 rounded-full bg-blue-100 text-blue-600">
30
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
31
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"></path>
32
+ </svg>
33
+ </div>
34
+ <div class="ml-4">
35
+ <p class="text-sm text-gray-500">Messages/Min</p>
36
+ <p class="text-2xl font-semibold text-gray-900"><span id="stat-messages-minute">-</span><span class="text-sm text-gray-400" id="stat-messages-minute-limit"></span></p>
37
+ </div>
38
+ </div>
39
+ </div>
40
+
41
+ <!-- Messages Last Hour -->
42
+ <div class="bg-white rounded-lg shadow p-6">
43
+ <div class="flex items-center">
44
+ <div class="p-3 rounded-full bg-green-100 text-green-600">
45
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
46
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
47
+ </svg>
48
+ </div>
49
+ <div class="ml-4">
50
+ <p class="text-sm text-gray-500">Messages/Hour</p>
51
+ <p class="text-2xl font-semibold text-gray-900"><span id="stat-messages-hour">-</span><span class="text-sm text-gray-400" id="stat-messages-hour-limit"></span></p>
52
+ </div>
53
+ </div>
54
+ </div>
55
+
56
+ <!-- New Contacts Today -->
57
+ <div class="bg-white rounded-lg shadow p-6">
58
+ <div class="flex items-center">
59
+ <div class="p-3 rounded-full bg-purple-100 text-purple-600">
60
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
61
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z"></path>
62
+ </svg>
63
+ </div>
64
+ <div class="ml-4">
65
+ <p class="text-sm text-gray-500">New Contacts Today</p>
66
+ <p class="text-2xl font-semibold text-gray-900"><span id="stat-new-contacts">-</span><span class="text-sm text-gray-400" id="stat-new-contacts-limit"></span></p>
67
+ </div>
68
+ </div>
69
+ </div>
70
+
71
+ <!-- Response Rate -->
72
+ <div class="bg-white rounded-lg shadow p-6">
73
+ <div class="flex items-center">
74
+ <div class="p-3 rounded-full bg-yellow-100 text-yellow-600">
75
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
76
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
77
+ </svg>
78
+ </div>
79
+ <div class="ml-4">
80
+ <p class="text-sm text-gray-500">Response Rate</p>
81
+ <p class="text-2xl font-semibold text-gray-900"><span id="stat-response-rate">-</span>%</p>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </div>
86
+
87
+ <!-- Pause Status -->
88
+ <div id="pause-alert" class="hidden bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg">
89
+ <div class="flex items-center justify-between">
90
+ <div class="flex items-center">
91
+ <svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
92
+ <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path>
93
+ </svg>
94
+ <span><strong>Rate Limiting Paused:</strong> <span id="pause-reason"></span></span>
95
+ </div>
96
+ <button id="unpause-btn" class="bg-red-600 text-white px-4 py-1 rounded hover:bg-red-700">
97
+ Unpause
98
+ </button>
99
+ </div>
100
+ </div>
101
+
102
+ <!-- Configuration Section -->
103
+ <div class="bg-white rounded-lg shadow">
104
+ <div class="px-6 py-4 border-b border-gray-200">
105
+ <h2 class="text-lg font-semibold text-gray-900">Rate Limiting Configuration</h2>
106
+ <p class="text-sm text-gray-500">Configure delays and limits to avoid WhatsApp detection and bans</p>
107
+ </div>
108
+
109
+ <form id="config-form" class="p-6 space-y-6">
110
+ <!-- Enable/Disable -->
111
+ <div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
112
+ <div>
113
+ <h3 class="font-medium text-gray-900">Enable Rate Limiting</h3>
114
+ <p class="text-sm text-gray-500">Master switch for all rate limiting features</p>
115
+ </div>
116
+ <label class="relative inline-flex items-center cursor-pointer">
117
+ <input type="checkbox" id="config-enabled" class="sr-only peer" checked>
118
+ <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-green-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-green-600"></div>
119
+ </label>
120
+ </div>
121
+
122
+ <!-- Delays Section -->
123
+ <div class="border-t pt-6">
124
+ <h3 class="text-md font-medium text-gray-900 mb-4">Message Delays (milliseconds)</h3>
125
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
126
+ <div>
127
+ <label class="block text-sm font-medium text-gray-700 mb-1">Minimum Delay</label>
128
+ <input type="number" id="config-min-delay" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0" step="100">
129
+ <p class="text-xs text-gray-500 mt-1">Minimum time between messages (default: 3000ms)</p>
130
+ </div>
131
+ <div>
132
+ <label class="block text-sm font-medium text-gray-700 mb-1">Maximum Delay</label>
133
+ <input type="number" id="config-max-delay" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0" step="100">
134
+ <p class="text-xs text-gray-500 mt-1">Maximum for randomization (default: 8000ms)</p>
135
+ </div>
136
+ <div>
137
+ <label class="block text-sm font-medium text-gray-700 mb-1">Typing Indicator Duration</label>
138
+ <input type="number" id="config-typing-delay" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0" step="100">
139
+ <p class="text-xs text-gray-500 mt-1">How long to show typing (default: 2000ms)</p>
140
+ </div>
141
+ <div>
142
+ <label class="block text-sm font-medium text-gray-700 mb-1">Extra Delay for Links</label>
143
+ <input type="number" id="config-link-delay" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0" step="100">
144
+ <p class="text-xs text-gray-500 mt-1">Additional delay for messages with URLs (default: 5000ms)</p>
145
+ </div>
146
+ </div>
147
+ </div>
148
+
149
+ <!-- Rate Limits Section -->
150
+ <div class="border-t pt-6">
151
+ <h3 class="text-md font-medium text-gray-900 mb-4">Rate Limits</h3>
152
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
153
+ <div>
154
+ <label class="block text-sm font-medium text-gray-700 mb-1">Messages per Minute</label>
155
+ <input type="number" id="config-per-minute" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0">
156
+ <p class="text-xs text-gray-500 mt-1">0 = unlimited (default: 10)</p>
157
+ </div>
158
+ <div>
159
+ <label class="block text-sm font-medium text-gray-700 mb-1">Messages per Hour</label>
160
+ <input type="number" id="config-per-hour" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0">
161
+ <p class="text-xs text-gray-500 mt-1">0 = unlimited (default: 60)</p>
162
+ </div>
163
+ <div>
164
+ <label class="block text-sm font-medium text-gray-700 mb-1">New Contacts per Day</label>
165
+ <input type="number" id="config-new-contacts" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0">
166
+ <p class="text-xs text-gray-500 mt-1">Critical for new accounts (default: 20)</p>
167
+ </div>
168
+ </div>
169
+ </div>
170
+
171
+ <!-- Human Simulation Section -->
172
+ <div class="border-t pt-6">
173
+ <h3 class="text-md font-medium text-gray-900 mb-4">Human Simulation</h3>
174
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
175
+ <div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
176
+ <div>
177
+ <h4 class="font-medium text-gray-900">Simulate Typing</h4>
178
+ <p class="text-sm text-gray-500">Send typing indicator before messages</p>
179
+ </div>
180
+ <label class="relative inline-flex items-center cursor-pointer">
181
+ <input type="checkbox" id="config-simulate-typing" class="sr-only peer">
182
+ <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-green-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-green-600"></div>
183
+ </label>
184
+ </div>
185
+ <div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
186
+ <div>
187
+ <h4 class="font-medium text-gray-900">Randomize Delays</h4>
188
+ <p class="text-sm text-gray-500">Add random variance to avoid patterns</p>
189
+ </div>
190
+ <label class="relative inline-flex items-center cursor-pointer">
191
+ <input type="checkbox" id="config-randomize" class="sr-only peer">
192
+ <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-green-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-green-600"></div>
193
+ </label>
194
+ </div>
195
+ </div>
196
+ </div>
197
+
198
+ <!-- Safety Section -->
199
+ <div class="border-t pt-6">
200
+ <h3 class="text-md font-medium text-gray-900 mb-4">Safety Settings</h3>
201
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
202
+ <div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
203
+ <div>
204
+ <h4 class="font-medium text-gray-900">Pause on Low Response</h4>
205
+ <p class="text-sm text-gray-500">Auto-pause if response rate drops too low</p>
206
+ </div>
207
+ <label class="relative inline-flex items-center cursor-pointer">
208
+ <input type="checkbox" id="config-pause-low-response" class="sr-only peer">
209
+ <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-green-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-green-600"></div>
210
+ </label>
211
+ </div>
212
+ <div>
213
+ <label class="block text-sm font-medium text-gray-700 mb-1">Response Rate Threshold</label>
214
+ <div class="flex items-center">
215
+ <input type="number" id="config-response-threshold" class="w-24 px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500" min="0" max="100" step="5">
216
+ <span class="ml-2 text-gray-500">%</span>
217
+ </div>
218
+ <p class="text-xs text-gray-500 mt-1">Minimum acceptable response rate (default: 30%)</p>
219
+ </div>
220
+ </div>
221
+ </div>
222
+
223
+ <!-- Actions -->
224
+ <div class="border-t pt-6 flex justify-between items-center">
225
+ <button type="button" id="reset-defaults" class="text-gray-600 hover:text-gray-800">
226
+ Reset to Defaults
227
+ </button>
228
+ <div class="flex gap-4">
229
+ <button type="button" id="cancel-changes" class="px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50">
230
+ Cancel
231
+ </button>
232
+ <button type="submit" class="bg-green-600 text-white px-6 py-2 rounded-lg hover:bg-green-700">
233
+ Save Configuration
234
+ </button>
235
+ </div>
236
+ </div>
237
+ </form>
238
+ </div>
239
+
240
+ <!-- Info Cards -->
241
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
242
+ <!-- Tips Card -->
243
+ <div class="bg-blue-50 border border-blue-200 rounded-lg p-6">
244
+ <h3 class="font-semibold text-blue-800 mb-3">Anti-Ban Tips</h3>
245
+ <ul class="text-sm text-blue-700 space-y-2">
246
+ <li>- First 10 days have highest ban risk for new numbers</li>
247
+ <li>- Keep new contacts under 20/day for new accounts</li>
248
+ <li>- Always enable typing simulation</li>
249
+ <li>- Use randomized delays to avoid patterns</li>
250
+ <li>- Messages with links need extra delay for preview generation</li>
251
+ <li>- Monitor response rate - low rates may indicate blocked messages</li>
252
+ </ul>
253
+ </div>
254
+
255
+ <!-- Current Time Info -->
256
+ <div class="bg-gray-50 border border-gray-200 rounded-lg p-6">
257
+ <h3 class="font-semibold text-gray-800 mb-3">Timing Information</h3>
258
+ <div class="text-sm text-gray-600 space-y-2">
259
+ <p><strong>Last Message:</strong> <span id="info-last-message">-</span></p>
260
+ <p><strong>Next Allowed:</strong> <span id="info-next-allowed">-</span></p>
261
+ <p><strong>Messages Today:</strong> <span id="info-messages-today">-</span></p>
262
+ <p><strong>Responses Received:</strong> <span id="info-responses">-</span></p>
263
+ </div>
264
+ </div>
265
+ </div>
266
+ </div>
267
+ {% endblock %}
268
+
269
+ {% block scripts %}
270
+ <script>
271
+ let currentConfig = {};
272
+ let currentStats = {};
273
+
274
+ document.addEventListener('DOMContentLoaded', function() {
275
+ // Load initial data
276
+ loadRateLimitData();
277
+
278
+ // Event listeners
279
+ document.getElementById('refresh-stats').addEventListener('click', loadRateLimitData);
280
+ document.getElementById('config-form').addEventListener('submit', saveConfiguration);
281
+ document.getElementById('unpause-btn').addEventListener('click', unpauseRateLimiting);
282
+ document.getElementById('reset-defaults').addEventListener('click', resetToDefaults);
283
+ document.getElementById('cancel-changes').addEventListener('click', loadRateLimitData);
284
+
285
+ // Auto-refresh every 10 seconds
286
+ setInterval(loadStats, 10000);
287
+ });
288
+
289
+ async function loadRateLimitData() {
290
+ try {
291
+ const response = await fetch('/api/rate-limit');
292
+ const result = await response.json();
293
+
294
+ if (result.success) {
295
+ currentConfig = result.data.config;
296
+ currentStats = result.data.stats;
297
+ updateUI();
298
+ } else {
299
+ showAlert('Failed to load rate limit data: ' + result.error, 'error');
300
+ }
301
+ } catch (error) {
302
+ showAlert('Error loading rate limit data: ' + error.message, 'error');
303
+ }
304
+ }
305
+
306
+ async function loadStats() {
307
+ try {
308
+ const response = await fetch('/api/rate-limit/stats');
309
+ const result = await response.json();
310
+
311
+ if (result.success) {
312
+ currentStats = result.data;
313
+ updateStats();
314
+ }
315
+ } catch (error) {
316
+ console.error('Error loading stats:', error);
317
+ }
318
+ }
319
+
320
+ function updateUI() {
321
+ updateStats();
322
+ updateConfigForm();
323
+ }
324
+
325
+ function updateStats() {
326
+ // Stats cards
327
+ document.getElementById('stat-messages-minute').textContent = currentStats.messages_sent_last_minute || 0;
328
+ document.getElementById('stat-messages-minute-limit').textContent = currentConfig.max_messages_per_minute ? ` / ${currentConfig.max_messages_per_minute}` : '';
329
+
330
+ document.getElementById('stat-messages-hour').textContent = currentStats.messages_sent_last_hour || 0;
331
+ document.getElementById('stat-messages-hour-limit').textContent = currentConfig.max_messages_per_hour ? ` / ${currentConfig.max_messages_per_hour}` : '';
332
+
333
+ document.getElementById('stat-new-contacts').textContent = currentStats.new_contacts_today || 0;
334
+ document.getElementById('stat-new-contacts-limit').textContent = currentConfig.max_new_contacts_per_day ? ` / ${currentConfig.max_new_contacts_per_day}` : '';
335
+
336
+ document.getElementById('stat-response-rate').textContent = ((currentStats.response_rate || 0) * 100).toFixed(1);
337
+
338
+ // Pause status
339
+ const pauseAlert = document.getElementById('pause-alert');
340
+ if (currentStats.is_paused) {
341
+ pauseAlert.classList.remove('hidden');
342
+ document.getElementById('pause-reason').textContent = currentStats.pause_reason || 'Unknown reason';
343
+ } else {
344
+ pauseAlert.classList.add('hidden');
345
+ }
346
+
347
+ // Timing info
348
+ document.getElementById('info-last-message').textContent = currentStats.last_message_time ? formatTime(currentStats.last_message_time) : 'Never';
349
+ document.getElementById('info-next-allowed').textContent = currentStats.next_allowed_time ? formatTime(currentStats.next_allowed_time) : '-';
350
+ document.getElementById('info-messages-today').textContent = currentStats.messages_sent_today || 0;
351
+ document.getElementById('info-responses').textContent = currentStats.responses_received || 0;
352
+ }
353
+
354
+ function updateConfigForm() {
355
+ document.getElementById('config-enabled').checked = currentConfig.enabled !== false;
356
+ document.getElementById('config-min-delay').value = currentConfig.min_delay_ms || 3000;
357
+ document.getElementById('config-max-delay').value = currentConfig.max_delay_ms || 8000;
358
+ document.getElementById('config-typing-delay').value = currentConfig.typing_delay_ms || 2000;
359
+ document.getElementById('config-link-delay').value = currentConfig.link_extra_delay_ms || 5000;
360
+ document.getElementById('config-per-minute').value = currentConfig.max_messages_per_minute || 10;
361
+ document.getElementById('config-per-hour').value = currentConfig.max_messages_per_hour || 60;
362
+ document.getElementById('config-new-contacts').value = currentConfig.max_new_contacts_per_day || 20;
363
+ document.getElementById('config-simulate-typing').checked = currentConfig.simulate_typing !== false;
364
+ document.getElementById('config-randomize').checked = currentConfig.randomize_delays !== false;
365
+ document.getElementById('config-pause-low-response').checked = currentConfig.pause_on_low_response === true;
366
+ document.getElementById('config-response-threshold').value = (currentConfig.response_rate_threshold || 0.3) * 100;
367
+ }
368
+
369
+ async function saveConfiguration(e) {
370
+ e.preventDefault();
371
+
372
+ const config = {
373
+ enabled: document.getElementById('config-enabled').checked,
374
+ min_delay_ms: parseInt(document.getElementById('config-min-delay').value) || 3000,
375
+ max_delay_ms: parseInt(document.getElementById('config-max-delay').value) || 8000,
376
+ typing_delay_ms: parseInt(document.getElementById('config-typing-delay').value) || 2000,
377
+ link_extra_delay_ms: parseInt(document.getElementById('config-link-delay').value) || 5000,
378
+ max_messages_per_minute: parseInt(document.getElementById('config-per-minute').value) || 0,
379
+ max_messages_per_hour: parseInt(document.getElementById('config-per-hour').value) || 0,
380
+ max_new_contacts_per_day: parseInt(document.getElementById('config-new-contacts').value) || 0,
381
+ simulate_typing: document.getElementById('config-simulate-typing').checked,
382
+ randomize_delays: document.getElementById('config-randomize').checked,
383
+ pause_on_low_response: document.getElementById('config-pause-low-response').checked,
384
+ response_rate_threshold: (parseInt(document.getElementById('config-response-threshold').value) || 30) / 100
385
+ };
386
+
387
+ try {
388
+ const response = await fetch('/api/rate-limit', {
389
+ method: 'POST',
390
+ headers: { 'Content-Type': 'application/json' },
391
+ body: JSON.stringify(config)
392
+ });
393
+
394
+ const result = await response.json();
395
+
396
+ if (result.success) {
397
+ currentConfig = result.data.config;
398
+ showAlert('Configuration saved successfully', 'success');
399
+ updateUI();
400
+ } else {
401
+ showAlert('Failed to save configuration: ' + result.error, 'error');
402
+ }
403
+ } catch (error) {
404
+ showAlert('Error saving configuration: ' + error.message, 'error');
405
+ }
406
+ }
407
+
408
+ async function unpauseRateLimiting() {
409
+ try {
410
+ const response = await fetch('/api/rate-limit/unpause', { method: 'POST' });
411
+ const result = await response.json();
412
+
413
+ if (result.success) {
414
+ currentStats = result.data.stats;
415
+ showAlert('Rate limiting unpaused', 'success');
416
+ updateStats();
417
+ } else {
418
+ showAlert('Failed to unpause: ' + result.error, 'error');
419
+ }
420
+ } catch (error) {
421
+ showAlert('Error unpausing: ' + error.message, 'error');
422
+ }
423
+ }
424
+
425
+ function resetToDefaults() {
426
+ document.getElementById('config-enabled').checked = true;
427
+ document.getElementById('config-min-delay').value = 3000;
428
+ document.getElementById('config-max-delay').value = 8000;
429
+ document.getElementById('config-typing-delay').value = 2000;
430
+ document.getElementById('config-link-delay').value = 5000;
431
+ document.getElementById('config-per-minute').value = 10;
432
+ document.getElementById('config-per-hour').value = 60;
433
+ document.getElementById('config-new-contacts').value = 20;
434
+ document.getElementById('config-simulate-typing').checked = true;
435
+ document.getElementById('config-randomize').checked = true;
436
+ document.getElementById('config-pause-low-response').checked = false;
437
+ document.getElementById('config-response-threshold').value = 30;
438
+ }
439
+
440
+ function formatTime(isoString) {
441
+ if (!isoString || isoString === '0001-01-01T00:00:00Z') return 'Never';
442
+ const date = new Date(isoString);
443
+ if (isNaN(date.getTime())) return '-';
444
+ return date.toLocaleTimeString();
445
+ }
446
+
447
+ function showAlert(message, type) {
448
+ const alertDiv = document.getElementById('status-alert');
449
+ const bgColor = type === 'success' ? 'bg-green-100 border-green-400 text-green-700' : 'bg-red-100 border-red-400 text-red-700';
450
+ alertDiv.className = `${bgColor} border px-4 py-3 rounded-lg mb-4`;
451
+ alertDiv.textContent = message;
452
+ alertDiv.classList.remove('hidden');
453
+
454
+ setTimeout(() => {
455
+ alertDiv.classList.add('hidden');
456
+ }, 5000);
457
+ }
458
+ </script>
459
+ {% endblock %}