@futdevpro/nts-dynamo 1.15.15 → 1.15.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.c8rc.json +26 -26
- package/.copilot/patterns.json +7 -7
- package/.cursor/rules/__assistant_guide.mdc +30 -30
- package/.cursor/rules/_ag_backend-structure.mdc +85 -85
- package/.cursor/rules/_ag_backend.mdc +16 -16
- package/.cursor/rules/_ag_frontend-structure.mdc +86 -86
- package/.cursor/rules/_ag_frontend.mdc +39 -39
- package/.cursor/rules/_ag_import-rules.mdc +44 -44
- package/.cursor/rules/_ag_naming.mdc +115 -115
- package/.cursor/rules/_ag_should-be.mdc +6 -6
- package/.cursor/rules/ai_development_guide.md +60 -60
- package/.cursor/rules/cursor-rules.md +160 -160
- package/.cursor/rules/default-command.mdc +464 -464
- package/.cursor/rules/error_code_pattern.md +39 -39
- package/.cursor/rules/saved rule mcp server use.md +15 -15
- package/.dynamo/version-bump.config.json +5 -0
- package/.github/workflows/main.yml +426 -393
- package/.husky/pre-commit +1 -0
- package/.vscode/settings.json +10 -10
- package/HOWTO.md +15 -15
- package/LICENSE +21 -21
- package/__documentations/2026-04-28-logs-module.md +49 -0
- package/__documentations/nts-integration-tests-2026-03-17.md +26 -26
- package/_specifications/BACKLOG.md +50 -50
- package/_specifications/TODO.md +15 -15
- package/_specifications/agent.md +138 -138
- package/eslint.config.js +3 -3
- package/nodemon.json +24 -24
- package/package.json +343 -362
- package/pipeline.cicd.config.json +152 -0
- package/pnpm-workspace.yaml +2 -0
- package/scripts/run-coverage-tests.js +28 -28
- package/spec/support/helpers/spec-reporter-loader.js +359 -359
- package/spec/support/helpers/ts-node-helper.js +93 -93
- package/spec/support/jasmine.coverage.json +24 -24
- package/spec/support/jasmine.json +24 -24
- package/src/_collections/archive.util.spec.ts +57 -57
- package/src/_collections/archive.util.ts +18 -18
- package/src/_collections/atlas-default-db-options.const.ts +9 -9
- package/src/_collections/default-fallback-cache-max-age.const.spec.ts +11 -11
- package/src/_collections/default-fallback-cache-max-age.const.ts +2 -2
- package/src/_collections/default-not-found-page.const.spec.ts +19 -19
- package/src/_collections/default-not-found-page.const.ts +22 -22
- package/src/_collections/default-socket-path.const.spec.ts +12 -12
- package/src/_collections/default-socket-path.const.ts +2 -2
- package/src/_collections/get-environment-settings.util.spec.ts +210 -210
- package/src/_collections/get-environment-settings.util.ts +48 -48
- package/src/_collections/sample.env +21 -21
- package/src/_collections/star.controller.spec.ts +224 -224
- package/src/_collections/star.controller.ts +129 -129
- package/src/_enums/data-model-type.enum.ts +14 -14
- package/src/_enums/data-service-function.enum.ts +24 -24
- package/src/_enums/predefined-data-types.enum.ts +16 -16
- package/src/_enums/route-security.enum.ts +12 -12
- package/src/_models/control-models/api-call-params.control-model.spec.ts +152 -152
- package/src/_models/control-models/api-call-params.control-model.ts +142 -142
- package/src/_models/control-models/app-ext-system-controls.control-model.spec.ts +52 -52
- package/src/_models/control-models/app-ext-system-controls.control-model.ts +9 -9
- package/src/_models/control-models/app-params.control-model.spec.ts +225 -225
- package/src/_models/control-models/app-params.control-model.ts +136 -136
- package/src/_models/control-models/app-system-controls.control-model.spec.ts +31 -31
- package/src/_models/control-models/app-system-controls.control-model.ts +9 -9
- package/src/_models/control-models/endpoint-params.control-model.spec.ts +578 -578
- package/src/_models/control-models/endpoint-params.control-model.ts +526 -526
- package/src/_models/control-models/http-settings.control-model.spec.ts +77 -77
- package/src/_models/control-models/http-settings.control-model.ts +37 -37
- package/src/_models/control-models/system-control.control-model.spec.ts +27 -27
- package/src/_models/control-models/system-control.control-model.ts +12 -12
- package/src/_models/interfaces/certification-settings.interface.ts +7 -7
- package/src/_models/interfaces/environment-settings.interface.ts +59 -59
- package/src/_models/interfaces/global-log-settings.interface.ts +108 -108
- package/src/_models/interfaces/global-service-settings.interface.ts +47 -47
- package/src/_models/interfaces/routing-module-settings.interface.ts +21 -21
- package/src/_models/interfaces/static-client-settings.interface.spec.ts +29 -29
- package/src/_models/interfaces/static-client-settings.interface.ts +28 -28
- package/src/_models/types/db-update.type.ts +100 -100
- package/src/_modules/ai/_models/ai-input-interfaces.ts +117 -117
- package/src/_modules/ai/_models/ai-test-generation-result.interface.ts +16 -16
- package/src/_modules/ai/_modules/anthropic/_services/aai-user-key.control-service.ts +138 -138
- package/src/_modules/ai/_modules/anthropic/index.ts +5 -5
- package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.spec.ts +242 -242
- package/src/_modules/ai/_modules/document-ai/_collections/dai-chunking.util.ts +639 -639
- package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.spec.ts +209 -209
- package/src/_modules/ai/_modules/document-ai/_collections/dai-document.util.ts +85 -85
- package/src/_modules/ai/_modules/document-ai/_enums/dai-compare-result-type.enum.ts +7 -7
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-chunk.data-model.ts +146 -146
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-doc-page.data-model.ts +162 -162
- package/src/_modules/ai/_modules/document-ai/_models/data-models/dai-document.data-model.ts +99 -99
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-chunk-compare-result.interface.ts +18 -18
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-doc-page-compare-result.interface.ts +19 -19
- package/src/_modules/ai/_modules/document-ai/_models/interfaces/dai-document-compare-result.interface.ts +25 -25
- package/src/_modules/ai/_modules/document-ai/index.ts +28 -28
- package/src/_modules/ai/_modules/fdp-ai/_services/fdpai-user-key.control-service.ts +189 -189
- package/src/_modules/ai/_modules/fdp-ai/index.ts +5 -5
- package/src/_modules/ai/_modules/open-ai/_collections/oai-global-settings.const.ts +9 -9
- package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests-hu.conts.ts +82 -82
- package/src/_modules/ai/_modules/open-ai/_collections/oai-llm-predefined-requests.conts.ts +75 -75
- package/src/_modules/ai/_modules/open-ai/_enums/oai-gpt-message-role.enum.ts +45 -45
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-global-settings.interface.ts +7 -7
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-gpt-message.interface.ts +7 -7
- package/src/_modules/ai/_modules/open-ai/_models/interfaces/oai-llm-predefined-requests.interface.ts +57 -57
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-doc-chunk-data.service.ts +292 -292
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-document.data-service.spec.ts +342 -342
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.spec.ts +550 -550
- package/src/_modules/ai/_modules/open-ai/_services/data-services/oai-vector-data.service.ts +630 -630
- package/src/_modules/ai/_modules/open-ai/_services/oai-embedding.control-service.spec.ts +240 -240
- package/src/_modules/ai/_modules/open-ai/_services/oai-embedding.control-service.ts +98 -98
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.spec.ts +462 -462
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm-chat.service-base.ts +615 -615
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.spec.ts +437 -437
- package/src/_modules/ai/_modules/open-ai/_services/oai-llm.service-base.ts +833 -833
- package/src/_modules/ai/_modules/open-ai/_services/oai-user-key.control-service.ts +157 -157
- package/src/_modules/ai/_services/ai-embedding.service-base.spec.ts +98 -98
- package/src/_modules/ai/_services/ai-embedding.service-base.ts +48 -48
- package/src/_modules/ai/_services/ai-llm-chat.service-base.spec.ts +229 -229
- package/src/_modules/ai/_services/ai-llm-chat.service-base.ts +68 -68
- package/src/_modules/ai/_services/ai-llm.service-base.spec.ts +250 -250
- package/src/_modules/ai/_services/ai-llm.service-base.ts +332 -332
- package/src/_modules/ai/_services/ai-provider.service-base.spec.ts +79 -79
- package/src/_modules/ai/_services/ai-provider.service-base.ts +29 -29
- package/src/_modules/ai/_services/ai-user-key.service-base.ts +59 -59
- package/src/_modules/ai/index.ts +13 -13
- package/src/_modules/assistant/_collections/ass-global-settings.const.ts +13 -13
- package/src/_modules/assistant/_collections/ass.util.spec.ts +176 -176
- package/src/_modules/assistant/_collections/ass.util.ts +50 -50
- package/src/_modules/assistant/_models/ass-global-settings.interface.ts +15 -15
- package/src/_modules/assistant/_services/ass-io.control-service.spec.ts +140 -140
- package/src/_modules/assistant/_services/ass-main.control-service.spec.ts +192 -192
- package/src/_modules/assistant/_services/ass-main.control-service.ts +107 -107
- package/src/_modules/bot/_collections/bot-default-commands.const.ts +12 -12
- package/src/_modules/bot/_collections/bot-global-settings.const.ts +39 -39
- package/src/_modules/bot/_models/bot-channel-wrapper.interface.ts +62 -62
- package/src/_modules/bot/_models/bot-command.interface.ts +8 -8
- package/src/_modules/bot/_models/bot-global-settings.interface.ts +96 -96
- package/src/_modules/bot/_models/bot-last-mention-date.interface.ts +6 -6
- package/src/_modules/bot/_models/bot-last-message-date.interface.ts +5 -5
- package/src/_modules/bot/_models/bot-user-wrapper.interface.ts +41 -41
- package/src/_modules/bot/_modules/discord-bot/_models/dib-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/discord-bot/_services/dib-messaging-provider.control-service.spec.ts +431 -431
- package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.spec.ts +160 -160
- package/src/_modules/bot/_modules/dynamo-bot/_collections/dyb-operations.util.ts +55 -55
- package/src/_modules/bot/_modules/dynamo-bot/_models/dyb-platform.types.ts +15 -15
- package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.spec.ts +374 -374
- package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.ts +447 -447
- package/src/_modules/bot/_modules/dynamo-bot/index.ts +15 -15
- package/src/_modules/bot/_modules/slack-bot/_models/slb-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.spec.ts +344 -344
- package/src/_modules/bot/_modules/slack-bot/_services/slb-messaging-provider.control-service.ts +197 -197
- package/src/_modules/bot/_modules/teams-bot/_models/teb-platform.types.ts +9 -9
- package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.spec.ts +345 -345
- package/src/_modules/bot/_modules/teams-bot/_services/teb-messaging-provider.control-service.ts +197 -197
- package/src/_modules/bot/_services/bot-commands.control-service.spec.ts +116 -116
- package/src/_modules/bot/_services/bot-io.control-service.spec.ts +285 -285
- package/src/_modules/bot/_services/bot-main.control-service.spec.ts +208 -208
- package/src/_modules/bot/_services/bot-messaging-provider.service-base.spec.ts +349 -349
- package/src/_modules/bot/_services/bot-routines.control-service.spec.ts +111 -111
- package/src/_modules/custom-data/custom-data.controller.spec.ts +49 -49
- package/src/_modules/custom-data/custom-data.controller.ts +67 -67
- package/src/_modules/custom-data/custom-data.data-service.spec.ts +54 -54
- package/src/_modules/custom-data/custom-data.data-service.ts +21 -21
- package/src/_modules/custom-data/get-custom-data-routing-module.util.spec.ts +28 -28
- package/src/_modules/custom-data/get-custom-data-routing-module.util.ts +24 -24
- package/src/_modules/custom-data/index.ts +9 -9
- package/src/_modules/defaults/_collections/default-endpoints.util.ts +487 -487
- package/src/_modules/defaults/_models/default-user.data-model.ts +72 -72
- package/src/_modules/defaults/_services/default-auth.service.spec.ts +269 -269
- package/src/_modules/defaults/_services/default-auth.service.ts +177 -177
- package/src/_modules/defaults/_services/default-socket-events.service.spec.ts +42 -42
- package/src/_modules/defaults/_services/default-socket-events.service.ts +61 -61
- package/src/_modules/defaults/_services/default-user.data-service.spec.ts +187 -187
- package/src/_modules/defaults/_services/default-user.data-service.ts +98 -98
- package/src/_modules/defaults/index.ts +17 -17
- package/src/_modules/discord-assistant/_collections/dias-global-settings.const.ts +19 -19
- package/src/_modules/discord-assistant/_collections/dias.util.spec.ts +366 -366
- package/src/_modules/discord-assistant/_collections/dias.util.ts +132 -132
- package/src/_modules/discord-assistant/_models/dias-global-settings.interface.ts +19 -19
- package/src/_modules/discord-assistant/_models/dias-knowledge.data-model.ts +52 -52
- package/src/_modules/discord-assistant/_services/dias-chunk.data-service.ts +177 -177
- package/src/_modules/discord-assistant/_services/dias-io.control-service.spec.ts +108 -108
- package/src/_modules/discord-assistant/_services/dias-io.control-service.ts +69 -69
- package/src/_modules/discord-assistant/_services/dias-main.control-service.spec.ts +22 -22
- package/src/_modules/discord-assistant/_services/dias-main.control-service.ts +27 -27
- package/src/_modules/discord-assistant/_services/dias.service-base.spec.ts +195 -195
- package/src/_modules/discord-assistant/_services/dias.service-base.ts +76 -76
- package/src/_modules/discord-assistant/index.ts +38 -38
- package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.spec.ts +34 -34
- package/src/_modules/discord-assistant-voiced/_services/dias-discord-bot.control-service.ts +11 -11
- package/src/_modules/discord-assistant-voiced/index.ts +36 -36
- package/src/_modules/discord-bot/_collections/dibo-default-commands.const.ts +16 -16
- package/src/_modules/discord-bot/_collections/dibo-global-settings.conts.ts +55 -55
- package/src/_modules/discord-bot/_collections/dibo-operations.util.spec.ts +214 -214
- package/src/_modules/discord-bot/_collections/dibo-operations.util.ts +387 -387
- package/src/_modules/discord-bot/_models/dibo-command.interface.ts +12 -12
- package/src/_modules/discord-bot/_models/dibo-global-settings.interface.ts +98 -98
- package/src/_modules/discord-bot/_models/dibo-last-mention-date.inteface.ts +7 -7
- package/src/_modules/discord-bot/_models/dibo-last-message-date.interface.ts +6 -6
- package/src/_modules/discord-bot/_services/dibo-commands.control-service.spec.ts +154 -154
- package/src/_modules/discord-bot/_services/dibo-commands.control-service.ts +153 -153
- package/src/_modules/discord-bot/_services/dibo-io.control-service.spec.ts +264 -264
- package/src/_modules/discord-bot/_services/dibo-io.control-service.ts +306 -306
- package/src/_modules/discord-bot/_services/dibo-main.control-service.spec.ts +408 -408
- package/src/_modules/discord-bot/_services/dibo-main.control-service.ts +487 -487
- package/src/_modules/discord-bot/_services/dibo-routines.control-service.spec.ts +105 -105
- package/src/_modules/discord-bot/index.ts +36 -36
- package/src/_modules/local-vector-search/_enums/lvs-search-mode.enum.ts +19 -19
- package/src/_modules/local-vector-search/_models/lvs-search-result.interface.ts +17 -17
- package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.spec.ts +418 -418
- package/src/_modules/local-vector-search/_services/lvs-doc-chunk-data.service.ts +276 -276
- package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.spec.ts +345 -345
- package/src/_modules/local-vector-search/_services/lvs-local-vector-search.data-service.ts +330 -330
- package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.spec.ts +393 -393
- package/src/_modules/local-vector-search/_services/lvs-vector-pool.control-service.ts +220 -220
- package/src/_modules/local-vector-search/index.ts +11 -11
- package/src/_modules/messaging/README.md +354 -354
- package/src/_modules/messaging/_collections/get-messaging-routing-module.util.ts +26 -26
- package/src/_modules/messaging/_collections/msg-global-settings.const.ts +22 -22
- package/src/_modules/messaging/_collections/msg.util.spec.ts +226 -226
- package/src/_modules/messaging/_models/msg-global-settings.interface.ts +37 -37
- package/src/_modules/messaging/_services/msg-conversation.data-service.ts +146 -146
- package/src/_modules/messaging/_services/msg-events.service.spec.ts +219 -219
- package/src/_modules/messaging/_services/msg-events.service.ts +267 -267
- package/src/_modules/messaging/_services/msg-integration.control-service.ts +179 -179
- package/src/_modules/messaging/_services/msg-main.control-service.spec.ts +147 -147
- package/src/_modules/messaging/_services/msg-main.control-service.ts +571 -571
- package/src/_modules/messaging/_services/msg-message.data-service.ts +129 -129
- package/src/_modules/messaging/_services/msg.controller.spec.ts +201 -201
- package/src/_modules/messaging/index.ts +30 -30
- package/src/_modules/mock/app-extended-server.mock.ts +201 -201
- package/src/_modules/mock/app-integration-test.mock.ts +51 -51
- package/src/_modules/mock/app-params.mock.spec.ts +21 -21
- package/src/_modules/mock/app-params.mock.ts +9 -9
- package/src/_modules/mock/app-server.mock.ts +188 -188
- package/src/_modules/mock/auth-service.mock.spec.ts +47 -47
- package/src/_modules/mock/auth-service.mock.ts +28 -28
- package/src/_modules/mock/controller.mock.spec.ts +26 -26
- package/src/_modules/mock/controller.mock.ts +16 -16
- package/src/_modules/mock/data-model.mock.spec.ts +111 -111
- package/src/_modules/mock/data-model.mock.ts +82 -82
- package/src/_modules/mock/email-service-collection.mock.spec.ts +24 -24
- package/src/_modules/mock/email-service-collection.mock.ts +15 -15
- package/src/_modules/mock/email-service.mock.spec.ts +17 -17
- package/src/_modules/mock/email-service.mock.ts +20 -20
- package/src/_modules/mock/email-template.mock.html +14 -14
- package/src/_modules/mock/endpoint.mock.ts +91 -91
- package/src/_modules/mock/socket-client.mock.spec.ts +40 -40
- package/src/_modules/mock/socket-client.mock.ts +45 -45
- package/src/_modules/mock/socket-server.mock.spec.ts +44 -44
- package/src/_modules/mock/socket-server.mock.ts +46 -46
- package/src/_modules/oauth2/_routes/oauth2.controller.spec.ts +107 -107
- package/src/_modules/oauth2/_routes/oauth2.controller.ts +98 -98
- package/src/_modules/oauth2/_services/oauth2.auth-service.spec.ts +254 -254
- package/src/_modules/oauth2/_services/oauth2.auth-service.ts +232 -232
- package/src/_modules/oauth2/_services/oauth2.control-service.spec.ts +585 -585
- package/src/_modules/oauth2/_services/oauth2.control-service.ts +653 -653
- package/src/_modules/oauth2/index.ts +17 -17
- package/src/_modules/server/errors/errors.control-service.spec.ts +230 -230
- package/src/_modules/server/errors/errors.control-service.ts +69 -69
- package/src/_modules/server/errors/errors.controller.spec.ts +165 -165
- package/src/_modules/server/errors/errors.controller.ts +270 -270
- package/src/_modules/server/errors/errors.data-service.spec.ts +355 -355
- package/src/_modules/server/index.ts +30 -30
- package/src/_modules/server/server-status/server-status-snapshot.control-service.spec.ts +70 -70
- package/src/_modules/server/server-status/server-status-snapshot.control-service.ts +17 -17
- package/src/_modules/server/server-status/server-status-snapshot.data-service.spec.ts +77 -77
- package/src/_modules/server/server-status/server-status-snapshot.data-service.ts +37 -37
- package/src/_modules/server/server-status/server-status.control-service.spec.ts +516 -516
- package/src/_modules/server/server-status/server-status.control-service.ts +336 -336
- package/src/_modules/server/server-status/server-status.controller.spec.ts +156 -156
- package/src/_modules/server/server-status/server-status.controller.ts +131 -131
- package/src/_modules/socket/_enums/socket-security.enum.ts +11 -11
- package/src/_modules/socket/_models/socket-client-service-params.control-model.spec.ts +32 -32
- package/src/_modules/socket/_models/socket-client-service-params.control-model.ts +22 -22
- package/src/_modules/socket/_models/socket-presence.control-model.spec.ts +164 -164
- package/src/_modules/socket/_models/socket-presence.control-model.ts +210 -210
- package/src/_modules/socket/_models/socket-server-service-params.control-model.spec.ts +46 -46
- package/src/_modules/socket/_models/socket-server-service-params.control-model.ts +22 -22
- package/src/_modules/socket/_services/socket-client.service.spec.ts +15 -15
- package/src/_modules/socket/_services/socket-client.service.ts +260 -260
- package/src/_modules/socket/_services/socket-server.service.spec.ts +11 -11
- package/src/_modules/socket/app-extended.integration.spec.ts +85 -85
- package/src/_modules/socket/app-extended.server.ts +630 -630
- package/src/_modules/socket/index.ts +42 -42
- package/src/_modules/test/get-test-routing-module.util.spec.ts +28 -28
- package/src/_modules/test/get-test-routing-module.util.ts +23 -23
- package/src/_modules/test/index.ts +11 -11
- package/src/_modules/test/test.controller.spec.ts +72 -72
- package/src/_modules/test/test.controller.ts +115 -115
- package/src/_modules/usage/get-usage-routing-module.util.ts +22 -22
- package/src/_modules/usage/index.ts +15 -15
- package/src/_modules/usage/usage.controller.spec.ts +81 -81
- package/src/_modules/usage/usage.controller.ts +126 -126
- package/src/_modules/usage/usage.data-service.spec.ts +332 -332
- package/src/_modules/usage/usage.data-service.ts +185 -185
- package/src/_services/base/api.service-base.spec.ts +125 -125
- package/src/_services/base/api.service-base.ts +74 -74
- package/src/_services/base/archive-data.service.spec.ts +196 -196
- package/src/_services/base/archive-data.service.ts +216 -216
- package/src/_services/base/data.service.spec.ts +493 -493
- package/src/_services/base/data.service.ts +2525 -2525
- package/src/_services/base/db.service.spec.ts +73 -73
- package/src/_services/base/db.service.ts +1575 -1575
- package/src/_services/base/singleton.service-base.spec.ts +28 -28
- package/src/_services/base/singleton.service-base.ts +24 -24
- package/src/_services/base/singleton.service.spec.ts +114 -114
- package/src/_services/base/singleton.service.ts +38 -38
- package/src/_services/core/api.service.spec.ts +140 -140
- package/src/_services/core/auth.service.spec.ts +159 -159
- package/src/_services/core/auth.service.ts +174 -174
- package/src/_services/core/email.service.spec.ts +85 -85
- package/src/_services/core/email.service.ts +742 -742
- package/src/_services/core/global.service.spec.ts +275 -275
- package/src/_services/core/global.service.ts +461 -461
- package/src/_services/core/service-collection.service.spec.ts +46 -46
- package/src/_services/core/service-collection.service.ts +6 -6
- package/src/_services/route/controller.service.spec.ts +53 -53
- package/src/_services/route/controller.service.ts +148 -148
- package/src/_services/route/routing-module.service.spec.ts +98 -98
- package/src/_services/route/routing-module.service.ts +330 -330
- package/src/_services/shared.static-service.spec.ts +99 -99
- package/src/_services/shared.static-service.ts +78 -78
- package/src/index.ts +94 -94
- package/tsconfig.app.json +12 -12
- package/tsconfig.json +42 -42
- package/build/_modules/logs/get-logs-routing-module.util.d.ts +0 -19
- package/build/_modules/logs/get-logs-routing-module.util.d.ts.map +0 -1
- package/build/_modules/logs/get-logs-routing-module.util.js +0 -32
- package/build/_modules/logs/get-logs-routing-module.util.js.map +0 -1
- package/build/_modules/logs/index.d.ts +0 -4
- package/build/_modules/logs/index.d.ts.map +0 -1
- package/build/_modules/logs/index.js +0 -10
- package/build/_modules/logs/index.js.map +0 -1
- package/build/_modules/logs/log-buffer.service.d.ts +0 -38
- package/build/_modules/logs/log-buffer.service.d.ts.map +0 -1
- package/build/_modules/logs/log-buffer.service.js +0 -97
- package/build/_modules/logs/log-buffer.service.js.map +0 -1
- package/build/_modules/logs/logs.controller.d.ts +0 -27
- package/build/_modules/logs/logs.controller.d.ts.map +0 -1
- package/build/_modules/logs/logs.controller.js +0 -90
- package/build/_modules/logs/logs.controller.js.map +0 -1
- package/build/_modules/logs/logs.service.d.ts +0 -40
- package/build/_modules/logs/logs.service.d.ts.map +0 -1
- package/build/_modules/logs/logs.service.js +0 -97
- package/build/_modules/logs/logs.service.js.map +0 -1
- package/src/_modules/logs/get-logs-routing-module.util.ts +0 -36
- package/src/_modules/logs/index.ts +0 -3
- package/src/_modules/logs/log-buffer.service.ts +0 -101
- package/src/_modules/logs/logs.controller.ts +0 -109
- package/src/_modules/logs/logs.service.ts +0 -100
package/src/_modules/bot/_modules/dynamo-bot/_services/dyb-messaging-provider.control-service.ts
CHANGED
|
@@ -1,447 +1,447 @@
|
|
|
1
|
-
import { DyFM_AnyError, DyFM_Array, DyFM_Error, DyFM_Log, week } from '@futdevpro/fsm-dynamo';
|
|
2
|
-
import {
|
|
3
|
-
DyFM_Msg_Provider_Type, DyFM_Msg_Conversation, DyFM_Msg_EventKey, DyFM_Msg_Message, DyFM_Msg_Participant
|
|
4
|
-
} from '@futdevpro/fsm-dynamo/messaging';
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
DyNTS_Bot_MessagingProvider_ServiceBase, DyNTS_Bot_MessagingProvider_Config
|
|
8
|
-
} from '../../../_services/bot-messaging-provider.service-base';
|
|
9
|
-
import { DyNTS_Bot_ChannelWrapper } from '../../../_models/bot-channel-wrapper.interface';
|
|
10
|
-
import { DyNTS_Bot_LastMessageDate } from '../../../_models/bot-last-message-date.interface';
|
|
11
|
-
import { DyNTS_Bot_LastMentionDate } from '../../../_models/bot-last-mention-date.interface';
|
|
12
|
-
import { DyNTS_Bot_MessageWrapper } from '../../../_models/bot-message-wrapper.interface';
|
|
13
|
-
import { DyNTS_Bot_UserWrapper } from '../../../_models/bot-user-wrapper.interface';
|
|
14
|
-
import { DyNTS_DyB_Message, DyNTS_DyB_Channel, DyNTS_DyB_User } from '../_models/dyb-platform.types';
|
|
15
|
-
import { DyNTS_global_settings } from '../../../../../_collections/global-settings.const';
|
|
16
|
-
import { DyNTS_Msg_Main_ControlService } from '../../../../messaging/_services/msg-main.control-service';
|
|
17
|
-
import { DyNTS_Msg_Message_DataService } from '../../../../messaging/_services/msg-message.data-service';
|
|
18
|
-
import { DyNTS_Msg_Conversation_DataService } from '../../../../messaging/_services/msg-conversation.data-service';
|
|
19
|
-
import { DyNTS_Msg_Events_Service } from '../../../../messaging/_services/msg-events.service';
|
|
20
|
-
|
|
21
|
-
export interface Dynamo_MessagingProviderConfig extends DyNTS_Bot_MessagingProvider_Config {
|
|
22
|
-
botUserId?: string;
|
|
23
|
-
botDisplayName?: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export class DyNTS_DyB_MessagingProvider_ControlService extends DyNTS_Bot_MessagingProvider_ServiceBase<
|
|
27
|
-
DyFM_Msg_Conversation,
|
|
28
|
-
DyFM_Msg_Message,
|
|
29
|
-
DyFM_Msg_Participant,
|
|
30
|
-
Dynamo_MessagingProviderConfig,
|
|
31
|
-
any
|
|
32
|
-
> {
|
|
33
|
-
readonly name = 'dynamo';
|
|
34
|
-
readonly type = DyFM_Msg_Provider_Type.dynamo;
|
|
35
|
-
|
|
36
|
-
get botId(): string {
|
|
37
|
-
return this.config.botUserId || 'dynamo-bot';
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
get botDisplayName(): string {
|
|
41
|
-
return this.config.botDisplayName || 'Dynamo Bot';
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
readonly config: Dynamo_MessagingProviderConfig;
|
|
45
|
-
|
|
46
|
-
/* protected override readonly channelCache: Map<string, DyFM_Msg_Conversation> = new Map();
|
|
47
|
-
protected override readonly roleCache: Map<string, any> = new Map(); */
|
|
48
|
-
|
|
49
|
-
// Services
|
|
50
|
-
private messaging_CS: DyNTS_Msg_Main_ControlService;
|
|
51
|
-
private eventsService: DyNTS_Msg_Events_Service;
|
|
52
|
-
|
|
53
|
-
constructor(setConfig: Dynamo_MessagingProviderConfig) {
|
|
54
|
-
super();
|
|
55
|
-
this.config = setConfig;
|
|
56
|
-
this.messaging_CS = DyNTS_Msg_Main_ControlService.getInstance();
|
|
57
|
-
this.eventsService = DyNTS_Msg_Events_Service.getInstance();
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async setup(issuer: string): Promise<void> {
|
|
61
|
-
try {
|
|
62
|
-
DyFM_Log.success('Dynamo bot provider setup completed');
|
|
63
|
-
} catch (error) {
|
|
64
|
-
DyFM_Error.logSimple('Error during Dynamo bot setup:', error);
|
|
65
|
-
|
|
66
|
-
throw new DyFM_Error({
|
|
67
|
-
...this.getDefaultErrorSettings('setup', error, issuer),
|
|
68
|
-
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-DyB-MessagingProvider-S000`,
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async start(issuer: string): Promise<void> {
|
|
74
|
-
try {
|
|
75
|
-
// Setup event listeners for messaging events
|
|
76
|
-
this.setupEventListeners();
|
|
77
|
-
DyFM_Log.success('Dynamo bot provider started');
|
|
78
|
-
} catch (error) {
|
|
79
|
-
DyFM_Error.logSimple('Error during Dynamo bot start:', error);
|
|
80
|
-
|
|
81
|
-
throw new DyFM_Error({
|
|
82
|
-
...this.getDefaultErrorSettings('start', error, issuer),
|
|
83
|
-
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-DyB-MessagingProvider-S001`,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private setupEventListeners(): void {
|
|
89
|
-
// Listen to messaging events and convert them to bot events
|
|
90
|
-
// Note: This would require extending the events service to support custom listeners
|
|
91
|
-
// For now, we'll implement a basic approach
|
|
92
|
-
DyFM_Log.info('Dynamo bot event listeners setup (messaging integration)');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Channel operations
|
|
96
|
-
async getChannelByName(name: string): Promise<DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>> {
|
|
97
|
-
if (this.channelCache.has(name)) {
|
|
98
|
-
return await this.wrapChannel(this.channelCache.get(name));
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const conversationService: DyNTS_Msg_Conversation_DataService = new DyNTS_Msg_Conversation_DataService({
|
|
102
|
-
issuer: 'dynamo-bot',
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// Try to find conversation by name or platformChannelId
|
|
106
|
-
const conversation: DyFM_Msg_Conversation = await conversationService.dataDBService.findOne({
|
|
107
|
-
$or: [
|
|
108
|
-
{ name: name },
|
|
109
|
-
{ platformChannelId: name }
|
|
110
|
-
],
|
|
111
|
-
__deleted: { $exists: false }
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
if (!conversation) {
|
|
115
|
-
throw new Error(`No conversation found with name "${name}"`);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
this.channelCache.set(name, conversation);
|
|
119
|
-
return await this.wrapChannel(conversation);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async getChannelById(id: string): Promise<DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>> {
|
|
123
|
-
if (this.channelCache.has(id)) {
|
|
124
|
-
return await this.wrapChannel(this.channelCache.get(id));
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const conversationService: DyNTS_Msg_Conversation_DataService = new DyNTS_Msg_Conversation_DataService({
|
|
128
|
-
issuer: 'dynamo-bot',
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
const conversation: DyFM_Msg_Conversation = await conversationService.dataDBService.findOne({
|
|
132
|
-
_id: id,
|
|
133
|
-
__deleted: { $exists: false }
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
if (!conversation) {
|
|
137
|
-
throw new Error(`No conversation found with ID "${id}"`);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
this.channelCache.set(id, conversation);
|
|
141
|
-
return await this.wrapChannel(conversation);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
async sendMessageToChannel(channel: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>, message: string, issuer: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
145
|
-
const msg: DyFM_Msg_Message = await this.messaging_CS.sendMessage(channel.id, { content: message }, this.botId, issuer);
|
|
146
|
-
|
|
147
|
-
return await this.wrapMessage(msg);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
async sendMessageToChannelByName(channelName: string, message: string, issuer: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
151
|
-
const channel: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
152
|
-
return this.sendMessageToChannel(channel, message, issuer);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
async getMessagesFromChannelByChannelName(channelName: string, limit: number = 100): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[]> {
|
|
156
|
-
const channel: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
157
|
-
return this.fetchMessages(channel, limit);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
async getLastMessageInChannel(channelName: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
161
|
-
const channel: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
162
|
-
const messages: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[] = await this.fetchMessages(channel, 1);
|
|
163
|
-
return messages.length > 0 ? messages[0] : null;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async clearChannel(channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>): Promise<void> {
|
|
167
|
-
// For messaging system, we don't actually delete messages
|
|
168
|
-
// This could be implemented to mark messages as deleted or archived
|
|
169
|
-
DyFM_Log.warn('Clear channel not implemented for messaging system');
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
async replyToMessage(messageWrapper: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>, content: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
173
|
-
// In messaging system, we can't directly reply to a message
|
|
174
|
-
// Instead, we'll send a new message with reference to the original
|
|
175
|
-
const replyContent: string = `[Reply to message ${messageWrapper.id}] ${content}`;
|
|
176
|
-
|
|
177
|
-
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(messageWrapper.channelName);
|
|
178
|
-
return this.sendMessageToChannel(channelWrapper, replyContent, messageWrapper.issuer);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
async sendTyping(channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>): Promise<void> {
|
|
182
|
-
// Typing indicators not implemented for messaging system
|
|
183
|
-
DyFM_Log.info('Typing indicator not supported in messaging system');
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async sendTypingForMessage(messageWrapper: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>): Promise<void> {
|
|
187
|
-
// Typing indicators not implemented for messaging system
|
|
188
|
-
DyFM_Log.info('Typing indicator not supported in messaging system');
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
async fetchMessages(channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>, limit: number): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[]> {
|
|
192
|
-
const messageService: DyNTS_Msg_Message_DataService = new DyNTS_Msg_Message_DataService({
|
|
193
|
-
issuer: 'dynamo-bot',
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
const messages: DyFM_Msg_Message[] = await messageService.dataDBService.find({
|
|
197
|
-
conversationId: channelWrapper.id,
|
|
198
|
-
__deleted: { $exists: false },
|
|
199
|
-
$sort: { sentAt: -1 },
|
|
200
|
-
$limit: limit
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
return await DyFM_Array.asyncMap(messages, async (msg: DyFM_Msg_Message) => await this.wrapMessage(msg));
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
async fetchMessagesById(id: string, limit: number): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[]> {
|
|
207
|
-
const messageService: DyNTS_Msg_Message_DataService = new DyNTS_Msg_Message_DataService({
|
|
208
|
-
issuer: 'dynamo-bot',
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
const messages: DyFM_Msg_Message[] = await messageService.dataDBService.find({
|
|
212
|
-
_id: id,
|
|
213
|
-
__deleted: { $exists: false },
|
|
214
|
-
$sort: { sentAt: -1 },
|
|
215
|
-
$limit: limit
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
return await DyFM_Array.asyncMap(messages, async (msg: DyFM_Msg_Message) => await this.wrapMessage(msg));
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
async fetchMessagesForMessage(messageWrapper: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>, limit: number): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[]> {
|
|
222
|
-
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(messageWrapper.channelName);
|
|
223
|
-
return this.fetchMessages(channelWrapper, limit);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
async fetchAllMessagesWithPaging(channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>, maxFetch: number = 1000): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[]> {
|
|
227
|
-
return this.fetchMessages(channelWrapper, maxFetch);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
async deleteMessage(messageWrapper: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>): Promise<void> {
|
|
231
|
-
await this.messaging_CS.deleteMessage(messageWrapper.id, 'dynamo-bot', 'dynamo-bot');
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
async updateMessage(message: DyFM_Msg_Message, issuer: string): Promise<void> {
|
|
235
|
-
await this.messaging_CS.modifyMessage(message, issuer);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// User operations
|
|
239
|
-
async getUserByName(username: string): Promise<DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>> {
|
|
240
|
-
// In messaging system, we don't have a direct user lookup by name
|
|
241
|
-
// This would need to be implemented based on your user management system
|
|
242
|
-
const userData: any = {
|
|
243
|
-
userId: username,
|
|
244
|
-
username: username,
|
|
245
|
-
displayName: username,
|
|
246
|
-
isBot: false,
|
|
247
|
-
role: 'member',
|
|
248
|
-
joinedAt: new Date()
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
return await this.wrapUser(userData);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
getUserMention(userId: string): string {
|
|
255
|
-
return `@${userId}`;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
async readMembersInChannel(channelName: string): Promise<DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>[]> {
|
|
259
|
-
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
260
|
-
const participants: DyFM_Msg_Participant[] = channelWrapper.rawPlatformChannel.participants || [];
|
|
261
|
-
|
|
262
|
-
return await DyFM_Array.asyncMap(participants, async (participant: DyFM_Msg_Participant) => await this.wrapUser(participant));
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
async readMemberNamesInChannel(channelName: string): Promise<string[]> {
|
|
266
|
-
const members: DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>[] = await this.readMembersInChannel(channelName);
|
|
267
|
-
return members.map(member => member.username);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Advanced message queries
|
|
271
|
-
async getLastMessageSentBy(channelName: string, username: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
272
|
-
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
273
|
-
const messages: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[] = await this.fetchAllMessagesWithPaging(channelWrapper, 1000);
|
|
274
|
-
|
|
275
|
-
return messages.find(msg => msg.authorName === username) || null;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
async getLastMentionOf(channelName: string, username: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
279
|
-
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
280
|
-
const messages: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[] = await this.fetchAllMessagesWithPaging(channelWrapper, 1000);
|
|
281
|
-
|
|
282
|
-
return messages.find(msg =>
|
|
283
|
-
msg.content.includes(`@${username}`) ||
|
|
284
|
-
msg.content.includes(username)
|
|
285
|
-
) || null;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
async readLastMessageDatesByMembers(channelName: string, memberNames: string[]): Promise<DyNTS_Bot_LastMessageDate[]> {
|
|
289
|
-
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
290
|
-
const messages: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[] = await this.fetchAllMessagesWithPaging(channelWrapper, 1000);
|
|
291
|
-
|
|
292
|
-
const memberStatus: Record<string, { lastMessageDate: Date | null, allMessages: number }> = {};
|
|
293
|
-
memberNames.forEach((name: string) => {
|
|
294
|
-
memberStatus[name] = { lastMessageDate: null, allMessages: 0 };
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
const cutoffTime: number = Date.now() - (3 * week); // 3 weeks
|
|
298
|
-
|
|
299
|
-
messages.forEach((message: DyNTS_DyB_Message) => {
|
|
300
|
-
if (message.timestamp < cutoffTime) return;
|
|
301
|
-
|
|
302
|
-
const author = message.authorName;
|
|
303
|
-
if (memberStatus[author] !== undefined) {
|
|
304
|
-
memberStatus[author].allMessages++;
|
|
305
|
-
if (!memberStatus[author].lastMessageDate) {
|
|
306
|
-
memberStatus[author].lastMessageDate = new Date(message.timestamp);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
return memberNames.map((memberName: string) => {
|
|
312
|
-
const status: { lastMessageDate: Date | null, allMessages: number } = memberStatus[memberName];
|
|
313
|
-
return {
|
|
314
|
-
memberName: memberName,
|
|
315
|
-
allMessages: status.allMessages,
|
|
316
|
-
lastMessageDate: status.lastMessageDate
|
|
317
|
-
};
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
async readLastMessageWithMemberNamePingInIt(channelName: string, users: DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>[]): Promise<DyNTS_Bot_LastMentionDate[]> {
|
|
322
|
-
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
323
|
-
const messages: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[] = await this.fetchAllMessagesWithPaging(channelWrapper, 1000);
|
|
324
|
-
|
|
325
|
-
const memberStatus: Record<string, { lastMentionDate: Date | null; allMentions: number }> = {};
|
|
326
|
-
users.forEach((user: DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>) => {
|
|
327
|
-
memberStatus[user.username] = { lastMentionDate: null, allMentions: 0 };
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
const cutoffTime: number = Date.now() - (3 * week); // 3 weeks
|
|
331
|
-
|
|
332
|
-
messages.forEach((message: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>) => {
|
|
333
|
-
if (message.timestamp < cutoffTime) return;
|
|
334
|
-
|
|
335
|
-
users.forEach((user: DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>) => {
|
|
336
|
-
if (
|
|
337
|
-
message.content.includes(`@${user.id}`) &&
|
|
338
|
-
!memberStatus[user.username].lastMentionDate
|
|
339
|
-
) {
|
|
340
|
-
memberStatus[user.username].lastMentionDate = new Date(message.timestamp);
|
|
341
|
-
memberStatus[user.username].allMentions++;
|
|
342
|
-
}
|
|
343
|
-
});
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
return users.map((user: DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>) => {
|
|
347
|
-
const status: { lastMentionDate: Date | null; allMentions: number } = memberStatus[user.username];
|
|
348
|
-
return {
|
|
349
|
-
memberId: user.id,
|
|
350
|
-
memberName: user.username,
|
|
351
|
-
allMentions: status.allMentions,
|
|
352
|
-
lastMentionDate: status.lastMentionDate
|
|
353
|
-
};
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// Platform-specific features (not applicable for messaging system)
|
|
358
|
-
getRoleByName?(roleName: string): any {
|
|
359
|
-
return null; // Not applicable for messaging system
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
getRolePingByName?(roleName: string): Promise<string> {
|
|
363
|
-
return Promise.resolve(''); // Not applicable for messaging system
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
getRolePingsByName?(roleNames: string[]): Promise<string> {
|
|
367
|
-
return Promise.resolve(''); // Not applicable for messaging system
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// Event binding
|
|
371
|
-
async create_onMessageEventListener(
|
|
372
|
-
handler: (message: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>, issuer: string) => Promise<void>
|
|
373
|
-
): Promise<void> {
|
|
374
|
-
// TODO: Implement message event listener for messaging system
|
|
375
|
-
DyFM_Log.info('Message event listener created (messaging integration)');
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
create_onErrorEventListener(handler: (error: DyFM_AnyError) => void): void {
|
|
379
|
-
// TODO: Implement error event listener for messaging system
|
|
380
|
-
DyFM_Log.info('Error event listener created (messaging integration)');
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
async sendReport(message: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
384
|
-
return await this.sendMessageToChannelByName(this.config.reportChannelName, message, 'dynamo-bot');
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
async sendReportIn(message: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
388
|
-
return await this.sendMessageToChannelByName(
|
|
389
|
-
this.config.reportChannelName,
|
|
390
|
-
`${this.botDisplayName} report for duty! ` +
|
|
391
|
-
`(v${DyNTS_global_settings.systemVersion} ${DyNTS_global_settings.env_settings?.environment})`,
|
|
392
|
-
'dynamo-bot'
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
async wrapMessage(msgMessage: DyFM_Msg_Message): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
397
|
-
return new DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>({
|
|
398
|
-
id: msgMessage._id,
|
|
399
|
-
content: msgMessage.content,
|
|
400
|
-
authorId: msgMessage.senderId,
|
|
401
|
-
authorName: msgMessage.senderName,
|
|
402
|
-
authorDisplayName: msgMessage.senderDisplayName,
|
|
403
|
-
channelId: msgMessage.conversationId,
|
|
404
|
-
channelName: msgMessage.conversationId,
|
|
405
|
-
timestamp: msgMessage.sentAt ? new Date(msgMessage.sentAt).getTime() : Date.now(),
|
|
406
|
-
isBot: msgMessage.isAIGenerated || false,
|
|
407
|
-
isTextBased: true,
|
|
408
|
-
isVoiceBased: false,
|
|
409
|
-
isDM: false,
|
|
410
|
-
replyToMessageId: msgMessage.parentMessageId,
|
|
411
|
-
replyToMessageAuthorId: null,
|
|
412
|
-
mentions: msgMessage.mentions.map(mention => mention.userId),
|
|
413
|
-
rawPlatformMessage: msgMessage,
|
|
414
|
-
|
|
415
|
-
issuer: msgMessage.senderId,
|
|
416
|
-
|
|
417
|
-
/* channel: this.wrapChannel(msgMessage.conversation), */
|
|
418
|
-
channel: null,
|
|
419
|
-
/* user: this.wrapUser(msgMessage.sender), */
|
|
420
|
-
|
|
421
|
-
provider: this,
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
async wrapChannel(conversation: DyFM_Msg_Conversation): Promise<DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>> {
|
|
426
|
-
return new DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>({
|
|
427
|
-
id: conversation._id,
|
|
428
|
-
name: conversation.title || conversation.platformChannelId || 'unknown',
|
|
429
|
-
isTextBased: true,
|
|
430
|
-
isDM: conversation.type === 'direct',
|
|
431
|
-
isVoiceBased: false,
|
|
432
|
-
rawPlatformChannel: conversation,
|
|
433
|
-
provider: this
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
async wrapUser(user: DyFM_Msg_Participant): Promise<DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>> {
|
|
438
|
-
return new DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>({
|
|
439
|
-
id: user.userId,
|
|
440
|
-
username: user.username,
|
|
441
|
-
displayName: user.displayName,
|
|
442
|
-
isBot: false,
|
|
443
|
-
rawPlatformUser: user,
|
|
444
|
-
provider: this
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
}
|
|
1
|
+
import { DyFM_AnyError, DyFM_Array, DyFM_Error, DyFM_Log, week } from '@futdevpro/fsm-dynamo';
|
|
2
|
+
import {
|
|
3
|
+
DyFM_Msg_Provider_Type, DyFM_Msg_Conversation, DyFM_Msg_EventKey, DyFM_Msg_Message, DyFM_Msg_Participant
|
|
4
|
+
} from '@futdevpro/fsm-dynamo/messaging';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
DyNTS_Bot_MessagingProvider_ServiceBase, DyNTS_Bot_MessagingProvider_Config
|
|
8
|
+
} from '../../../_services/bot-messaging-provider.service-base';
|
|
9
|
+
import { DyNTS_Bot_ChannelWrapper } from '../../../_models/bot-channel-wrapper.interface';
|
|
10
|
+
import { DyNTS_Bot_LastMessageDate } from '../../../_models/bot-last-message-date.interface';
|
|
11
|
+
import { DyNTS_Bot_LastMentionDate } from '../../../_models/bot-last-mention-date.interface';
|
|
12
|
+
import { DyNTS_Bot_MessageWrapper } from '../../../_models/bot-message-wrapper.interface';
|
|
13
|
+
import { DyNTS_Bot_UserWrapper } from '../../../_models/bot-user-wrapper.interface';
|
|
14
|
+
import { DyNTS_DyB_Message, DyNTS_DyB_Channel, DyNTS_DyB_User } from '../_models/dyb-platform.types';
|
|
15
|
+
import { DyNTS_global_settings } from '../../../../../_collections/global-settings.const';
|
|
16
|
+
import { DyNTS_Msg_Main_ControlService } from '../../../../messaging/_services/msg-main.control-service';
|
|
17
|
+
import { DyNTS_Msg_Message_DataService } from '../../../../messaging/_services/msg-message.data-service';
|
|
18
|
+
import { DyNTS_Msg_Conversation_DataService } from '../../../../messaging/_services/msg-conversation.data-service';
|
|
19
|
+
import { DyNTS_Msg_Events_Service } from '../../../../messaging/_services/msg-events.service';
|
|
20
|
+
|
|
21
|
+
export interface Dynamo_MessagingProviderConfig extends DyNTS_Bot_MessagingProvider_Config {
|
|
22
|
+
botUserId?: string;
|
|
23
|
+
botDisplayName?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class DyNTS_DyB_MessagingProvider_ControlService extends DyNTS_Bot_MessagingProvider_ServiceBase<
|
|
27
|
+
DyFM_Msg_Conversation,
|
|
28
|
+
DyFM_Msg_Message,
|
|
29
|
+
DyFM_Msg_Participant,
|
|
30
|
+
Dynamo_MessagingProviderConfig,
|
|
31
|
+
any
|
|
32
|
+
> {
|
|
33
|
+
readonly name = 'dynamo';
|
|
34
|
+
readonly type = DyFM_Msg_Provider_Type.dynamo;
|
|
35
|
+
|
|
36
|
+
get botId(): string {
|
|
37
|
+
return this.config.botUserId || 'dynamo-bot';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get botDisplayName(): string {
|
|
41
|
+
return this.config.botDisplayName || 'Dynamo Bot';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
readonly config: Dynamo_MessagingProviderConfig;
|
|
45
|
+
|
|
46
|
+
/* protected override readonly channelCache: Map<string, DyFM_Msg_Conversation> = new Map();
|
|
47
|
+
protected override readonly roleCache: Map<string, any> = new Map(); */
|
|
48
|
+
|
|
49
|
+
// Services
|
|
50
|
+
private messaging_CS: DyNTS_Msg_Main_ControlService;
|
|
51
|
+
private eventsService: DyNTS_Msg_Events_Service;
|
|
52
|
+
|
|
53
|
+
constructor(setConfig: Dynamo_MessagingProviderConfig) {
|
|
54
|
+
super();
|
|
55
|
+
this.config = setConfig;
|
|
56
|
+
this.messaging_CS = DyNTS_Msg_Main_ControlService.getInstance();
|
|
57
|
+
this.eventsService = DyNTS_Msg_Events_Service.getInstance();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async setup(issuer: string): Promise<void> {
|
|
61
|
+
try {
|
|
62
|
+
DyFM_Log.success('Dynamo bot provider setup completed');
|
|
63
|
+
} catch (error) {
|
|
64
|
+
DyFM_Error.logSimple('Error during Dynamo bot setup:', error);
|
|
65
|
+
|
|
66
|
+
throw new DyFM_Error({
|
|
67
|
+
...this.getDefaultErrorSettings('setup', error, issuer),
|
|
68
|
+
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-DyB-MessagingProvider-S000`,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async start(issuer: string): Promise<void> {
|
|
74
|
+
try {
|
|
75
|
+
// Setup event listeners for messaging events
|
|
76
|
+
this.setupEventListeners();
|
|
77
|
+
DyFM_Log.success('Dynamo bot provider started');
|
|
78
|
+
} catch (error) {
|
|
79
|
+
DyFM_Error.logSimple('Error during Dynamo bot start:', error);
|
|
80
|
+
|
|
81
|
+
throw new DyFM_Error({
|
|
82
|
+
...this.getDefaultErrorSettings('start', error, issuer),
|
|
83
|
+
errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-DyB-MessagingProvider-S001`,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private setupEventListeners(): void {
|
|
89
|
+
// Listen to messaging events and convert them to bot events
|
|
90
|
+
// Note: This would require extending the events service to support custom listeners
|
|
91
|
+
// For now, we'll implement a basic approach
|
|
92
|
+
DyFM_Log.info('Dynamo bot event listeners setup (messaging integration)');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Channel operations
|
|
96
|
+
async getChannelByName(name: string): Promise<DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>> {
|
|
97
|
+
if (this.channelCache.has(name)) {
|
|
98
|
+
return await this.wrapChannel(this.channelCache.get(name));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const conversationService: DyNTS_Msg_Conversation_DataService = new DyNTS_Msg_Conversation_DataService({
|
|
102
|
+
issuer: 'dynamo-bot',
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Try to find conversation by name or platformChannelId
|
|
106
|
+
const conversation: DyFM_Msg_Conversation = await conversationService.dataDBService.findOne({
|
|
107
|
+
$or: [
|
|
108
|
+
{ name: name },
|
|
109
|
+
{ platformChannelId: name }
|
|
110
|
+
],
|
|
111
|
+
__deleted: { $exists: false }
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (!conversation) {
|
|
115
|
+
throw new Error(`No conversation found with name "${name}"`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.channelCache.set(name, conversation);
|
|
119
|
+
return await this.wrapChannel(conversation);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async getChannelById(id: string): Promise<DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>> {
|
|
123
|
+
if (this.channelCache.has(id)) {
|
|
124
|
+
return await this.wrapChannel(this.channelCache.get(id));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const conversationService: DyNTS_Msg_Conversation_DataService = new DyNTS_Msg_Conversation_DataService({
|
|
128
|
+
issuer: 'dynamo-bot',
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const conversation: DyFM_Msg_Conversation = await conversationService.dataDBService.findOne({
|
|
132
|
+
_id: id,
|
|
133
|
+
__deleted: { $exists: false }
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
if (!conversation) {
|
|
137
|
+
throw new Error(`No conversation found with ID "${id}"`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
this.channelCache.set(id, conversation);
|
|
141
|
+
return await this.wrapChannel(conversation);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async sendMessageToChannel(channel: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>, message: string, issuer: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
145
|
+
const msg: DyFM_Msg_Message = await this.messaging_CS.sendMessage(channel.id, { content: message }, this.botId, issuer);
|
|
146
|
+
|
|
147
|
+
return await this.wrapMessage(msg);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async sendMessageToChannelByName(channelName: string, message: string, issuer: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
151
|
+
const channel: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
152
|
+
return this.sendMessageToChannel(channel, message, issuer);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async getMessagesFromChannelByChannelName(channelName: string, limit: number = 100): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[]> {
|
|
156
|
+
const channel: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
157
|
+
return this.fetchMessages(channel, limit);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async getLastMessageInChannel(channelName: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
161
|
+
const channel: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
162
|
+
const messages: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[] = await this.fetchMessages(channel, 1);
|
|
163
|
+
return messages.length > 0 ? messages[0] : null;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async clearChannel(channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>): Promise<void> {
|
|
167
|
+
// For messaging system, we don't actually delete messages
|
|
168
|
+
// This could be implemented to mark messages as deleted or archived
|
|
169
|
+
DyFM_Log.warn('Clear channel not implemented for messaging system');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async replyToMessage(messageWrapper: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>, content: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
173
|
+
// In messaging system, we can't directly reply to a message
|
|
174
|
+
// Instead, we'll send a new message with reference to the original
|
|
175
|
+
const replyContent: string = `[Reply to message ${messageWrapper.id}] ${content}`;
|
|
176
|
+
|
|
177
|
+
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(messageWrapper.channelName);
|
|
178
|
+
return this.sendMessageToChannel(channelWrapper, replyContent, messageWrapper.issuer);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async sendTyping(channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>): Promise<void> {
|
|
182
|
+
// Typing indicators not implemented for messaging system
|
|
183
|
+
DyFM_Log.info('Typing indicator not supported in messaging system');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async sendTypingForMessage(messageWrapper: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>): Promise<void> {
|
|
187
|
+
// Typing indicators not implemented for messaging system
|
|
188
|
+
DyFM_Log.info('Typing indicator not supported in messaging system');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async fetchMessages(channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>, limit: number): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[]> {
|
|
192
|
+
const messageService: DyNTS_Msg_Message_DataService = new DyNTS_Msg_Message_DataService({
|
|
193
|
+
issuer: 'dynamo-bot',
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const messages: DyFM_Msg_Message[] = await messageService.dataDBService.find({
|
|
197
|
+
conversationId: channelWrapper.id,
|
|
198
|
+
__deleted: { $exists: false },
|
|
199
|
+
$sort: { sentAt: -1 },
|
|
200
|
+
$limit: limit
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
return await DyFM_Array.asyncMap(messages, async (msg: DyFM_Msg_Message) => await this.wrapMessage(msg));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async fetchMessagesById(id: string, limit: number): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[]> {
|
|
207
|
+
const messageService: DyNTS_Msg_Message_DataService = new DyNTS_Msg_Message_DataService({
|
|
208
|
+
issuer: 'dynamo-bot',
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const messages: DyFM_Msg_Message[] = await messageService.dataDBService.find({
|
|
212
|
+
_id: id,
|
|
213
|
+
__deleted: { $exists: false },
|
|
214
|
+
$sort: { sentAt: -1 },
|
|
215
|
+
$limit: limit
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
return await DyFM_Array.asyncMap(messages, async (msg: DyFM_Msg_Message) => await this.wrapMessage(msg));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async fetchMessagesForMessage(messageWrapper: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>, limit: number): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[]> {
|
|
222
|
+
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(messageWrapper.channelName);
|
|
223
|
+
return this.fetchMessages(channelWrapper, limit);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async fetchAllMessagesWithPaging(channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>, maxFetch: number = 1000): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[]> {
|
|
227
|
+
return this.fetchMessages(channelWrapper, maxFetch);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async deleteMessage(messageWrapper: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>): Promise<void> {
|
|
231
|
+
await this.messaging_CS.deleteMessage(messageWrapper.id, 'dynamo-bot', 'dynamo-bot');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async updateMessage(message: DyFM_Msg_Message, issuer: string): Promise<void> {
|
|
235
|
+
await this.messaging_CS.modifyMessage(message, issuer);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// User operations
|
|
239
|
+
async getUserByName(username: string): Promise<DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>> {
|
|
240
|
+
// In messaging system, we don't have a direct user lookup by name
|
|
241
|
+
// This would need to be implemented based on your user management system
|
|
242
|
+
const userData: any = {
|
|
243
|
+
userId: username,
|
|
244
|
+
username: username,
|
|
245
|
+
displayName: username,
|
|
246
|
+
isBot: false,
|
|
247
|
+
role: 'member',
|
|
248
|
+
joinedAt: new Date()
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
return await this.wrapUser(userData);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
getUserMention(userId: string): string {
|
|
255
|
+
return `@${userId}`;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async readMembersInChannel(channelName: string): Promise<DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>[]> {
|
|
259
|
+
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
260
|
+
const participants: DyFM_Msg_Participant[] = channelWrapper.rawPlatformChannel.participants || [];
|
|
261
|
+
|
|
262
|
+
return await DyFM_Array.asyncMap(participants, async (participant: DyFM_Msg_Participant) => await this.wrapUser(participant));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
async readMemberNamesInChannel(channelName: string): Promise<string[]> {
|
|
266
|
+
const members: DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>[] = await this.readMembersInChannel(channelName);
|
|
267
|
+
return members.map(member => member.username);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Advanced message queries
|
|
271
|
+
async getLastMessageSentBy(channelName: string, username: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
272
|
+
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
273
|
+
const messages: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[] = await this.fetchAllMessagesWithPaging(channelWrapper, 1000);
|
|
274
|
+
|
|
275
|
+
return messages.find(msg => msg.authorName === username) || null;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async getLastMentionOf(channelName: string, username: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
279
|
+
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
280
|
+
const messages: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[] = await this.fetchAllMessagesWithPaging(channelWrapper, 1000);
|
|
281
|
+
|
|
282
|
+
return messages.find(msg =>
|
|
283
|
+
msg.content.includes(`@${username}`) ||
|
|
284
|
+
msg.content.includes(username)
|
|
285
|
+
) || null;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async readLastMessageDatesByMembers(channelName: string, memberNames: string[]): Promise<DyNTS_Bot_LastMessageDate[]> {
|
|
289
|
+
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
290
|
+
const messages: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[] = await this.fetchAllMessagesWithPaging(channelWrapper, 1000);
|
|
291
|
+
|
|
292
|
+
const memberStatus: Record<string, { lastMessageDate: Date | null, allMessages: number }> = {};
|
|
293
|
+
memberNames.forEach((name: string) => {
|
|
294
|
+
memberStatus[name] = { lastMessageDate: null, allMessages: 0 };
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
const cutoffTime: number = Date.now() - (3 * week); // 3 weeks
|
|
298
|
+
|
|
299
|
+
messages.forEach((message: DyNTS_DyB_Message) => {
|
|
300
|
+
if (message.timestamp < cutoffTime) return;
|
|
301
|
+
|
|
302
|
+
const author = message.authorName;
|
|
303
|
+
if (memberStatus[author] !== undefined) {
|
|
304
|
+
memberStatus[author].allMessages++;
|
|
305
|
+
if (!memberStatus[author].lastMessageDate) {
|
|
306
|
+
memberStatus[author].lastMessageDate = new Date(message.timestamp);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
return memberNames.map((memberName: string) => {
|
|
312
|
+
const status: { lastMessageDate: Date | null, allMessages: number } = memberStatus[memberName];
|
|
313
|
+
return {
|
|
314
|
+
memberName: memberName,
|
|
315
|
+
allMessages: status.allMessages,
|
|
316
|
+
lastMessageDate: status.lastMessageDate
|
|
317
|
+
};
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async readLastMessageWithMemberNamePingInIt(channelName: string, users: DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>[]): Promise<DyNTS_Bot_LastMentionDate[]> {
|
|
322
|
+
const channelWrapper: DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation> = await this.getChannelByName(channelName);
|
|
323
|
+
const messages: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>[] = await this.fetchAllMessagesWithPaging(channelWrapper, 1000);
|
|
324
|
+
|
|
325
|
+
const memberStatus: Record<string, { lastMentionDate: Date | null; allMentions: number }> = {};
|
|
326
|
+
users.forEach((user: DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>) => {
|
|
327
|
+
memberStatus[user.username] = { lastMentionDate: null, allMentions: 0 };
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
const cutoffTime: number = Date.now() - (3 * week); // 3 weeks
|
|
331
|
+
|
|
332
|
+
messages.forEach((message: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>) => {
|
|
333
|
+
if (message.timestamp < cutoffTime) return;
|
|
334
|
+
|
|
335
|
+
users.forEach((user: DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>) => {
|
|
336
|
+
if (
|
|
337
|
+
message.content.includes(`@${user.id}`) &&
|
|
338
|
+
!memberStatus[user.username].lastMentionDate
|
|
339
|
+
) {
|
|
340
|
+
memberStatus[user.username].lastMentionDate = new Date(message.timestamp);
|
|
341
|
+
memberStatus[user.username].allMentions++;
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
return users.map((user: DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>) => {
|
|
347
|
+
const status: { lastMentionDate: Date | null; allMentions: number } = memberStatus[user.username];
|
|
348
|
+
return {
|
|
349
|
+
memberId: user.id,
|
|
350
|
+
memberName: user.username,
|
|
351
|
+
allMentions: status.allMentions,
|
|
352
|
+
lastMentionDate: status.lastMentionDate
|
|
353
|
+
};
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Platform-specific features (not applicable for messaging system)
|
|
358
|
+
getRoleByName?(roleName: string): any {
|
|
359
|
+
return null; // Not applicable for messaging system
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
getRolePingByName?(roleName: string): Promise<string> {
|
|
363
|
+
return Promise.resolve(''); // Not applicable for messaging system
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
getRolePingsByName?(roleNames: string[]): Promise<string> {
|
|
367
|
+
return Promise.resolve(''); // Not applicable for messaging system
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Event binding
|
|
371
|
+
async create_onMessageEventListener(
|
|
372
|
+
handler: (message: DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>, issuer: string) => Promise<void>
|
|
373
|
+
): Promise<void> {
|
|
374
|
+
// TODO: Implement message event listener for messaging system
|
|
375
|
+
DyFM_Log.info('Message event listener created (messaging integration)');
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
create_onErrorEventListener(handler: (error: DyFM_AnyError) => void): void {
|
|
379
|
+
// TODO: Implement error event listener for messaging system
|
|
380
|
+
DyFM_Log.info('Error event listener created (messaging integration)');
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
async sendReport(message: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
384
|
+
return await this.sendMessageToChannelByName(this.config.reportChannelName, message, 'dynamo-bot');
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
async sendReportIn(message: string): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
388
|
+
return await this.sendMessageToChannelByName(
|
|
389
|
+
this.config.reportChannelName,
|
|
390
|
+
`${this.botDisplayName} report for duty! ` +
|
|
391
|
+
`(v${DyNTS_global_settings.systemVersion} ${DyNTS_global_settings.env_settings?.environment})`,
|
|
392
|
+
'dynamo-bot'
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
async wrapMessage(msgMessage: DyFM_Msg_Message): Promise<DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>> {
|
|
397
|
+
return new DyNTS_Bot_MessageWrapper<DyFM_Msg_Message>({
|
|
398
|
+
id: msgMessage._id,
|
|
399
|
+
content: msgMessage.content,
|
|
400
|
+
authorId: msgMessage.senderId,
|
|
401
|
+
authorName: msgMessage.senderName,
|
|
402
|
+
authorDisplayName: msgMessage.senderDisplayName,
|
|
403
|
+
channelId: msgMessage.conversationId,
|
|
404
|
+
channelName: msgMessage.conversationId,
|
|
405
|
+
timestamp: msgMessage.sentAt ? new Date(msgMessage.sentAt).getTime() : Date.now(),
|
|
406
|
+
isBot: msgMessage.isAIGenerated || false,
|
|
407
|
+
isTextBased: true,
|
|
408
|
+
isVoiceBased: false,
|
|
409
|
+
isDM: false,
|
|
410
|
+
replyToMessageId: msgMessage.parentMessageId,
|
|
411
|
+
replyToMessageAuthorId: null,
|
|
412
|
+
mentions: msgMessage.mentions.map(mention => mention.userId),
|
|
413
|
+
rawPlatformMessage: msgMessage,
|
|
414
|
+
|
|
415
|
+
issuer: msgMessage.senderId,
|
|
416
|
+
|
|
417
|
+
/* channel: this.wrapChannel(msgMessage.conversation), */
|
|
418
|
+
channel: null,
|
|
419
|
+
/* user: this.wrapUser(msgMessage.sender), */
|
|
420
|
+
|
|
421
|
+
provider: this,
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
async wrapChannel(conversation: DyFM_Msg_Conversation): Promise<DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>> {
|
|
426
|
+
return new DyNTS_Bot_ChannelWrapper<DyFM_Msg_Conversation>({
|
|
427
|
+
id: conversation._id,
|
|
428
|
+
name: conversation.title || conversation.platformChannelId || 'unknown',
|
|
429
|
+
isTextBased: true,
|
|
430
|
+
isDM: conversation.type === 'direct',
|
|
431
|
+
isVoiceBased: false,
|
|
432
|
+
rawPlatformChannel: conversation,
|
|
433
|
+
provider: this
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async wrapUser(user: DyFM_Msg_Participant): Promise<DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>> {
|
|
438
|
+
return new DyNTS_Bot_UserWrapper<DyFM_Msg_Participant>({
|
|
439
|
+
id: user.userId,
|
|
440
|
+
username: user.username,
|
|
441
|
+
displayName: user.displayName,
|
|
442
|
+
isBot: false,
|
|
443
|
+
rawPlatformUser: user,
|
|
444
|
+
provider: this
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|