machinaos 0.0.1

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 (288) hide show
  1. package/.env.template +71 -0
  2. package/LICENSE +21 -0
  3. package/README.md +87 -0
  4. package/bin/cli.js +159 -0
  5. package/client/.dockerignore +45 -0
  6. package/client/Dockerfile +68 -0
  7. package/client/eslint.config.js +29 -0
  8. package/client/index.html +13 -0
  9. package/client/nginx.conf +66 -0
  10. package/client/package.json +48 -0
  11. package/client/src/App.tsx +27 -0
  12. package/client/src/Dashboard.tsx +1173 -0
  13. package/client/src/ParameterPanel.tsx +301 -0
  14. package/client/src/components/AIAgentNode.tsx +321 -0
  15. package/client/src/components/APIKeyValidator.tsx +118 -0
  16. package/client/src/components/ClaudeChatModelNode.tsx +18 -0
  17. package/client/src/components/ConditionalEdge.tsx +189 -0
  18. package/client/src/components/CredentialsModal.tsx +306 -0
  19. package/client/src/components/EdgeConditionEditor.tsx +443 -0
  20. package/client/src/components/GeminiChatModelNode.tsx +18 -0
  21. package/client/src/components/GenericNode.tsx +357 -0
  22. package/client/src/components/LocationParameterPanel.tsx +154 -0
  23. package/client/src/components/ModelNode.tsx +286 -0
  24. package/client/src/components/OpenAIChatModelNode.tsx +18 -0
  25. package/client/src/components/OutputPanel.tsx +471 -0
  26. package/client/src/components/ParameterRenderer.tsx +1874 -0
  27. package/client/src/components/SkillEditorModal.tsx +417 -0
  28. package/client/src/components/SquareNode.tsx +797 -0
  29. package/client/src/components/StartNode.tsx +250 -0
  30. package/client/src/components/ToolkitNode.tsx +365 -0
  31. package/client/src/components/TriggerNode.tsx +463 -0
  32. package/client/src/components/auth/LoginPage.tsx +247 -0
  33. package/client/src/components/auth/ProtectedRoute.tsx +59 -0
  34. package/client/src/components/base/BaseChatModelNode.tsx +271 -0
  35. package/client/src/components/icons/AIProviderIcons.tsx +50 -0
  36. package/client/src/components/maps/GoogleMapsPicker.tsx +137 -0
  37. package/client/src/components/maps/MapsPreviewPanel.tsx +110 -0
  38. package/client/src/components/maps/index.ts +26 -0
  39. package/client/src/components/parameterPanel/InputSection.tsx +1094 -0
  40. package/client/src/components/parameterPanel/LocationPanelLayout.tsx +65 -0
  41. package/client/src/components/parameterPanel/MapsSection.tsx +92 -0
  42. package/client/src/components/parameterPanel/MiddleSection.tsx +571 -0
  43. package/client/src/components/parameterPanel/OutputSection.tsx +81 -0
  44. package/client/src/components/parameterPanel/ParameterPanelLayout.tsx +82 -0
  45. package/client/src/components/parameterPanel/ToolSchemaEditor.tsx +436 -0
  46. package/client/src/components/parameterPanel/index.ts +42 -0
  47. package/client/src/components/shared/DataPanel.tsx +142 -0
  48. package/client/src/components/shared/JSONTreeRenderer.tsx +106 -0
  49. package/client/src/components/ui/AIResultModal.tsx +204 -0
  50. package/client/src/components/ui/AndroidSettingsPanel.tsx +401 -0
  51. package/client/src/components/ui/CodeEditor.tsx +81 -0
  52. package/client/src/components/ui/CollapsibleSection.tsx +88 -0
  53. package/client/src/components/ui/ComponentItem.tsx +154 -0
  54. package/client/src/components/ui/ComponentPalette.tsx +321 -0
  55. package/client/src/components/ui/ConsolePanel.tsx +1074 -0
  56. package/client/src/components/ui/ErrorBoundary.tsx +196 -0
  57. package/client/src/components/ui/InputNodesPanel.tsx +204 -0
  58. package/client/src/components/ui/MapSelector.tsx +314 -0
  59. package/client/src/components/ui/Modal.tsx +149 -0
  60. package/client/src/components/ui/NodeContextMenu.tsx +192 -0
  61. package/client/src/components/ui/NodeOutputPanel.tsx +1150 -0
  62. package/client/src/components/ui/OutputDisplayPanel.tsx +381 -0
  63. package/client/src/components/ui/SettingsPanel.tsx +243 -0
  64. package/client/src/components/ui/TopToolbar.tsx +736 -0
  65. package/client/src/components/ui/WhatsAppSettingsPanel.tsx +345 -0
  66. package/client/src/components/ui/WorkflowSidebar.tsx +294 -0
  67. package/client/src/config/antdTheme.ts +186 -0
  68. package/client/src/config/api.ts +54 -0
  69. package/client/src/contexts/AuthContext.tsx +221 -0
  70. package/client/src/contexts/ThemeContext.tsx +42 -0
  71. package/client/src/contexts/WebSocketContext.tsx +1971 -0
  72. package/client/src/factories/baseChatModelFactory.ts +256 -0
  73. package/client/src/hooks/useAndroidOperations.ts +164 -0
  74. package/client/src/hooks/useApiKeyValidation.ts +107 -0
  75. package/client/src/hooks/useApiKeys.ts +238 -0
  76. package/client/src/hooks/useAppTheme.ts +17 -0
  77. package/client/src/hooks/useComponentPalette.ts +51 -0
  78. package/client/src/hooks/useCopyPaste.ts +155 -0
  79. package/client/src/hooks/useDragAndDrop.ts +124 -0
  80. package/client/src/hooks/useDragVariable.ts +88 -0
  81. package/client/src/hooks/useExecution.ts +313 -0
  82. package/client/src/hooks/useParameterPanel.ts +176 -0
  83. package/client/src/hooks/useReactFlowNodes.ts +189 -0
  84. package/client/src/hooks/useToolSchema.ts +209 -0
  85. package/client/src/hooks/useWhatsApp.ts +196 -0
  86. package/client/src/hooks/useWorkflowManagement.ts +46 -0
  87. package/client/src/index.css +315 -0
  88. package/client/src/main.tsx +19 -0
  89. package/client/src/nodeDefinitions/aiAgentNodes.ts +336 -0
  90. package/client/src/nodeDefinitions/aiModelNodes.ts +340 -0
  91. package/client/src/nodeDefinitions/androidDeviceNodes.ts +140 -0
  92. package/client/src/nodeDefinitions/androidServiceNodes.ts +383 -0
  93. package/client/src/nodeDefinitions/chatNodes.ts +135 -0
  94. package/client/src/nodeDefinitions/codeNodes.ts +54 -0
  95. package/client/src/nodeDefinitions/documentNodes.ts +379 -0
  96. package/client/src/nodeDefinitions/index.ts +15 -0
  97. package/client/src/nodeDefinitions/locationNodes.ts +463 -0
  98. package/client/src/nodeDefinitions/schedulerNodes.ts +220 -0
  99. package/client/src/nodeDefinitions/skillNodes.ts +211 -0
  100. package/client/src/nodeDefinitions/toolNodes.ts +198 -0
  101. package/client/src/nodeDefinitions/utilityNodes.ts +284 -0
  102. package/client/src/nodeDefinitions/whatsappNodes.ts +865 -0
  103. package/client/src/nodeDefinitions/workflowNodes.ts +41 -0
  104. package/client/src/nodeDefinitions.ts +104 -0
  105. package/client/src/schemas/workflowSchema.ts +264 -0
  106. package/client/src/services/dynamicParameterService.ts +96 -0
  107. package/client/src/services/execution/aiAgentExecutionService.ts +35 -0
  108. package/client/src/services/executionService.ts +232 -0
  109. package/client/src/services/workflowApi.ts +91 -0
  110. package/client/src/store/useAppStore.ts +582 -0
  111. package/client/src/styles/theme.ts +508 -0
  112. package/client/src/styles/zIndex.ts +17 -0
  113. package/client/src/types/ComponentTypes.ts +39 -0
  114. package/client/src/types/EdgeCondition.ts +231 -0
  115. package/client/src/types/INodeProperties.ts +288 -0
  116. package/client/src/types/NodeTypes.ts +28 -0
  117. package/client/src/utils/formatters.ts +33 -0
  118. package/client/src/utils/googleMapsLoader.ts +140 -0
  119. package/client/src/utils/locationUtils.ts +85 -0
  120. package/client/src/utils/nodeUtils.ts +31 -0
  121. package/client/src/utils/workflow.ts +30 -0
  122. package/client/src/utils/workflowExport.ts +120 -0
  123. package/client/src/vite-env.d.ts +12 -0
  124. package/client/tailwind.config.js +60 -0
  125. package/client/tsconfig.json +25 -0
  126. package/client/tsconfig.node.json +11 -0
  127. package/client/vite.config.js +35 -0
  128. package/docker-compose.prod.yml +107 -0
  129. package/docker-compose.yml +104 -0
  130. package/docs-MachinaOs/README.md +85 -0
  131. package/docs-MachinaOs/deployment/docker.mdx +228 -0
  132. package/docs-MachinaOs/deployment/production.mdx +345 -0
  133. package/docs-MachinaOs/docs.json +75 -0
  134. package/docs-MachinaOs/faq.mdx +309 -0
  135. package/docs-MachinaOs/favicon.svg +5 -0
  136. package/docs-MachinaOs/installation.mdx +160 -0
  137. package/docs-MachinaOs/introduction.mdx +114 -0
  138. package/docs-MachinaOs/logo/dark.svg +6 -0
  139. package/docs-MachinaOs/logo/light.svg +6 -0
  140. package/docs-MachinaOs/nodes/ai-agent.mdx +216 -0
  141. package/docs-MachinaOs/nodes/ai-models.mdx +240 -0
  142. package/docs-MachinaOs/nodes/android.mdx +411 -0
  143. package/docs-MachinaOs/nodes/overview.mdx +181 -0
  144. package/docs-MachinaOs/nodes/schedulers.mdx +316 -0
  145. package/docs-MachinaOs/nodes/webhooks.mdx +330 -0
  146. package/docs-MachinaOs/nodes/whatsapp.mdx +305 -0
  147. package/docs-MachinaOs/quickstart.mdx +119 -0
  148. package/docs-MachinaOs/tutorials/ai-agent-workflow.mdx +177 -0
  149. package/docs-MachinaOs/tutorials/android-automation.mdx +242 -0
  150. package/docs-MachinaOs/tutorials/first-workflow.mdx +134 -0
  151. package/docs-MachinaOs/tutorials/whatsapp-automation.mdx +185 -0
  152. package/nul +0 -0
  153. package/package.json +70 -0
  154. package/scripts/build.js +158 -0
  155. package/scripts/check-ports.ps1 +33 -0
  156. package/scripts/clean.js +40 -0
  157. package/scripts/docker.js +93 -0
  158. package/scripts/kill-port.ps1 +154 -0
  159. package/scripts/start.js +210 -0
  160. package/scripts/stop.js +325 -0
  161. package/server/.dockerignore +44 -0
  162. package/server/Dockerfile +45 -0
  163. package/server/constants.py +249 -0
  164. package/server/core/__init__.py +1 -0
  165. package/server/core/cache.py +461 -0
  166. package/server/core/config.py +128 -0
  167. package/server/core/container.py +99 -0
  168. package/server/core/database.py +1211 -0
  169. package/server/core/logging.py +314 -0
  170. package/server/main.py +289 -0
  171. package/server/middleware/__init__.py +5 -0
  172. package/server/middleware/auth.py +89 -0
  173. package/server/models/__init__.py +1 -0
  174. package/server/models/auth.py +52 -0
  175. package/server/models/cache.py +24 -0
  176. package/server/models/database.py +211 -0
  177. package/server/models/nodes.py +455 -0
  178. package/server/package.json +9 -0
  179. package/server/pyproject.toml +72 -0
  180. package/server/requirements.txt +83 -0
  181. package/server/routers/__init__.py +1 -0
  182. package/server/routers/android.py +294 -0
  183. package/server/routers/auth.py +203 -0
  184. package/server/routers/database.py +151 -0
  185. package/server/routers/maps.py +142 -0
  186. package/server/routers/nodejs_compat.py +289 -0
  187. package/server/routers/webhook.py +90 -0
  188. package/server/routers/websocket.py +2127 -0
  189. package/server/routers/whatsapp.py +761 -0
  190. package/server/routers/workflow.py +200 -0
  191. package/server/services/__init__.py +1 -0
  192. package/server/services/ai.py +2415 -0
  193. package/server/services/android/__init__.py +27 -0
  194. package/server/services/android/broadcaster.py +114 -0
  195. package/server/services/android/client.py +608 -0
  196. package/server/services/android/manager.py +78 -0
  197. package/server/services/android/protocol.py +165 -0
  198. package/server/services/android_service.py +588 -0
  199. package/server/services/auth.py +131 -0
  200. package/server/services/chat_client.py +160 -0
  201. package/server/services/deployment/__init__.py +12 -0
  202. package/server/services/deployment/manager.py +706 -0
  203. package/server/services/deployment/state.py +47 -0
  204. package/server/services/deployment/triggers.py +275 -0
  205. package/server/services/event_waiter.py +785 -0
  206. package/server/services/execution/__init__.py +77 -0
  207. package/server/services/execution/cache.py +769 -0
  208. package/server/services/execution/conditions.py +373 -0
  209. package/server/services/execution/dlq.py +132 -0
  210. package/server/services/execution/executor.py +1351 -0
  211. package/server/services/execution/models.py +531 -0
  212. package/server/services/execution/recovery.py +235 -0
  213. package/server/services/handlers/__init__.py +126 -0
  214. package/server/services/handlers/ai.py +355 -0
  215. package/server/services/handlers/android.py +260 -0
  216. package/server/services/handlers/code.py +278 -0
  217. package/server/services/handlers/document.py +598 -0
  218. package/server/services/handlers/http.py +193 -0
  219. package/server/services/handlers/polyglot.py +105 -0
  220. package/server/services/handlers/tools.py +845 -0
  221. package/server/services/handlers/triggers.py +107 -0
  222. package/server/services/handlers/utility.py +822 -0
  223. package/server/services/handlers/whatsapp.py +476 -0
  224. package/server/services/maps.py +289 -0
  225. package/server/services/memory_store.py +103 -0
  226. package/server/services/node_executor.py +375 -0
  227. package/server/services/parameter_resolver.py +218 -0
  228. package/server/services/polyglot_client.py +169 -0
  229. package/server/services/scheduler.py +155 -0
  230. package/server/services/skill_loader.py +417 -0
  231. package/server/services/status_broadcaster.py +826 -0
  232. package/server/services/temporal/__init__.py +23 -0
  233. package/server/services/temporal/activities.py +344 -0
  234. package/server/services/temporal/client.py +76 -0
  235. package/server/services/temporal/executor.py +147 -0
  236. package/server/services/temporal/worker.py +251 -0
  237. package/server/services/temporal/workflow.py +355 -0
  238. package/server/services/temporal/ws_client.py +236 -0
  239. package/server/services/text.py +111 -0
  240. package/server/services/user_auth.py +172 -0
  241. package/server/services/websocket_client.py +29 -0
  242. package/server/services/workflow.py +597 -0
  243. package/server/skills/android-skill/SKILL.md +82 -0
  244. package/server/skills/assistant-personality/SKILL.md +45 -0
  245. package/server/skills/code-skill/SKILL.md +140 -0
  246. package/server/skills/http-skill/SKILL.md +161 -0
  247. package/server/skills/maps-skill/SKILL.md +170 -0
  248. package/server/skills/memory-skill/SKILL.md +154 -0
  249. package/server/skills/scheduler-skill/SKILL.md +84 -0
  250. package/server/skills/whatsapp-skill/SKILL.md +283 -0
  251. package/server/uv.lock +2916 -0
  252. package/server/whatsapp-rpc/.dockerignore +30 -0
  253. package/server/whatsapp-rpc/Dockerfile +44 -0
  254. package/server/whatsapp-rpc/Dockerfile.web +17 -0
  255. package/server/whatsapp-rpc/README.md +139 -0
  256. package/server/whatsapp-rpc/cli.js +95 -0
  257. package/server/whatsapp-rpc/configs/config.yaml +7 -0
  258. package/server/whatsapp-rpc/docker-compose.yml +35 -0
  259. package/server/whatsapp-rpc/docs/API.md +410 -0
  260. package/server/whatsapp-rpc/go.mod +67 -0
  261. package/server/whatsapp-rpc/go.sum +203 -0
  262. package/server/whatsapp-rpc/package.json +30 -0
  263. package/server/whatsapp-rpc/schema.json +1294 -0
  264. package/server/whatsapp-rpc/scripts/clean.cjs +66 -0
  265. package/server/whatsapp-rpc/scripts/cli.js +162 -0
  266. package/server/whatsapp-rpc/src/go/cmd/server/main.go +91 -0
  267. package/server/whatsapp-rpc/src/go/config/config.go +49 -0
  268. package/server/whatsapp-rpc/src/go/rpc/rpc.go +446 -0
  269. package/server/whatsapp-rpc/src/go/rpc/server.go +112 -0
  270. package/server/whatsapp-rpc/src/go/whatsapp/history.go +166 -0
  271. package/server/whatsapp-rpc/src/go/whatsapp/messages.go +390 -0
  272. package/server/whatsapp-rpc/src/go/whatsapp/service.go +2130 -0
  273. package/server/whatsapp-rpc/src/go/whatsapp/types.go +261 -0
  274. package/server/whatsapp-rpc/src/python/pyproject.toml +15 -0
  275. package/server/whatsapp-rpc/src/python/whatsapp_rpc/__init__.py +4 -0
  276. package/server/whatsapp-rpc/src/python/whatsapp_rpc/client.py +427 -0
  277. package/server/whatsapp-rpc/web/app.py +609 -0
  278. package/server/whatsapp-rpc/web/requirements.txt +6 -0
  279. package/server/whatsapp-rpc/web/rpc_client.py +427 -0
  280. package/server/whatsapp-rpc/web/static/openapi.yaml +59 -0
  281. package/server/whatsapp-rpc/web/templates/base.html +150 -0
  282. package/server/whatsapp-rpc/web/templates/contacts.html +240 -0
  283. package/server/whatsapp-rpc/web/templates/dashboard.html +320 -0
  284. package/server/whatsapp-rpc/web/templates/groups.html +328 -0
  285. package/server/whatsapp-rpc/web/templates/messages.html +465 -0
  286. package/server/whatsapp-rpc/web/templates/messaging.html +681 -0
  287. package/server/whatsapp-rpc/web/templates/send.html +259 -0
  288. package/server/whatsapp-rpc/web/templates/settings.html +459 -0
@@ -0,0 +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 %}