flow-frame-core 0.1.0
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.
- package/README.md +64 -0
- package/dist/Dockerfile +86 -0
- package/dist/GPU_DEPLOYMENT_README.md +324 -0
- package/dist/OPS_AGENT_README.md +174 -0
- package/dist/README-H100-VM.md +192 -0
- package/dist/README-worker-pools.md +231 -0
- package/dist/README.md +8 -0
- package/dist/WEB-ELEMENT-REQUESTS-README.md +302 -0
- package/dist/append.d.ts +3 -0
- package/dist/append.d.ts.map +1 -0
- package/dist/append.js +42 -0
- package/dist/append.js.map +1 -0
- package/dist/audioRoutes.d.ts +2 -0
- package/dist/audioRoutes.d.ts.map +1 -0
- package/dist/audioRoutes.js +97 -0
- package/dist/audioRoutes.js.map +1 -0
- package/dist/augment-parallel.d.ts +6 -0
- package/dist/augment-parallel.d.ts.map +1 -0
- package/dist/augment-parallel.js +128 -0
- package/dist/augment-parallel.js.map +1 -0
- package/dist/augment-worker.d.ts +2 -0
- package/dist/augment-worker.d.ts.map +1 -0
- package/dist/augment-worker.js +100 -0
- package/dist/augment-worker.js.map +1 -0
- package/dist/browerRoutes.d.ts +2 -0
- package/dist/browerRoutes.d.ts.map +1 -0
- package/dist/browerRoutes.js +323 -0
- package/dist/browerRoutes.js.map +1 -0
- package/dist/browser-utils/utils.d.ts +6 -0
- package/dist/browser-utils/utils.d.ts.map +1 -0
- package/dist/browser-utils/utils.js +133 -0
- package/dist/browser-utils/utils.js.map +1 -0
- package/dist/capture_training_data_endpoints.d.ts +158 -0
- package/dist/capture_training_data_endpoints.d.ts.map +1 -0
- package/dist/capture_training_data_endpoints.js +1812 -0
- package/dist/capture_training_data_endpoints.js.map +1 -0
- package/dist/config.json +28 -0
- package/dist/configEndpoints.d.ts +2 -0
- package/dist/configEndpoints.d.ts.map +1 -0
- package/dist/configEndpoints.js +459 -0
- package/dist/configEndpoints.js.map +1 -0
- package/dist/constants.d.ts +109 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +110 -0
- package/dist/constants.js.map +1 -0
- package/dist/docs/workflow_nodes.md +257 -0
- package/dist/download.d.ts +11 -0
- package/dist/download.d.ts.map +1 -0
- package/dist/download.js +31 -0
- package/dist/download.js.map +1 -0
- package/dist/download.py +61 -0
- package/dist/ecosystem.config.json +63 -0
- package/dist/email-body-extractor.d.ts +20 -0
- package/dist/email-body-extractor.d.ts.map +1 -0
- package/dist/email-body-extractor.js +103 -0
- package/dist/email-body-extractor.js.map +1 -0
- package/dist/express_util.d.ts +2 -0
- package/dist/express_util.d.ts.map +1 -0
- package/dist/express_util.js +30 -0
- package/dist/express_util.js.map +1 -0
- package/dist/extension/background.d.ts +2 -0
- package/dist/extension/background.d.ts.map +1 -0
- package/dist/extension/background.js +268 -0
- package/dist/extension/background.js.map +1 -0
- package/dist/extension/manifest.json +19 -0
- package/dist/extensionUtils.d.ts +2 -0
- package/dist/extensionUtils.d.ts.map +1 -0
- package/dist/extensionUtils.js +48 -0
- package/dist/extensionUtils.js.map +1 -0
- package/dist/filter-gmail-poller/README.md +320 -0
- package/dist/filter-gmail-poller/demo.d.ts +2 -0
- package/dist/filter-gmail-poller/demo.d.ts.map +1 -0
- package/dist/filter-gmail-poller/demo.js +79 -0
- package/dist/filter-gmail-poller/demo.js.map +1 -0
- package/dist/filter-gmail-poller/example-existing-app.d.ts +2 -0
- package/dist/filter-gmail-poller/example-existing-app.d.ts.map +1 -0
- package/dist/filter-gmail-poller/example-existing-app.js +72 -0
- package/dist/filter-gmail-poller/example-existing-app.js.map +1 -0
- package/dist/filter-gmail-poller/filter-gmail-poller.d.ts +160 -0
- package/dist/filter-gmail-poller/filter-gmail-poller.d.ts.map +1 -0
- package/dist/filter-gmail-poller/filter-gmail-poller.js +1048 -0
- package/dist/filter-gmail-poller/filter-gmail-poller.js.map +1 -0
- package/dist/filter-gmail-poller/index.d.ts +3 -0
- package/dist/filter-gmail-poller/index.d.ts.map +1 -0
- package/dist/filter-gmail-poller/index.js +18 -0
- package/dist/filter-gmail-poller/index.js.map +1 -0
- package/dist/filter-gmail-poller/manual-test.d.ts +2 -0
- package/dist/filter-gmail-poller/manual-test.d.ts.map +1 -0
- package/dist/filter-gmail-poller/manual-test.js +70 -0
- package/dist/filter-gmail-poller/manual-test.js.map +1 -0
- package/dist/filter-gmail-poller/poller-prompts.d.ts +12 -0
- package/dist/filter-gmail-poller/poller-prompts.d.ts.map +1 -0
- package/dist/filter-gmail-poller/poller-prompts.js +330 -0
- package/dist/filter-gmail-poller/poller-prompts.js.map +1 -0
- package/dist/filter-gmail-poller/test.js +69 -0
- package/dist/flowframe-auto-firebase-adminsdk.json +13 -0
- package/dist/gmail-poller/README-microsoft-email-poller.md +203 -0
- package/dist/gmail-poller/README.md +129 -0
- package/dist/gmail-poller/example.d.ts +5 -0
- package/dist/gmail-poller/example.d.ts.map +1 -0
- package/dist/gmail-poller/example.js +83 -0
- package/dist/gmail-poller/example.js.map +1 -0
- package/dist/gmail-poller/gmail-poller.d.ts +82 -0
- package/dist/gmail-poller/gmail-poller.d.ts.map +1 -0
- package/dist/gmail-poller/gmail-poller.js +455 -0
- package/dist/gmail-poller/gmail-poller.js.map +1 -0
- package/dist/gmail-poller/manual-test.d.ts +2 -0
- package/dist/gmail-poller/manual-test.d.ts.map +1 -0
- package/dist/gmail-poller/manual-test.js +37 -0
- package/dist/gmail-poller/manual-test.js.map +1 -0
- package/dist/gmail-poller/microsoft-email-example.d.ts +8 -0
- package/dist/gmail-poller/microsoft-email-example.d.ts.map +1 -0
- package/dist/gmail-poller/microsoft-email-example.js +58 -0
- package/dist/gmail-poller/microsoft-email-example.js.map +1 -0
- package/dist/gmail-poller/microsoft-email-poller.d.ts +73 -0
- package/dist/gmail-poller/microsoft-email-poller.d.ts.map +1 -0
- package/dist/gmail-poller/microsoft-email-poller.js +346 -0
- package/dist/gmail-poller/microsoft-email-poller.js.map +1 -0
- package/dist/gmail-poller/setup-auth.d.ts +3 -0
- package/dist/gmail-poller/setup-auth.d.ts.map +1 -0
- package/dist/gmail-poller/setup-auth.js +36 -0
- package/dist/gmail-poller/setup-auth.js.map +1 -0
- package/dist/gmail-poller/test.js +36 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/inference/augment_levels.d.ts +2 -0
- package/dist/inference/augment_levels.d.ts.map +1 -0
- package/dist/inference/augment_levels.js +1 -0
- package/dist/inference/augment_levels.js.map +1 -0
- package/dist/inference/capture-overlay.d.ts +13 -0
- package/dist/inference/capture-overlay.d.ts.map +1 -0
- package/dist/inference/capture-overlay.js +355 -0
- package/dist/inference/capture-overlay.js.map +1 -0
- package/dist/inference/capturescreenshot.d.ts +12 -0
- package/dist/inference/capturescreenshot.d.ts.map +1 -0
- package/dist/inference/capturescreenshot.js +157 -0
- package/dist/inference/capturescreenshot.js.map +1 -0
- package/dist/jsonHandler.d.ts +37 -0
- package/dist/jsonHandler.d.ts.map +1 -0
- package/dist/jsonHandler.js +191 -0
- package/dist/jsonHandler.js.map +1 -0
- package/dist/localStorage.json +11 -0
- package/dist/media_data_endpoints.d.ts +2 -0
- package/dist/media_data_endpoints.d.ts.map +1 -0
- package/dist/media_data_endpoints.js +102 -0
- package/dist/media_data_endpoints.js.map +1 -0
- package/dist/operations/blender-ops.d.ts +4 -0
- package/dist/operations/blender-ops.d.ts.map +1 -0
- package/dist/operations/blender-ops.js +55 -0
- package/dist/operations/blender-ops.js.map +1 -0
- package/dist/operations.d.ts +34 -0
- package/dist/operations.d.ts.map +1 -0
- package/dist/operations.js +1514 -0
- package/dist/operations.js.map +1 -0
- package/dist/pdfRoutes.d.ts +2 -0
- package/dist/pdfRoutes.d.ts.map +1 -0
- package/dist/pdfRoutes.js +56 -0
- package/dist/pdfRoutes.js.map +1 -0
- package/dist/peers.d.ts +9 -0
- package/dist/peers.d.ts.map +1 -0
- package/dist/peers.js +70 -0
- package/dist/peers.js.map +1 -0
- package/dist/playparser.d.ts +2 -0
- package/dist/playparser.d.ts.map +1 -0
- package/dist/playparser.js +281 -0
- package/dist/playparser.js.map +1 -0
- package/dist/process.d.ts +4 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.js +375 -0
- package/dist/process.js.map +1 -0
- package/dist/promptRoutes.d.ts +7 -0
- package/dist/promptRoutes.d.ts.map +1 -0
- package/dist/promptRoutes.js +68 -0
- package/dist/promptRoutes.js.map +1 -0
- package/dist/queueManager.d.ts +23 -0
- package/dist/queueManager.d.ts.map +1 -0
- package/dist/queueManager.js +96 -0
- package/dist/queueManager.js.map +1 -0
- package/dist/run-flow.d.ts +8 -0
- package/dist/run-flow.d.ts.map +1 -0
- package/dist/run-flow.js +220 -0
- package/dist/run-flow.js.map +1 -0
- package/dist/scraper.d.ts +2 -0
- package/dist/scraper.d.ts.map +1 -0
- package/dist/scraper.js +75 -0
- package/dist/scraper.js.map +1 -0
- package/dist/scraper_endpoints.d.ts +2 -0
- package/dist/scraper_endpoints.d.ts.map +1 -0
- package/dist/scraper_endpoints.js +40 -0
- package/dist/scraper_endpoints.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +528 -0
- package/dist/server.js.map +1 -0
- package/dist/services/ModelContext.d.ts +7 -0
- package/dist/services/ModelContext.d.ts.map +1 -0
- package/dist/services/ModelContext.js +7 -0
- package/dist/services/ModelContext.js.map +1 -0
- package/dist/services/agenticUiPlanner.d.ts +27 -0
- package/dist/services/agenticUiPlanner.d.ts.map +1 -0
- package/dist/services/agenticUiPlanner.js +161 -0
- package/dist/services/agenticUiPlanner.js.map +1 -0
- package/dist/services/apiKeyService.d.ts +3 -0
- package/dist/services/apiKeyService.d.ts.map +1 -0
- package/dist/services/apiKeyService.js +7 -0
- package/dist/services/apiKeyService.js.map +1 -0
- package/dist/services/audioService.d.ts +10 -0
- package/dist/services/audioService.d.ts.map +1 -0
- package/dist/services/audioService.js +140 -0
- package/dist/services/audioService.js.map +1 -0
- package/dist/services/autoPromptOptimizer.d.ts +44 -0
- package/dist/services/autoPromptOptimizer.d.ts.map +1 -0
- package/dist/services/autoPromptOptimizer.js +344 -0
- package/dist/services/autoPromptOptimizer.js.map +1 -0
- package/dist/services/autoPromptOptimizer.manual-test.d.ts +2 -0
- package/dist/services/autoPromptOptimizer.manual-test.d.ts.map +1 -0
- package/dist/services/autoPromptOptimizer.manual-test.js +27 -0
- package/dist/services/autoPromptOptimizer.manual-test.js.map +1 -0
- package/dist/services/chainExecutor.d.ts +26 -0
- package/dist/services/chainExecutor.d.ts.map +1 -0
- package/dist/services/chainExecutor.js +399 -0
- package/dist/services/chainExecutor.js.map +1 -0
- package/dist/services/classifyImageQuestion.d.ts +55 -0
- package/dist/services/classifyImageQuestion.d.ts.map +1 -0
- package/dist/services/classifyImageQuestion.js +428 -0
- package/dist/services/classifyImageQuestion.js.map +1 -0
- package/dist/services/configuration/executor.d.ts +3 -0
- package/dist/services/configuration/executor.d.ts.map +1 -0
- package/dist/services/configuration/executor.js +795 -0
- package/dist/services/configuration/executor.js.map +1 -0
- package/dist/services/error.d.ts +13 -0
- package/dist/services/error.d.ts.map +1 -0
- package/dist/services/error.js +34 -0
- package/dist/services/error.js.map +1 -0
- package/dist/services/executor.d.ts +11 -0
- package/dist/services/executor.d.ts.map +1 -0
- package/dist/services/executor.js +1587 -0
- package/dist/services/executor.js.map +1 -0
- package/dist/services/extractPdf.d.ts +26 -0
- package/dist/services/extractPdf.d.ts.map +1 -0
- package/dist/services/extractPdf.js +256 -0
- package/dist/services/extractPdf.js.map +1 -0
- package/dist/services/generateJsTransformFromPrompt.d.ts +11 -0
- package/dist/services/generateJsTransformFromPrompt.d.ts.map +1 -0
- package/dist/services/generateJsTransformFromPrompt.js +328 -0
- package/dist/services/generateJsTransformFromPrompt.js.map +1 -0
- package/dist/services/localizeFirebaseMedia.d.ts +20 -0
- package/dist/services/localizeFirebaseMedia.d.ts.map +1 -0
- package/dist/services/localizeFirebaseMedia.js +135 -0
- package/dist/services/localizeFirebaseMedia.js.map +1 -0
- package/dist/services/polyfill_canvas.d.ts +2 -0
- package/dist/services/polyfill_canvas.d.ts.map +1 -0
- package/dist/services/polyfill_canvas.js +19 -0
- package/dist/services/polyfill_canvas.js.map +1 -0
- package/dist/services/promptRoutes.d.ts +7 -0
- package/dist/services/promptRoutes.d.ts.map +1 -0
- package/dist/services/promptRoutes.js +70 -0
- package/dist/services/promptRoutes.js.map +1 -0
- package/dist/services/runPrompt.d.ts +29 -0
- package/dist/services/runPrompt.d.ts.map +1 -0
- package/dist/services/runPrompt.js +232 -0
- package/dist/services/runPrompt.js.map +1 -0
- package/dist/services/schemaInference.d.ts +2 -0
- package/dist/services/schemaInference.d.ts.map +1 -0
- package/dist/services/schemaInference.js +17 -0
- package/dist/services/schemaInference.js.map +1 -0
- package/dist/services/self-learning/api.d.ts +2 -0
- package/dist/services/self-learning/api.d.ts.map +1 -0
- package/dist/services/self-learning/api.js +84 -0
- package/dist/services/self-learning/api.js.map +1 -0
- package/dist/services/self-learning/autolearn.d.ts +23 -0
- package/dist/services/self-learning/autolearn.d.ts.map +1 -0
- package/dist/services/self-learning/autolearn.js +308 -0
- package/dist/services/self-learning/autolearn.js.map +1 -0
- package/dist/services/self-learning/discover.d.ts +11 -0
- package/dist/services/self-learning/discover.d.ts.map +1 -0
- package/dist/services/self-learning/discover.js +446 -0
- package/dist/services/self-learning/discover.js.map +1 -0
- package/dist/services/self-learning/image.d.ts +10 -0
- package/dist/services/self-learning/image.d.ts.map +1 -0
- package/dist/services/self-learning/image.js +38 -0
- package/dist/services/self-learning/image.js.map +1 -0
- package/dist/services/self-learning/injest.d.ts +25 -0
- package/dist/services/self-learning/injest.d.ts.map +1 -0
- package/dist/services/self-learning/injest.js +110 -0
- package/dist/services/self-learning/injest.js.map +1 -0
- package/dist/services/self-learning/learn.d.ts +2 -0
- package/dist/services/self-learning/learn.d.ts.map +1 -0
- package/dist/services/self-learning/learn.js +145 -0
- package/dist/services/self-learning/learn.js.map +1 -0
- package/dist/services/self-learning/matcher.d.ts +2 -0
- package/dist/services/self-learning/matcher.d.ts.map +1 -0
- package/dist/services/self-learning/matcher.js +38 -0
- package/dist/services/self-learning/matcher.js.map +1 -0
- package/dist/services/self-learning/openai.d.ts +8 -0
- package/dist/services/self-learning/openai.d.ts.map +1 -0
- package/dist/services/self-learning/openai.js +97 -0
- package/dist/services/self-learning/openai.js.map +1 -0
- package/dist/services/self-learning/phash.d.ts +5 -0
- package/dist/services/self-learning/phash.d.ts.map +1 -0
- package/dist/services/self-learning/phash.js +68 -0
- package/dist/services/self-learning/phash.js.map +1 -0
- package/dist/services/self-learning/recognize.d.ts +17 -0
- package/dist/services/self-learning/recognize.d.ts.map +1 -0
- package/dist/services/self-learning/recognize.js +116 -0
- package/dist/services/self-learning/recognize.js.map +1 -0
- package/dist/services/self-learning/record_transition.d.ts +8 -0
- package/dist/services/self-learning/record_transition.d.ts.map +1 -0
- package/dist/services/self-learning/record_transition.js +20 -0
- package/dist/services/self-learning/record_transition.js.map +1 -0
- package/dist/services/self-learning/registry.d.ts +4 -0
- package/dist/services/self-learning/registry.d.ts.map +1 -0
- package/dist/services/self-learning/registry.js +19 -0
- package/dist/services/self-learning/registry.js.map +1 -0
- package/dist/services/self-learning/schema.d.ts +114 -0
- package/dist/services/self-learning/schema.d.ts.map +1 -0
- package/dist/services/self-learning/schema.js +70 -0
- package/dist/services/self-learning/schema.js.map +1 -0
- package/dist/services/self-learning/schemaStrictify.d.ts +2 -0
- package/dist/services/self-learning/schemaStrictify.d.ts.map +1 -0
- package/dist/services/self-learning/schemaStrictify.js +34 -0
- package/dist/services/self-learning/schemaStrictify.js.map +1 -0
- package/dist/services/self-learning/transition_graph.d.ts +6 -0
- package/dist/services/self-learning/transition_graph.d.ts.map +1 -0
- package/dist/services/self-learning/transition_graph.js +83 -0
- package/dist/services/self-learning/transition_graph.js.map +1 -0
- package/dist/services/self-learning/transition_log.d.ts +3 -0
- package/dist/services/self-learning/transition_log.d.ts.map +1 -0
- package/dist/services/self-learning/transition_log.js +42 -0
- package/dist/services/self-learning/transition_log.js.map +1 -0
- package/dist/services/self-learning/util.d.ts +3 -0
- package/dist/services/self-learning/util.d.ts.map +1 -0
- package/dist/services/self-learning/util.js +11 -0
- package/dist/services/self-learning/util.js.map +1 -0
- package/dist/services/stepByStepAiPlanner.d.ts +39 -0
- package/dist/services/stepByStepAiPlanner.d.ts.map +1 -0
- package/dist/services/stepByStepAiPlanner.js +379 -0
- package/dist/services/stepByStepAiPlanner.js.map +1 -0
- package/dist/services/test-genjs.js +39 -0
- package/dist/services/test-genjs.manual-test.d.ts +2 -0
- package/dist/services/test-genjs.manual-test.d.ts.map +1 -0
- package/dist/services/test-genjs.manual-test.js +40 -0
- package/dist/services/test-genjs.manual-test.js.map +1 -0
- package/dist/services/uiMapPathFinder.d.ts +13 -0
- package/dist/services/uiMapPathFinder.d.ts.map +1 -0
- package/dist/services/uiMapPathFinder.js +79 -0
- package/dist/services/uiMapPathFinder.js.map +1 -0
- package/dist/services/uiMapService.d.ts +26 -0
- package/dist/services/uiMapService.d.ts.map +1 -0
- package/dist/services/uiMapService.js +275 -0
- package/dist/services/uiMapService.js.map +1 -0
- package/dist/services/uiPlanner.d.ts +54 -0
- package/dist/services/uiPlanner.d.ts.map +1 -0
- package/dist/services/uiPlanner.js +558 -0
- package/dist/services/uiPlanner.js.map +1 -0
- package/dist/services/utilityFunctions.d.ts +80 -0
- package/dist/services/utilityFunctions.d.ts.map +1 -0
- package/dist/services/utilityFunctions.js +352 -0
- package/dist/services/utilityFunctions.js.map +1 -0
- package/dist/services/variableGenerator.d.ts +39 -0
- package/dist/services/variableGenerator.d.ts.map +1 -0
- package/dist/services/variableGenerator.js +157 -0
- package/dist/services/variableGenerator.js.map +1 -0
- package/dist/services/workflow/build-workflow.d.ts +49 -0
- package/dist/services/workflow/build-workflow.d.ts.map +1 -0
- package/dist/services/workflow/build-workflow.js +119 -0
- package/dist/services/workflow/build-workflow.js.map +1 -0
- package/dist/standardRoutes.d.ts +2 -0
- package/dist/standardRoutes.d.ts.map +1 -0
- package/dist/standardRoutes.js +1495 -0
- package/dist/standardRoutes.js.map +1 -0
- package/dist/stepWorkflowRoutes.d.ts +2 -0
- package/dist/stepWorkflowRoutes.d.ts.map +1 -0
- package/dist/stepWorkflowRoutes.js +1007 -0
- package/dist/stepWorkflowRoutes.js.map +1 -0
- package/dist/storage.d.ts +19 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.docker.json +61 -0
- package/dist/storage.js +131 -0
- package/dist/storage.js.map +1 -0
- package/dist/storage.json +78 -0
- package/dist/storage_cache/boxes.json +48 -0
- package/dist/storage_cache/suno_state.json +3 -0
- package/dist/suno_download.d.ts +11 -0
- package/dist/suno_download.d.ts.map +1 -0
- package/dist/suno_download.js +33 -0
- package/dist/suno_download.js.map +1 -0
- package/dist/suno_download.py +119 -0
- package/dist/test-web-element-requests.d.ts +6 -0
- package/dist/test-web-element-requests.d.ts.map +1 -0
- package/dist/test-web-element-requests.js +114 -0
- package/dist/test-web-element-requests.js.map +1 -0
- package/dist/test_pdf_render.d.ts +2 -0
- package/dist/test_pdf_render.d.ts.map +1 -0
- package/dist/test_pdf_render.js +50 -0
- package/dist/test_pdf_render.js.map +1 -0
- package/dist/training_data_viewer_endpoints.d.ts +2 -0
- package/dist/training_data_viewer_endpoints.d.ts.map +1 -0
- package/dist/training_data_viewer_endpoints.js +141 -0
- package/dist/training_data_viewer_endpoints.js.map +1 -0
- package/dist/utils.d.ts +353 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +1517 -0
- package/dist/utils.js.map +1 -0
- package/dist/vm-h100.env.template +55 -0
- package/dist/web-element-requests.d.ts +102 -0
- package/dist/web-element-requests.d.ts.map +1 -0
- package/dist/web-element-requests.js +278 -0
- package/dist/web-element-requests.js.map +1 -0
- package/dist/workflowRoutes.d.ts +2 -0
- package/dist/workflowRoutes.d.ts.map +1 -0
- package/dist/workflowRoutes.js +441 -0
- package/dist/workflowRoutes.js.map +1 -0
- package/package.json +109 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# Filter Gmail Poller
|
|
2
|
+
|
|
3
|
+
A specialized Gmail poller that filters emails by subject prefix, maintains an in-memory cache of recent emails, and provides a REST API for accessing filtered emails.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎯 **Subject Prefix Filtering** - Only processes emails with specific subject prefixes
|
|
8
|
+
- 💾 **In-Memory Cache** - Keeps the last N emails in memory for fast access
|
|
9
|
+
- 🌐 **REST API** - HTTP endpoints to retrieve filtered emails
|
|
10
|
+
- 🔄 **Continuous Polling** - Regularly checks for new emails matching the filter
|
|
11
|
+
- 📊 **Statistics & Health Checks** - API endpoints for monitoring
|
|
12
|
+
|
|
13
|
+
## Configuration
|
|
14
|
+
|
|
15
|
+
Edit `config.json` to customize behavior:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"gmail": {
|
|
20
|
+
"credentialsPath": "../gmail-poller/credentials.json",
|
|
21
|
+
"scopes": ["https://www.googleapis.com/auth/gmail.readonly"]
|
|
22
|
+
},
|
|
23
|
+
"filter": {
|
|
24
|
+
"subjectPrefix": "[FILTER]",
|
|
25
|
+
"maxEmailsInMemory": 50,
|
|
26
|
+
"pollingIntervalMs": 30000
|
|
27
|
+
},
|
|
28
|
+
"api": {
|
|
29
|
+
"port": 3001,
|
|
30
|
+
"host": "localhost"
|
|
31
|
+
},
|
|
32
|
+
"logging": {
|
|
33
|
+
"level": "info",
|
|
34
|
+
"enableConsole": true
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Setup
|
|
40
|
+
|
|
41
|
+
### 1. Install Dependencies
|
|
42
|
+
|
|
43
|
+
The dependencies are already installed in the main midjourney project.
|
|
44
|
+
|
|
45
|
+
### 2. Set up Gmail Authentication
|
|
46
|
+
|
|
47
|
+
Make sure Gmail credentials are set up in the parent `gmail-poller` folder:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cd ../gmail-poller
|
|
51
|
+
node setup-auth.js
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 3. Configure Filter
|
|
55
|
+
|
|
56
|
+
Edit `config.json` to set your desired subject prefix and other settings.
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
### Standalone Server
|
|
61
|
+
|
|
62
|
+
Run as a standalone server (creates its own Express app):
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
node index.js
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Integration with Existing Express App
|
|
69
|
+
|
|
70
|
+
Integrate with your existing Express application:
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
import express from 'express';
|
|
74
|
+
import { FilterGmailPoller } from './path/to/filter-gmail-poller/index.js';
|
|
75
|
+
|
|
76
|
+
const app = express();
|
|
77
|
+
// ... your existing middleware and routes ...
|
|
78
|
+
|
|
79
|
+
const poller = new FilterGmailPoller();
|
|
80
|
+
|
|
81
|
+
// Initialize (authenticates once, starts API server)
|
|
82
|
+
await poller.initialize(app);
|
|
83
|
+
|
|
84
|
+
// Start polling when ready
|
|
85
|
+
await poller.startPolling();
|
|
86
|
+
|
|
87
|
+
// Stop polling when needed
|
|
88
|
+
poller.stopPolling();
|
|
89
|
+
|
|
90
|
+
// Start polling again later
|
|
91
|
+
await poller.startPolling();
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Programmatic Control
|
|
95
|
+
|
|
96
|
+
Control polling programmatically:
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
import { FilterGmailPoller } from './filter-gmail-poller/index.js';
|
|
100
|
+
|
|
101
|
+
const poller = new FilterGmailPoller();
|
|
102
|
+
|
|
103
|
+
// Initialize (authenticates once)
|
|
104
|
+
await poller.initialize();
|
|
105
|
+
|
|
106
|
+
// Check status
|
|
107
|
+
console.log('Is polling:', poller.pollingInterval !== null);
|
|
108
|
+
console.log('Is authenticated:', poller.isAuthenticated);
|
|
109
|
+
|
|
110
|
+
// Start/stop polling as needed
|
|
111
|
+
await poller.startPolling();
|
|
112
|
+
poller.stopPolling();
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
app.listen(3000, () => {
|
|
116
|
+
console.log('Server running with Gmail poller integrated');
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
See `example-existing-app.js` for a complete integration example.
|
|
121
|
+
|
|
122
|
+
### API Endpoints
|
|
123
|
+
|
|
124
|
+
#### Get Filtered Emails
|
|
125
|
+
```
|
|
126
|
+
GET /api/emails
|
|
127
|
+
GET /api/emails?limit=10
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Returns the most recent filtered emails.
|
|
131
|
+
|
|
132
|
+
#### Get Specific Email
|
|
133
|
+
```
|
|
134
|
+
GET /api/emails/{emailId}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Returns a specific email by ID.
|
|
138
|
+
|
|
139
|
+
#### Get Statistics
|
|
140
|
+
```
|
|
141
|
+
GET /api/stats
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Returns poller statistics and configuration.
|
|
145
|
+
|
|
146
|
+
#### Get Configuration
|
|
147
|
+
```
|
|
148
|
+
GET /api/config
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Returns the current configuration settings.
|
|
152
|
+
|
|
153
|
+
#### Start Polling
|
|
154
|
+
```
|
|
155
|
+
POST /api/polling/start
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Starts the email polling process. If this is the first time polling is started, Gmail authentication will occur automatically. Subsequent calls will reuse the existing authentication.
|
|
159
|
+
|
|
160
|
+
#### Stop Polling
|
|
161
|
+
```
|
|
162
|
+
POST /api/polling/stop
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Stops the email polling process.
|
|
166
|
+
|
|
167
|
+
#### Get Polling Status
|
|
168
|
+
```
|
|
169
|
+
GET /api/polling/status
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Returns the current polling status and authentication state.
|
|
173
|
+
|
|
174
|
+
#### Check If Polling
|
|
175
|
+
```
|
|
176
|
+
GET /api/polling
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Returns a simple boolean indicating if the poller is currently active.
|
|
180
|
+
|
|
181
|
+
#### Update Filter Configuration
|
|
182
|
+
```
|
|
183
|
+
PUT /api/config/filter
|
|
184
|
+
Content-Type: application/json
|
|
185
|
+
|
|
186
|
+
{
|
|
187
|
+
"subjectPrefix": "[NEW_PREFIX]",
|
|
188
|
+
"maxEmailsInMemory": 100,
|
|
189
|
+
"pollingIntervalMs": 60000
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Updates the filter configuration and saves it to the config file. Only provided fields will be updated.
|
|
194
|
+
|
|
195
|
+
## Example API Usage
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
// Initialize poller (no authentication yet)
|
|
199
|
+
const poller = new FilterGmailPoller();
|
|
200
|
+
await poller.initialize();
|
|
201
|
+
|
|
202
|
+
// First call to start polling triggers authentication
|
|
203
|
+
await fetch('http://localhost:3001/api/polling/start', { method: 'POST' });
|
|
204
|
+
// Authentication happens here automatically
|
|
205
|
+
|
|
206
|
+
// Check status
|
|
207
|
+
const statusResponse = await fetch('http://localhost:3001/api/polling/status');
|
|
208
|
+
const status = await statusResponse.json();
|
|
209
|
+
console.log('Is authenticated:', status.isAuthenticated);
|
|
210
|
+
console.log('Is polling:', status.isPolling);
|
|
211
|
+
|
|
212
|
+
// Check if polling (simple boolean)
|
|
213
|
+
const pollingResponse = await fetch('http://localhost:3001/api/polling');
|
|
214
|
+
const pollingStatus = await pollingResponse.json();
|
|
215
|
+
console.log('Currently polling:', pollingStatus.isPolling);
|
|
216
|
+
|
|
217
|
+
// Stop polling
|
|
218
|
+
await fetch('http://localhost:3001/api/polling/stop', { method: 'POST' });
|
|
219
|
+
|
|
220
|
+
// Start polling again (no re-authentication)
|
|
221
|
+
await fetch('http://localhost:3001/api/polling/start', { method: 'POST' });
|
|
222
|
+
|
|
223
|
+
// Get recent filtered emails
|
|
224
|
+
const emailsResponse = await fetch('http://localhost:3001/api/emails');
|
|
225
|
+
const emailsData = await emailsResponse.json();
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Files
|
|
229
|
+
|
|
230
|
+
- `config.json` - Configuration file
|
|
231
|
+
- `filter-gmail-poller.js` - Main poller class
|
|
232
|
+
- `index.js` - Entry point for standalone usage
|
|
233
|
+
- `test.js` - Test suite
|
|
234
|
+
- `demo.js` - Interactive demo
|
|
235
|
+
- `example-existing-app.js` - Example of integration with existing Express app
|
|
236
|
+
- `README.md` - This documentation
|
|
237
|
+
|
|
238
|
+
1. **Authentication**: Uses OAuth2 credentials from the parent `gmail-poller` folder
|
|
239
|
+
2. **Polling**: Regularly queries Gmail for recent emails (last 24 hours)
|
|
240
|
+
3. **Filtering**: Checks each email's subject against the configured prefix
|
|
241
|
+
4. **Caching**: Stores matching emails in memory (most recent first)
|
|
242
|
+
5. **API**: Provides HTTP endpoints to access the cached emails
|
|
243
|
+
|
|
244
|
+
## Authentication & Polling Control
|
|
245
|
+
|
|
246
|
+
### Authentication
|
|
247
|
+
- **Lazy authentication**: Gmail authentication occurs only when polling starts for the first time
|
|
248
|
+
- **One-time process**: Authentication happens once and persists across polling start/stop cycles
|
|
249
|
+
- **Delayed initialization**: No authentication overhead until polling is actually needed
|
|
250
|
+
- **Token management**: OAuth2 tokens are managed automatically by the Google APIs client
|
|
251
|
+
|
|
252
|
+
### Polling Control
|
|
253
|
+
- **Independent polling**: Start and stop email polling without affecting authentication
|
|
254
|
+
- **Automatic auth**: First call to `startPolling()` triggers authentication if not already authenticated
|
|
255
|
+
- **API control**: Use REST endpoints to control polling remotely
|
|
256
|
+
- **Programmatic control**: Call `startPolling()` and `stopPolling()` methods directly
|
|
257
|
+
- **Status monitoring**: Check polling status via `/api/polling/status` endpoint
|
|
258
|
+
|
|
259
|
+
### Usage Pattern
|
|
260
|
+
```javascript
|
|
261
|
+
const poller = new FilterGmailPoller();
|
|
262
|
+
|
|
263
|
+
// Initialize (no authentication yet)
|
|
264
|
+
await poller.initialize();
|
|
265
|
+
|
|
266
|
+
// First call to startPolling triggers authentication
|
|
267
|
+
await poller.startPolling(); // ← Authentication happens here
|
|
268
|
+
|
|
269
|
+
// Subsequent calls don't re-authenticate
|
|
270
|
+
poller.stopPolling(); // Stop polling
|
|
271
|
+
await poller.startPolling(); // Start again (no re-auth needed)
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Configuration Updates
|
|
275
|
+
|
|
276
|
+
### Programmatic Updates
|
|
277
|
+
|
|
278
|
+
You can update filter configuration programmatically:
|
|
279
|
+
|
|
280
|
+
```javascript
|
|
281
|
+
// Update subject prefix
|
|
282
|
+
await poller.updateFilterConfig({
|
|
283
|
+
subjectPrefix: '[IMPORTANT]'
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Update multiple settings
|
|
287
|
+
await poller.updateFilterConfig({
|
|
288
|
+
subjectPrefix: '[ALERT]',
|
|
289
|
+
maxEmailsInMemory: 100,
|
|
290
|
+
pollingIntervalMs: 60000
|
|
291
|
+
});
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### API Updates
|
|
295
|
+
|
|
296
|
+
Update configuration via REST API:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
curl -X PUT http://localhost:3001/api/config/filter \
|
|
300
|
+
-H "Content-Type: application/json" \
|
|
301
|
+
-d '{
|
|
302
|
+
"subjectPrefix": "[NEW_FILTER]",
|
|
303
|
+
"maxEmailsInMemory": 75,
|
|
304
|
+
"pollingIntervalMs": 45000
|
|
305
|
+
}'
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Automatic Saving
|
|
309
|
+
|
|
310
|
+
All configuration updates are automatically saved to `config.json` and persist across restarts.
|
|
311
|
+
|
|
312
|
+
## Dependencies
|
|
313
|
+
|
|
314
|
+
- `express` - API server
|
|
315
|
+
- `cors` - Cross-origin requests
|
|
316
|
+
- Gmail API credentials (from parent folder)
|
|
317
|
+
|
|
318
|
+
## License
|
|
319
|
+
|
|
320
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/filter-gmail-poller/demo.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import FilterGmailPoller from './filter-gmail-poller.js';
|
|
2
|
+
async function demo() {
|
|
3
|
+
console.log('🎯 Filter Gmail Poller Demo');
|
|
4
|
+
console.log('===========================\n');
|
|
5
|
+
const poller = new FilterGmailPoller();
|
|
6
|
+
try {
|
|
7
|
+
// Load config and authenticate
|
|
8
|
+
await poller.loadConfig();
|
|
9
|
+
await poller.authenticate();
|
|
10
|
+
console.log('📧 Current filter configuration:');
|
|
11
|
+
console.log(` Subject prefix: "${poller.config.filter.subjectPrefix}"`);
|
|
12
|
+
console.log(` Max emails: ${poller.config.filter.maxEmailsInMemory}`);
|
|
13
|
+
console.log(` Poll interval: ${poller.config.filter.pollingIntervalMs}ms\n`);
|
|
14
|
+
// Start API server
|
|
15
|
+
await poller.startAPIServer();
|
|
16
|
+
// Do an initial poll
|
|
17
|
+
console.log('🔍 Performing initial email scan...');
|
|
18
|
+
await poller.pollAndFilter();
|
|
19
|
+
const emails = poller.getEmails();
|
|
20
|
+
console.log(`📬 Found ${emails.length} emails matching filter\n`);
|
|
21
|
+
// Show sample API calls
|
|
22
|
+
console.log('🌐 API Demo:');
|
|
23
|
+
console.log('-----------');
|
|
24
|
+
// Health check
|
|
25
|
+
const healthResponse = await fetch(`http://localhost:3001/api/health`);
|
|
26
|
+
const health = await healthResponse.json();
|
|
27
|
+
console.log('✅ Health check:', health.success ? 'OK' : 'FAIL');
|
|
28
|
+
// Get stats
|
|
29
|
+
const statsResponse = await fetch(`http://localhost:3001/api/stats`);
|
|
30
|
+
const stats = await statsResponse.json();
|
|
31
|
+
console.log('📊 Stats:', JSON.stringify(stats.stats, null, 2));
|
|
32
|
+
// Get emails
|
|
33
|
+
const emailsResponse = await fetch(`http://localhost:3001/api/emails?limit=5`);
|
|
34
|
+
const emailsData = await emailsResponse.json();
|
|
35
|
+
console.log(`📧 Emails API returned ${emailsData.count} emails`);
|
|
36
|
+
if (emailsData.emails.length > 0) {
|
|
37
|
+
console.log('\n📋 Sample filtered email:');
|
|
38
|
+
const sampleEmail = emailsData.emails[0];
|
|
39
|
+
console.log(` Subject: ${sampleEmail.subject}`);
|
|
40
|
+
console.log(` Filtered at: ${sampleEmail.filteredAt}`);
|
|
41
|
+
}
|
|
42
|
+
// Test configuration update
|
|
43
|
+
console.log('\n⚙️ Testing configuration update...');
|
|
44
|
+
const configUpdate = await fetch('http://localhost:3001/api/config/filter', {
|
|
45
|
+
method: 'PUT',
|
|
46
|
+
headers: {
|
|
47
|
+
'Content-Type': 'application/json',
|
|
48
|
+
},
|
|
49
|
+
body: JSON.stringify({
|
|
50
|
+
subjectPrefix: '[UPDATED]',
|
|
51
|
+
maxEmailsInMemory: 25,
|
|
52
|
+
pollingIntervalMs: 45000
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
const configResult = await configUpdate.json();
|
|
56
|
+
if (configResult.success) {
|
|
57
|
+
console.log('✅ Configuration updated via API:');
|
|
58
|
+
console.log(` New prefix: "${configResult.newConfig.subjectPrefix}"`);
|
|
59
|
+
console.log(` New max emails: ${configResult.newConfig.maxEmailsInMemory}`);
|
|
60
|
+
console.log(` New interval: ${configResult.newConfig.pollingIntervalMs}ms`);
|
|
61
|
+
}
|
|
62
|
+
console.log('\n🎉 Demo completed successfully!');
|
|
63
|
+
console.log('\n💡 To use with real emails:');
|
|
64
|
+
console.log(' 1. Send emails with subject starting with "[FILTER]"');
|
|
65
|
+
console.log(' 2. Run: node index.js');
|
|
66
|
+
console.log(' 3. Access API at http://localhost:3001');
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.error('❌ Demo failed:', error);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
// Clean up
|
|
73
|
+
poller.stopAPIServer();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
77
|
+
demo();
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=demo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo.js","sourceRoot":"","sources":["../../src/filter-gmail-poller/demo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example-existing-app.d.ts","sourceRoot":"","sources":["../../src/filter-gmail-poller/example-existing-app.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import cors from 'cors';
|
|
3
|
+
import { FilterGmailPoller } from './index.js';
|
|
4
|
+
async function exampleWithExistingApp() {
|
|
5
|
+
console.log('🚀 Example: Filter Gmail Poller with Existing Express App');
|
|
6
|
+
console.log('==================================================\n');
|
|
7
|
+
// Create your existing Express app
|
|
8
|
+
const app = express();
|
|
9
|
+
app.use(cors());
|
|
10
|
+
app.use(express.json());
|
|
11
|
+
// Add your own routes
|
|
12
|
+
app.get('/', (req, res) => {
|
|
13
|
+
res.json({
|
|
14
|
+
message: 'Main application API',
|
|
15
|
+
endpoints: [
|
|
16
|
+
'GET / - This message',
|
|
17
|
+
'GET /api/emails - Gmail poller emails',
|
|
18
|
+
'GET /api/stats - Gmail poller stats',
|
|
19
|
+
'PUT /api/config/filter - Update Gmail poller config'
|
|
20
|
+
]
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
app.get('/custom-route', (req, res) => {
|
|
24
|
+
res.json({
|
|
25
|
+
message: 'This is a custom route in your main app',
|
|
26
|
+
timestamp: new Date().toISOString()
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
// Create and initialize the Gmail poller with your existing app
|
|
30
|
+
const poller = new FilterGmailPoller();
|
|
31
|
+
try {
|
|
32
|
+
// Initialize the poller (sets up API routes, no authentication yet)
|
|
33
|
+
await poller.initialize(app);
|
|
34
|
+
// Start polling (authentication will occur here on first start)
|
|
35
|
+
await poller.startPolling();
|
|
36
|
+
// Example: Stop polling after 30 seconds, then restart after 10 seconds
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
console.log('\n⏹️ Stopping polling for demonstration...');
|
|
39
|
+
poller.stopPolling();
|
|
40
|
+
}, 30000);
|
|
41
|
+
setTimeout(async () => {
|
|
42
|
+
console.log('\n🚀 Restarting polling...');
|
|
43
|
+
await poller.startPolling();
|
|
44
|
+
}, 40000);
|
|
45
|
+
// Start your main server
|
|
46
|
+
const PORT = 3001;
|
|
47
|
+
app.listen(PORT, () => {
|
|
48
|
+
console.log(`\n🌐 Main application server started on http://localhost:${PORT}`);
|
|
49
|
+
console.log('📊 All endpoints available:');
|
|
50
|
+
console.log(' Main App:');
|
|
51
|
+
console.log(` GET http://localhost:${PORT}/ - Main app info`);
|
|
52
|
+
console.log(` GET http://localhost:${PORT}/custom-route - Custom route`);
|
|
53
|
+
console.log(' Gmail Poller:');
|
|
54
|
+
console.log(` GET http://localhost:${PORT}/api/emails - Filtered emails`);
|
|
55
|
+
console.log(` GET http://localhost:${PORT}/api/stats - Poller stats`);
|
|
56
|
+
console.log(` GET http://localhost:${PORT}/api/config - Current config`);
|
|
57
|
+
console.log(` GET http://localhost:${PORT}/api/polling/status - Polling status`);
|
|
58
|
+
console.log(` POST http://localhost:${PORT}/api/polling/start - Start polling`);
|
|
59
|
+
console.log(` POST http://localhost:${PORT}/api/polling/stop - Stop polling`);
|
|
60
|
+
console.log(` PUT http://localhost:${PORT}/api/config/filter - Update config`);
|
|
61
|
+
console.log('\n💡 Polling will stop after 30s and restart after 40s for demo');
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error('❌ Failed to start:', error);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
70
|
+
exampleWithExistingApp();
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=example-existing-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example-existing-app.js","sourceRoot":"","sources":["../../src/filter-gmail-poller/example-existing-app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
declare class FilterGmailPoller {
|
|
2
|
+
static instance: any;
|
|
3
|
+
constructor(configPath?: string);
|
|
4
|
+
/**
|
|
5
|
+
* Load configuration from JSON file
|
|
6
|
+
*/
|
|
7
|
+
loadConfig(): Promise<any>;
|
|
8
|
+
/**
|
|
9
|
+
* Authenticate with Gmail API
|
|
10
|
+
*/
|
|
11
|
+
authenticate(): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Check if email subject starts with the configured prefix
|
|
14
|
+
*/
|
|
15
|
+
matchesFilter(email: any): any;
|
|
16
|
+
/**
|
|
17
|
+
* Extract and decode email body from Gmail message
|
|
18
|
+
* @param {Object} email - Gmail message object
|
|
19
|
+
* @param {string} [preferredType='text/plain'] - Preferred MIME type ('text/plain' or 'text/html')
|
|
20
|
+
* @returns {string} - Decoded email body as string
|
|
21
|
+
*/
|
|
22
|
+
extractEmailBody(email: any, preferredType?: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Extract subject from email headers
|
|
25
|
+
*/
|
|
26
|
+
getEmailSubject(email: any): any;
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a Gmail label ID by its display name
|
|
29
|
+
*/
|
|
30
|
+
getLabelIdByName(labelName: any): Promise<any>;
|
|
31
|
+
/**
|
|
32
|
+
* Determine which label IDs to use when querying Gmail
|
|
33
|
+
*/
|
|
34
|
+
getFilterLabelIds(): Promise<any[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Get all labels
|
|
37
|
+
*/
|
|
38
|
+
getLabels(): Promise<any>;
|
|
39
|
+
/**
|
|
40
|
+
* Create new label/folder
|
|
41
|
+
*/
|
|
42
|
+
createLabel(labelName: any): Promise<any>;
|
|
43
|
+
/**
|
|
44
|
+
* Find or create label
|
|
45
|
+
*/
|
|
46
|
+
findOrCreateLabel(labelName: any): Promise<any>;
|
|
47
|
+
/**
|
|
48
|
+
* Get human-like delay
|
|
49
|
+
*/
|
|
50
|
+
getHumanDelay(): number;
|
|
51
|
+
/**
|
|
52
|
+
* Get full email details
|
|
53
|
+
*/
|
|
54
|
+
getEmailDetails(messageId: any): Promise<any>;
|
|
55
|
+
/**
|
|
56
|
+
* Move email to different label/folder
|
|
57
|
+
*/
|
|
58
|
+
moveEmail(messageId: any, targetLabelId: any, removeLabelIds?: any[]): Promise<any>;
|
|
59
|
+
/**
|
|
60
|
+
* Ensure a folder/label exists by name
|
|
61
|
+
* Returns the label object (existing or newly created)
|
|
62
|
+
*/
|
|
63
|
+
ensureFolderExists(folderName: any): Promise<any>;
|
|
64
|
+
/**
|
|
65
|
+
* Move an email to a specific folder by name
|
|
66
|
+
* Automatically ensures the folder exists before moving
|
|
67
|
+
*/
|
|
68
|
+
moveEmailToFolder(messageId: any, folderName: any, removeFromInbox?: boolean): Promise<any>;
|
|
69
|
+
/**
|
|
70
|
+
* Step through emails manually with pagination
|
|
71
|
+
* Ensures authentication and allows controlled processing of emails
|
|
72
|
+
* Honors the configured filter (subject prefix)
|
|
73
|
+
*/
|
|
74
|
+
stepThroughEmails(options?: {}): Promise<{
|
|
75
|
+
messages: any;
|
|
76
|
+
nextPageToken: any;
|
|
77
|
+
hasMore: boolean;
|
|
78
|
+
totalMessages: any;
|
|
79
|
+
filteredMessages: number;
|
|
80
|
+
subjectPrefix: any;
|
|
81
|
+
}>;
|
|
82
|
+
/**
|
|
83
|
+
* Add email to memory (keeping only the most recent N emails)
|
|
84
|
+
*/
|
|
85
|
+
addEmailToMemory(email: any): void;
|
|
86
|
+
/**
|
|
87
|
+
* Poll for new emails and filter them
|
|
88
|
+
*/
|
|
89
|
+
pollAndFilter(): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Start the polling process
|
|
92
|
+
*/
|
|
93
|
+
startPolling(): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Stop the polling process
|
|
96
|
+
*/
|
|
97
|
+
stopPolling(): void;
|
|
98
|
+
/**
|
|
99
|
+
* Start the API server or integrate with existing Express app
|
|
100
|
+
* @param {Object} [existingApp] - Optional existing Express app to integrate with
|
|
101
|
+
*/
|
|
102
|
+
startAPIServer(existingApp?: any): Promise<unknown>;
|
|
103
|
+
/**
|
|
104
|
+
* Stop the API server (only if we created it)
|
|
105
|
+
*/
|
|
106
|
+
stopAPIServer(): void;
|
|
107
|
+
/**
|
|
108
|
+
* Authenticate with Gmail API (only once)
|
|
109
|
+
*/
|
|
110
|
+
authenticateOnce(): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Initialize and start everything (without auto-starting polling)
|
|
113
|
+
* @param {Object} [existingApp] - Optional existing Express app to integrate with
|
|
114
|
+
*/
|
|
115
|
+
initialize(existingApp?: any): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Initialize and start everything (legacy method - now calls initialize)
|
|
118
|
+
* @param {Object} [existingApp] - Optional existing Express app to integrate with
|
|
119
|
+
*/
|
|
120
|
+
start(existingApp?: any): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Get current emails (for testing/debugging)
|
|
123
|
+
*/
|
|
124
|
+
getEmails(): any;
|
|
125
|
+
/**
|
|
126
|
+
* Update filter configuration parameters
|
|
127
|
+
* @param {Object} updates - Configuration updates
|
|
128
|
+
* @param {string} [updates.subjectPrefix] - New subject prefix
|
|
129
|
+
* @param {number} [updates.maxEmailsInMemory] - New maximum emails in memory
|
|
130
|
+
* @param {number} [updates.pollingIntervalMs] - New polling interval in milliseconds
|
|
131
|
+
*/
|
|
132
|
+
updateFilterConfig(updates: any): Promise<{
|
|
133
|
+
success: boolean;
|
|
134
|
+
updated: boolean;
|
|
135
|
+
pollingRestarted: boolean;
|
|
136
|
+
newConfig: any;
|
|
137
|
+
error?: undefined;
|
|
138
|
+
} | {
|
|
139
|
+
success: boolean;
|
|
140
|
+
error: any;
|
|
141
|
+
updated?: undefined;
|
|
142
|
+
pollingRestarted?: undefined;
|
|
143
|
+
newConfig?: undefined;
|
|
144
|
+
}>;
|
|
145
|
+
/**
|
|
146
|
+
* Clear all emails from memory
|
|
147
|
+
*/
|
|
148
|
+
clearEmails(): void;
|
|
149
|
+
isTextMimeType(mimeType?: string): boolean;
|
|
150
|
+
isTextExtension(filename?: string): boolean;
|
|
151
|
+
decodeToBuffer(data?: string): Buffer<ArrayBuffer>;
|
|
152
|
+
encodeToBase64Url(str?: string): string;
|
|
153
|
+
collectAttachmentParts(part: any, attachments?: any[]): any[];
|
|
154
|
+
fetchAttachmentBuffer(messageId: any, attachmentId: any): Promise<Buffer<ArrayBuffer>>;
|
|
155
|
+
parsePdfAttachment(buffer: any, messageId: any, filename?: string): Promise<string>;
|
|
156
|
+
extractAttachmentText(messageId: any, part: any): Promise<any>;
|
|
157
|
+
includeAttachmentsInBody(message: any): Promise<any>;
|
|
158
|
+
}
|
|
159
|
+
export default FilterGmailPoller;
|
|
160
|
+
//# sourceMappingURL=filter-gmail-poller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-gmail-poller.d.ts","sourceRoot":"","sources":["../../src/filter-gmail-poller/filter-gmail-poller.ts"],"names":[],"mappings":"AA0BA,cAAM,iBAAiB;IACrB,MAAM,CAAC,QAAQ,MAAQ;gBACX,UAAU,SAAkB;IAWxC;;OAEG;IACG,UAAU;IAYhB;;OAEG;IACG,YAAY;IAkBlB;;OAEG;IACH,aAAa,CAAC,KAAK,KAAA;IAMnB;;;;;OAKG;IACH,gBAAgB,CAAC,KAAK,KAAA,EAAE,aAAa,SAAe;IA4DpD;;OAEG;IACH,eAAe,CAAC,KAAK,KAAA;IAUrB;;OAEG;IACG,gBAAgB,CAAC,SAAS,KAAA;IAiBhC;;OAEG;IACG,iBAAiB;IAuCvB;;OAEG;IACG,SAAS;IAiBf;;OAEG;IACG,WAAW,CAAC,SAAS,KAAA;IA0B3B;;OAEG;IACG,iBAAiB,CAAC,SAAS,KAAA;IAWjC;;OAEG;IACH,aAAa;IAMb;;OAEG;IACG,eAAe,CAAC,SAAS,KAAA;IAsB/B;;OAEG;IACG,SAAS,CAAC,SAAS,KAAA,EAAE,aAAa,KAAA,EAAE,cAAc,QAAK;IAiC7D;;;OAGG;IACG,kBAAkB,CAAC,UAAU,KAAA;IAgBnC;;;OAGG;IACG,iBAAiB,CAAC,SAAS,KAAA,EAAE,UAAU,KAAA,EAAE,eAAe,UAAO;IAwBrE;;;;OAIG;IACG,iBAAiB,CAAC,OAAO,KAAK;;;;;;;;IAsFpC;;OAEG;IACH,gBAAgB,CAAC,KAAK,KAAA;IAqBtB;;OAEG;IACG,aAAa;IAsDnB;;OAEG;IACG,YAAY;IA2BlB;;OAEG;IACH,WAAW;IAQX;;;OAGG;IACG,cAAc,CAAC,WAAW,MAAO;IAmNvC;;OAEG;IACH,aAAa;IAYb;;OAEG;IACG,gBAAgB;IActB;;;OAGG;IACG,UAAU,CAAC,WAAW,MAAO;IA6BnC;;;OAGG;IACG,KAAK,CAAC,WAAW,MAAO;IAa9B;;OAEG;IACH,SAAS;IAIT;;;;;;OAMG;IACG,kBAAkB,CAAC,OAAO,KAAA;;;;;;;;;;;;;IA2FhC;;OAEG;IACH,WAAW;IAKX,cAAc,CAAC,QAAQ,SAAK;IAI5B,eAAe,CAAC,QAAQ,SAAK;IAK7B,cAAc,CAAC,IAAI,SAAK;IAKxB,iBAAiB,CAAC,GAAG,SAAK;IAQ1B,sBAAsB,CAAC,IAAI,KAAA,EAAE,WAAW,QAAK;IAgBvC,qBAAqB,CAAC,SAAS,KAAA,EAAE,YAAY,KAAA;IAc7C,kBAAkB,CAAC,MAAM,KAAA,EAAE,SAAS,KAAA,EAAE,QAAQ,SAAmB;IA2CjE,qBAAqB,CAAC,SAAS,KAAA,EAAE,IAAI,KAAA;IA2BrC,wBAAwB,CAAC,OAAO,KAAA;CA2CvC;AAED,eAAe,iBAAiB,CAAC"}
|