@dementevdev/maxbot-ts 1.0.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/CHANGELOG.md +9 -0
- package/LICENSE +21 -0
- package/README.md +1176 -0
- package/dist/cjs/api/BotsApi.d.ts +17 -0
- package/dist/cjs/api/BotsApi.d.ts.map +1 -0
- package/dist/cjs/api/BotsApi.js +22 -0
- package/dist/cjs/api/ChatsApi.d.ts +87 -0
- package/dist/cjs/api/ChatsApi.d.ts.map +1 -0
- package/dist/cjs/api/ChatsApi.js +144 -0
- package/dist/cjs/api/MessagesApi.d.ts +41 -0
- package/dist/cjs/api/MessagesApi.d.ts.map +1 -0
- package/dist/cjs/api/MessagesApi.js +66 -0
- package/dist/cjs/api/SubscriptionsApi.d.ts +45 -0
- package/dist/cjs/api/SubscriptionsApi.d.ts.map +1 -0
- package/dist/cjs/api/SubscriptionsApi.js +69 -0
- package/dist/cjs/api/UploadsApi.d.ts +45 -0
- package/dist/cjs/api/UploadsApi.d.ts.map +1 -0
- package/dist/cjs/api/UploadsApi.js +113 -0
- package/dist/cjs/api/index.d.ts +7 -0
- package/dist/cjs/api/index.d.ts.map +1 -0
- package/dist/cjs/api/index.js +14 -0
- package/dist/cjs/api/interfaces.d.ts +108 -0
- package/dist/cjs/api/interfaces.d.ts.map +1 -0
- package/dist/cjs/api/interfaces.js +3 -0
- package/dist/cjs/bot/Bot.d.ts +380 -0
- package/dist/cjs/bot/Bot.d.ts.map +1 -0
- package/dist/cjs/bot/Bot.js +624 -0
- package/dist/cjs/bot/Composer.d.ts +131 -0
- package/dist/cjs/bot/Composer.d.ts.map +1 -0
- package/dist/cjs/bot/Composer.js +218 -0
- package/dist/cjs/bot/context/BotStartedContext.d.ts +83 -0
- package/dist/cjs/bot/context/BotStartedContext.d.ts.map +1 -0
- package/dist/cjs/bot/context/BotStartedContext.js +113 -0
- package/dist/cjs/bot/context/CallbackContext.d.ts +107 -0
- package/dist/cjs/bot/context/CallbackContext.d.ts.map +1 -0
- package/dist/cjs/bot/context/CallbackContext.js +158 -0
- package/dist/cjs/bot/context/ChatContext.d.ts +35 -0
- package/dist/cjs/bot/context/ChatContext.d.ts.map +1 -0
- package/dist/cjs/bot/context/ChatContext.js +52 -0
- package/dist/cjs/bot/context/MessageContext.d.ts +149 -0
- package/dist/cjs/bot/context/MessageContext.d.ts.map +1 -0
- package/dist/cjs/bot/context/MessageContext.js +228 -0
- package/dist/cjs/bot/context/guards.d.ts +69 -0
- package/dist/cjs/bot/context/guards.d.ts.map +1 -0
- package/dist/cjs/bot/context/guards.js +85 -0
- package/dist/cjs/bot/context/index.d.ts +6 -0
- package/dist/cjs/bot/context/index.d.ts.map +1 -0
- package/dist/cjs/bot/context/index.js +18 -0
- package/dist/cjs/bot/dispatch.d.ts +51 -0
- package/dist/cjs/bot/dispatch.d.ts.map +1 -0
- package/dist/cjs/bot/dispatch.js +201 -0
- package/dist/cjs/bot/index.d.ts +10 -0
- package/dist/cjs/bot/index.d.ts.map +1 -0
- package/dist/cjs/bot/index.js +24 -0
- package/dist/cjs/bot/lifecycle.d.ts +85 -0
- package/dist/cjs/bot/lifecycle.d.ts.map +1 -0
- package/dist/cjs/bot/lifecycle.js +167 -0
- package/dist/cjs/bot/metrics.d.ts +18 -0
- package/dist/cjs/bot/metrics.d.ts.map +1 -0
- package/dist/cjs/bot/metrics.js +3 -0
- package/dist/cjs/bot/routing.d.ts +131 -0
- package/dist/cjs/bot/routing.d.ts.map +1 -0
- package/dist/cjs/bot/routing.js +198 -0
- package/dist/cjs/bot/triggers.d.ts +61 -0
- package/dist/cjs/bot/triggers.d.ts.map +1 -0
- package/dist/cjs/bot/triggers.js +84 -0
- package/dist/cjs/core/errors/MaxError.d.ts +11 -0
- package/dist/cjs/core/errors/MaxError.d.ts.map +1 -0
- package/dist/cjs/core/errors/MaxError.js +19 -0
- package/dist/cjs/core/errors/errors.d.ts +59 -0
- package/dist/cjs/core/errors/errors.d.ts.map +1 -0
- package/dist/cjs/core/errors/errors.js +84 -0
- package/dist/cjs/core/errors/index.d.ts +3 -0
- package/dist/cjs/core/errors/index.d.ts.map +1 -0
- package/dist/cjs/core/errors/index.js +13 -0
- package/dist/cjs/core/http/HttpClient.d.ts +28 -0
- package/dist/cjs/core/http/HttpClient.d.ts.map +1 -0
- package/dist/cjs/core/http/HttpClient.js +148 -0
- package/dist/cjs/core/http/index.d.ts +3 -0
- package/dist/cjs/core/http/index.d.ts.map +1 -0
- package/dist/cjs/core/http/index.js +6 -0
- package/dist/cjs/core/http/interfaces.d.ts +42 -0
- package/dist/cjs/core/http/interfaces.d.ts.map +1 -0
- package/dist/cjs/core/http/interfaces.js +3 -0
- package/dist/cjs/core/rate-limiter/RateLimiter.d.ts +46 -0
- package/dist/cjs/core/rate-limiter/RateLimiter.d.ts.map +1 -0
- package/dist/cjs/core/rate-limiter/RateLimiter.js +110 -0
- package/dist/cjs/core/rate-limiter/index.d.ts +3 -0
- package/dist/cjs/core/rate-limiter/index.d.ts.map +1 -0
- package/dist/cjs/core/rate-limiter/index.js +6 -0
- package/dist/cjs/filters/index.d.ts +2 -0
- package/dist/cjs/filters/index.d.ts.map +1 -0
- package/dist/cjs/filters/index.js +10 -0
- package/dist/cjs/filters/predicates.d.ts +85 -0
- package/dist/cjs/filters/predicates.d.ts.map +1 -0
- package/dist/cjs/filters/predicates.js +111 -0
- package/dist/cjs/index.d.ts +11 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +27 -0
- package/dist/cjs/middleware/compose.d.ts +28 -0
- package/dist/cjs/middleware/compose.d.ts.map +1 -0
- package/dist/cjs/middleware/compose.js +89 -0
- package/dist/cjs/middleware/index.d.ts +3 -0
- package/dist/cjs/middleware/index.d.ts.map +1 -0
- package/dist/cjs/middleware/index.js +7 -0
- package/dist/cjs/middleware/types.d.ts +17 -0
- package/dist/cjs/middleware/types.d.ts.map +1 -0
- package/dist/cjs/middleware/types.js +3 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/transport/LongPollingTransport.d.ts +33 -0
- package/dist/cjs/transport/LongPollingTransport.d.ts.map +1 -0
- package/dist/cjs/transport/LongPollingTransport.js +153 -0
- package/dist/cjs/transport/WebhookTransport.d.ts +40 -0
- package/dist/cjs/transport/WebhookTransport.d.ts.map +1 -0
- package/dist/cjs/transport/WebhookTransport.js +229 -0
- package/dist/cjs/transport/index.d.ts +4 -0
- package/dist/cjs/transport/index.d.ts.map +1 -0
- package/dist/cjs/transport/index.js +8 -0
- package/dist/cjs/transport/interfaces.d.ts +74 -0
- package/dist/cjs/transport/interfaces.d.ts.map +1 -0
- package/dist/cjs/transport/interfaces.js +3 -0
- package/dist/cjs/types/bot.d.ts +19 -0
- package/dist/cjs/types/bot.d.ts.map +1 -0
- package/dist/cjs/types/bot.js +3 -0
- package/dist/cjs/types/chat.d.ts +94 -0
- package/dist/cjs/types/chat.d.ts.map +1 -0
- package/dist/cjs/types/chat.js +3 -0
- package/dist/cjs/types/common.d.ts +38 -0
- package/dist/cjs/types/common.d.ts.map +1 -0
- package/dist/cjs/types/common.js +6 -0
- package/dist/cjs/types/index.d.ts +9 -0
- package/dist/cjs/types/index.d.ts.map +1 -0
- package/dist/cjs/types/index.js +26 -0
- package/dist/cjs/types/keyboard.d.ts +97 -0
- package/dist/cjs/types/keyboard.d.ts.map +1 -0
- package/dist/cjs/types/keyboard.js +3 -0
- package/dist/cjs/types/message.d.ts +162 -0
- package/dist/cjs/types/message.d.ts.map +1 -0
- package/dist/cjs/types/message.js +3 -0
- package/dist/cjs/types/subscription.d.ts +23 -0
- package/dist/cjs/types/subscription.d.ts.map +1 -0
- package/dist/cjs/types/subscription.js +3 -0
- package/dist/cjs/types/update.d.ts +99 -0
- package/dist/cjs/types/update.d.ts.map +1 -0
- package/dist/cjs/types/update.js +3 -0
- package/dist/cjs/types/upload.d.ts +29 -0
- package/dist/cjs/types/upload.d.ts.map +1 -0
- package/dist/cjs/types/upload.js +3 -0
- package/dist/cjs/utils/Histogram.d.ts +93 -0
- package/dist/cjs/utils/Histogram.d.ts.map +1 -0
- package/dist/cjs/utils/Histogram.js +103 -0
- package/dist/cjs/utils/assertNever.d.ts +19 -0
- package/dist/cjs/utils/assertNever.d.ts.map +1 -0
- package/dist/cjs/utils/assertNever.js +24 -0
- package/dist/cjs/utils/format.d.ts +22 -0
- package/dist/cjs/utils/format.d.ts.map +1 -0
- package/dist/cjs/utils/format.js +25 -0
- package/dist/cjs/utils/index.d.ts +6 -0
- package/dist/cjs/utils/index.d.ts.map +1 -0
- package/dist/cjs/utils/index.js +14 -0
- package/dist/cjs/utils/keyboard.d.ts +70 -0
- package/dist/cjs/utils/keyboard.d.ts.map +1 -0
- package/dist/cjs/utils/keyboard.js +166 -0
- package/dist/esm/api/BotsApi.d.ts +17 -0
- package/dist/esm/api/BotsApi.d.ts.map +1 -0
- package/dist/esm/api/BotsApi.js +18 -0
- package/dist/esm/api/ChatsApi.d.ts +87 -0
- package/dist/esm/api/ChatsApi.d.ts.map +1 -0
- package/dist/esm/api/ChatsApi.js +140 -0
- package/dist/esm/api/MessagesApi.d.ts +41 -0
- package/dist/esm/api/MessagesApi.d.ts.map +1 -0
- package/dist/esm/api/MessagesApi.js +62 -0
- package/dist/esm/api/SubscriptionsApi.d.ts +45 -0
- package/dist/esm/api/SubscriptionsApi.d.ts.map +1 -0
- package/dist/esm/api/SubscriptionsApi.js +65 -0
- package/dist/esm/api/UploadsApi.d.ts +45 -0
- package/dist/esm/api/UploadsApi.d.ts.map +1 -0
- package/dist/esm/api/UploadsApi.js +109 -0
- package/dist/esm/api/index.d.ts +7 -0
- package/dist/esm/api/index.d.ts.map +1 -0
- package/dist/esm/api/index.js +6 -0
- package/dist/esm/api/interfaces.d.ts +108 -0
- package/dist/esm/api/interfaces.d.ts.map +1 -0
- package/dist/esm/api/interfaces.js +2 -0
- package/dist/esm/bot/Bot.d.ts +380 -0
- package/dist/esm/bot/Bot.d.ts.map +1 -0
- package/dist/esm/bot/Bot.js +620 -0
- package/dist/esm/bot/Composer.d.ts +131 -0
- package/dist/esm/bot/Composer.d.ts.map +1 -0
- package/dist/esm/bot/Composer.js +214 -0
- package/dist/esm/bot/context/BotStartedContext.d.ts +83 -0
- package/dist/esm/bot/context/BotStartedContext.d.ts.map +1 -0
- package/dist/esm/bot/context/BotStartedContext.js +109 -0
- package/dist/esm/bot/context/CallbackContext.d.ts +107 -0
- package/dist/esm/bot/context/CallbackContext.d.ts.map +1 -0
- package/dist/esm/bot/context/CallbackContext.js +154 -0
- package/dist/esm/bot/context/ChatContext.d.ts +35 -0
- package/dist/esm/bot/context/ChatContext.d.ts.map +1 -0
- package/dist/esm/bot/context/ChatContext.js +48 -0
- package/dist/esm/bot/context/MessageContext.d.ts +149 -0
- package/dist/esm/bot/context/MessageContext.d.ts.map +1 -0
- package/dist/esm/bot/context/MessageContext.js +224 -0
- package/dist/esm/bot/context/guards.d.ts +69 -0
- package/dist/esm/bot/context/guards.d.ts.map +1 -0
- package/dist/esm/bot/context/guards.js +78 -0
- package/dist/esm/bot/context/index.d.ts +6 -0
- package/dist/esm/bot/context/index.d.ts.map +1 -0
- package/dist/esm/bot/context/index.js +6 -0
- package/dist/esm/bot/dispatch.d.ts +51 -0
- package/dist/esm/bot/dispatch.d.ts.map +1 -0
- package/dist/esm/bot/dispatch.js +197 -0
- package/dist/esm/bot/index.d.ts +10 -0
- package/dist/esm/bot/index.d.ts.map +1 -0
- package/dist/esm/bot/index.js +9 -0
- package/dist/esm/bot/lifecycle.d.ts +85 -0
- package/dist/esm/bot/lifecycle.d.ts.map +1 -0
- package/dist/esm/bot/lifecycle.js +163 -0
- package/dist/esm/bot/metrics.d.ts +18 -0
- package/dist/esm/bot/metrics.d.ts.map +1 -0
- package/dist/esm/bot/metrics.js +2 -0
- package/dist/esm/bot/routing.d.ts +131 -0
- package/dist/esm/bot/routing.d.ts.map +1 -0
- package/dist/esm/bot/routing.js +194 -0
- package/dist/esm/bot/triggers.d.ts +61 -0
- package/dist/esm/bot/triggers.d.ts.map +1 -0
- package/dist/esm/bot/triggers.js +80 -0
- package/dist/esm/core/errors/MaxError.d.ts +11 -0
- package/dist/esm/core/errors/MaxError.d.ts.map +1 -0
- package/dist/esm/core/errors/MaxError.js +15 -0
- package/dist/esm/core/errors/errors.d.ts +59 -0
- package/dist/esm/core/errors/errors.d.ts.map +1 -0
- package/dist/esm/core/errors/errors.js +75 -0
- package/dist/esm/core/errors/index.d.ts +3 -0
- package/dist/esm/core/errors/index.d.ts.map +1 -0
- package/dist/esm/core/errors/index.js +3 -0
- package/dist/esm/core/http/HttpClient.d.ts +28 -0
- package/dist/esm/core/http/HttpClient.d.ts.map +1 -0
- package/dist/esm/core/http/HttpClient.js +144 -0
- package/dist/esm/core/http/index.d.ts +3 -0
- package/dist/esm/core/http/index.d.ts.map +1 -0
- package/dist/esm/core/http/index.js +2 -0
- package/dist/esm/core/http/interfaces.d.ts +42 -0
- package/dist/esm/core/http/interfaces.d.ts.map +1 -0
- package/dist/esm/core/http/interfaces.js +2 -0
- package/dist/esm/core/rate-limiter/RateLimiter.d.ts +46 -0
- package/dist/esm/core/rate-limiter/RateLimiter.d.ts.map +1 -0
- package/dist/esm/core/rate-limiter/RateLimiter.js +106 -0
- package/dist/esm/core/rate-limiter/index.d.ts +3 -0
- package/dist/esm/core/rate-limiter/index.d.ts.map +1 -0
- package/dist/esm/core/rate-limiter/index.js +2 -0
- package/dist/esm/filters/index.d.ts +2 -0
- package/dist/esm/filters/index.d.ts.map +1 -0
- package/dist/esm/filters/index.js +2 -0
- package/dist/esm/filters/predicates.d.ts +85 -0
- package/dist/esm/filters/predicates.d.ts.map +1 -0
- package/dist/esm/filters/predicates.js +104 -0
- package/dist/esm/index.d.ts +11 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/middleware/compose.d.ts +28 -0
- package/dist/esm/middleware/compose.d.ts.map +1 -0
- package/dist/esm/middleware/compose.js +85 -0
- package/dist/esm/middleware/index.d.ts +3 -0
- package/dist/esm/middleware/index.d.ts.map +1 -0
- package/dist/esm/middleware/index.js +2 -0
- package/dist/esm/middleware/types.d.ts +17 -0
- package/dist/esm/middleware/types.d.ts.map +1 -0
- package/dist/esm/middleware/types.js +2 -0
- package/dist/esm/transport/LongPollingTransport.d.ts +33 -0
- package/dist/esm/transport/LongPollingTransport.d.ts.map +1 -0
- package/dist/esm/transport/LongPollingTransport.js +149 -0
- package/dist/esm/transport/WebhookTransport.d.ts +40 -0
- package/dist/esm/transport/WebhookTransport.d.ts.map +1 -0
- package/dist/esm/transport/WebhookTransport.js +225 -0
- package/dist/esm/transport/index.d.ts +4 -0
- package/dist/esm/transport/index.d.ts.map +1 -0
- package/dist/esm/transport/index.js +3 -0
- package/dist/esm/transport/interfaces.d.ts +74 -0
- package/dist/esm/transport/interfaces.d.ts.map +1 -0
- package/dist/esm/transport/interfaces.js +2 -0
- package/dist/esm/types/bot.d.ts +19 -0
- package/dist/esm/types/bot.d.ts.map +1 -0
- package/dist/esm/types/bot.js +2 -0
- package/dist/esm/types/chat.d.ts +94 -0
- package/dist/esm/types/chat.d.ts.map +1 -0
- package/dist/esm/types/chat.js +2 -0
- package/dist/esm/types/common.d.ts +38 -0
- package/dist/esm/types/common.d.ts.map +1 -0
- package/dist/esm/types/common.js +5 -0
- package/dist/esm/types/index.d.ts +9 -0
- package/dist/esm/types/index.d.ts.map +1 -0
- package/dist/esm/types/index.js +10 -0
- package/dist/esm/types/keyboard.d.ts +97 -0
- package/dist/esm/types/keyboard.d.ts.map +1 -0
- package/dist/esm/types/keyboard.js +2 -0
- package/dist/esm/types/message.d.ts +162 -0
- package/dist/esm/types/message.d.ts.map +1 -0
- package/dist/esm/types/message.js +2 -0
- package/dist/esm/types/subscription.d.ts +23 -0
- package/dist/esm/types/subscription.d.ts.map +1 -0
- package/dist/esm/types/subscription.js +2 -0
- package/dist/esm/types/update.d.ts +99 -0
- package/dist/esm/types/update.d.ts.map +1 -0
- package/dist/esm/types/update.js +2 -0
- package/dist/esm/types/upload.d.ts +29 -0
- package/dist/esm/types/upload.d.ts.map +1 -0
- package/dist/esm/types/upload.js +2 -0
- package/dist/esm/utils/Histogram.d.ts +93 -0
- package/dist/esm/utils/Histogram.d.ts.map +1 -0
- package/dist/esm/utils/Histogram.js +99 -0
- package/dist/esm/utils/assertNever.d.ts +19 -0
- package/dist/esm/utils/assertNever.d.ts.map +1 -0
- package/dist/esm/utils/assertNever.js +21 -0
- package/dist/esm/utils/format.d.ts +22 -0
- package/dist/esm/utils/format.d.ts.map +1 -0
- package/dist/esm/utils/format.js +22 -0
- package/dist/esm/utils/index.d.ts +6 -0
- package/dist/esm/utils/index.d.ts.map +1 -0
- package/dist/esm/utils/index.js +5 -0
- package/dist/esm/utils/keyboard.d.ts +70 -0
- package/dist/esm/utils/keyboard.d.ts.map +1 -0
- package/dist/esm/utils/keyboard.js +162 -0
- package/dist/types/api/BotsApi.d.ts +17 -0
- package/dist/types/api/BotsApi.d.ts.map +1 -0
- package/dist/types/api/ChatsApi.d.ts +87 -0
- package/dist/types/api/ChatsApi.d.ts.map +1 -0
- package/dist/types/api/MessagesApi.d.ts +41 -0
- package/dist/types/api/MessagesApi.d.ts.map +1 -0
- package/dist/types/api/SubscriptionsApi.d.ts +45 -0
- package/dist/types/api/SubscriptionsApi.d.ts.map +1 -0
- package/dist/types/api/UploadsApi.d.ts +45 -0
- package/dist/types/api/UploadsApi.d.ts.map +1 -0
- package/dist/types/api/index.d.ts +7 -0
- package/dist/types/api/index.d.ts.map +1 -0
- package/dist/types/api/interfaces.d.ts +108 -0
- package/dist/types/api/interfaces.d.ts.map +1 -0
- package/dist/types/bot/Bot.d.ts +380 -0
- package/dist/types/bot/Bot.d.ts.map +1 -0
- package/dist/types/bot/Composer.d.ts +131 -0
- package/dist/types/bot/Composer.d.ts.map +1 -0
- package/dist/types/bot/context/BotStartedContext.d.ts +83 -0
- package/dist/types/bot/context/BotStartedContext.d.ts.map +1 -0
- package/dist/types/bot/context/CallbackContext.d.ts +107 -0
- package/dist/types/bot/context/CallbackContext.d.ts.map +1 -0
- package/dist/types/bot/context/ChatContext.d.ts +35 -0
- package/dist/types/bot/context/ChatContext.d.ts.map +1 -0
- package/dist/types/bot/context/MessageContext.d.ts +149 -0
- package/dist/types/bot/context/MessageContext.d.ts.map +1 -0
- package/dist/types/bot/context/guards.d.ts +69 -0
- package/dist/types/bot/context/guards.d.ts.map +1 -0
- package/dist/types/bot/context/index.d.ts +6 -0
- package/dist/types/bot/context/index.d.ts.map +1 -0
- package/dist/types/bot/dispatch.d.ts +51 -0
- package/dist/types/bot/dispatch.d.ts.map +1 -0
- package/dist/types/bot/index.d.ts +10 -0
- package/dist/types/bot/index.d.ts.map +1 -0
- package/dist/types/bot/lifecycle.d.ts +85 -0
- package/dist/types/bot/lifecycle.d.ts.map +1 -0
- package/dist/types/bot/metrics.d.ts +18 -0
- package/dist/types/bot/metrics.d.ts.map +1 -0
- package/dist/types/bot/routing.d.ts +131 -0
- package/dist/types/bot/routing.d.ts.map +1 -0
- package/dist/types/bot/triggers.d.ts +61 -0
- package/dist/types/bot/triggers.d.ts.map +1 -0
- package/dist/types/core/errors/MaxError.d.ts +11 -0
- package/dist/types/core/errors/MaxError.d.ts.map +1 -0
- package/dist/types/core/errors/errors.d.ts +59 -0
- package/dist/types/core/errors/errors.d.ts.map +1 -0
- package/dist/types/core/errors/index.d.ts +3 -0
- package/dist/types/core/errors/index.d.ts.map +1 -0
- package/dist/types/core/http/HttpClient.d.ts +28 -0
- package/dist/types/core/http/HttpClient.d.ts.map +1 -0
- package/dist/types/core/http/index.d.ts +3 -0
- package/dist/types/core/http/index.d.ts.map +1 -0
- package/dist/types/core/http/interfaces.d.ts +42 -0
- package/dist/types/core/http/interfaces.d.ts.map +1 -0
- package/dist/types/core/rate-limiter/RateLimiter.d.ts +46 -0
- package/dist/types/core/rate-limiter/RateLimiter.d.ts.map +1 -0
- package/dist/types/core/rate-limiter/index.d.ts +3 -0
- package/dist/types/core/rate-limiter/index.d.ts.map +1 -0
- package/dist/types/filters/index.d.ts +2 -0
- package/dist/types/filters/index.d.ts.map +1 -0
- package/dist/types/filters/predicates.d.ts +85 -0
- package/dist/types/filters/predicates.d.ts.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/middleware/compose.d.ts +28 -0
- package/dist/types/middleware/compose.d.ts.map +1 -0
- package/dist/types/middleware/index.d.ts +3 -0
- package/dist/types/middleware/index.d.ts.map +1 -0
- package/dist/types/middleware/types.d.ts +17 -0
- package/dist/types/middleware/types.d.ts.map +1 -0
- package/dist/types/transport/LongPollingTransport.d.ts +33 -0
- package/dist/types/transport/LongPollingTransport.d.ts.map +1 -0
- package/dist/types/transport/WebhookTransport.d.ts +40 -0
- package/dist/types/transport/WebhookTransport.d.ts.map +1 -0
- package/dist/types/transport/index.d.ts +4 -0
- package/dist/types/transport/index.d.ts.map +1 -0
- package/dist/types/transport/interfaces.d.ts +74 -0
- package/dist/types/transport/interfaces.d.ts.map +1 -0
- package/dist/types/types/bot.d.ts +19 -0
- package/dist/types/types/bot.d.ts.map +1 -0
- package/dist/types/types/chat.d.ts +94 -0
- package/dist/types/types/chat.d.ts.map +1 -0
- package/dist/types/types/common.d.ts +38 -0
- package/dist/types/types/common.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +9 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/types/keyboard.d.ts +97 -0
- package/dist/types/types/keyboard.d.ts.map +1 -0
- package/dist/types/types/message.d.ts +162 -0
- package/dist/types/types/message.d.ts.map +1 -0
- package/dist/types/types/subscription.d.ts +23 -0
- package/dist/types/types/subscription.d.ts.map +1 -0
- package/dist/types/types/update.d.ts +99 -0
- package/dist/types/types/update.d.ts.map +1 -0
- package/dist/types/types/upload.d.ts +29 -0
- package/dist/types/types/upload.d.ts.map +1 -0
- package/dist/types/utils/Histogram.d.ts +93 -0
- package/dist/types/utils/Histogram.d.ts.map +1 -0
- package/dist/types/utils/assertNever.d.ts +19 -0
- package/dist/types/utils/assertNever.d.ts.map +1 -0
- package/dist/types/utils/format.d.ts +22 -0
- package/dist/types/utils/format.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +6 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/keyboard.d.ts +70 -0
- package/dist/types/utils/keyboard.d.ts.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Bot = void 0;
|
|
4
|
+
const index_js_1 = require("../api/index.js");
|
|
5
|
+
const HttpClient_js_1 = require("../core/http/HttpClient.js");
|
|
6
|
+
const RateLimiter_js_1 = require("../core/rate-limiter/RateLimiter.js");
|
|
7
|
+
const LongPollingTransport_js_1 = require("../transport/LongPollingTransport.js");
|
|
8
|
+
const WebhookTransport_js_1 = require("../transport/WebhookTransport.js");
|
|
9
|
+
const CallbackContext_js_1 = require("./context/CallbackContext.js");
|
|
10
|
+
const ChatContext_js_1 = require("./context/ChatContext.js");
|
|
11
|
+
const BotStartedContext_js_1 = require("./context/BotStartedContext.js");
|
|
12
|
+
const MessageContext_js_1 = require("./context/MessageContext.js");
|
|
13
|
+
const assertNever_js_1 = require("../utils/assertNever.js");
|
|
14
|
+
const compose_js_1 = require("../middleware/compose.js");
|
|
15
|
+
const guards_js_1 = require("./context/guards.js");
|
|
16
|
+
const triggers_js_1 = require("./triggers.js");
|
|
17
|
+
const BASE_URL = "https://platform-api.max.ru";
|
|
18
|
+
/**
|
|
19
|
+
* Главный класс бота.
|
|
20
|
+
*
|
|
21
|
+
* Параметр `Ctx` задаёт тип контекста, передаваемого в middleware и handlers.
|
|
22
|
+
* По умолчанию — базовый `Context = MessageContext | CallbackContext | ChatContext`.
|
|
23
|
+
* Используй `contextFactory` в конфиге чтобы расширить контекст своими полями.
|
|
24
|
+
*
|
|
25
|
+
* @example Базовое использование
|
|
26
|
+
* const bot = new Bot({ token: '...', transport: 'polling' });
|
|
27
|
+
*
|
|
28
|
+
* @example Расширенный контекст
|
|
29
|
+
* const bot = new Bot<MyCtx>({ token: '...', transport: 'polling', contextFactory: buildCtx });
|
|
30
|
+
*/
|
|
31
|
+
class Bot {
|
|
32
|
+
/** Доступ к низкоуровневым API для продвинутых сценариев */
|
|
33
|
+
api;
|
|
34
|
+
http;
|
|
35
|
+
transport;
|
|
36
|
+
contextApi;
|
|
37
|
+
_contextFactory;
|
|
38
|
+
handlers = new Map();
|
|
39
|
+
middlewares = [];
|
|
40
|
+
errorHandler = null;
|
|
41
|
+
slowHandler = null;
|
|
42
|
+
slowThresholdMs = 0;
|
|
43
|
+
unknownUpdateHandler = null;
|
|
44
|
+
metricsHandler = null;
|
|
45
|
+
// Семафор для backpressure: ограничивает число параллельных обработчиков.
|
|
46
|
+
concurrency;
|
|
47
|
+
activeCount = 0;
|
|
48
|
+
waitQueue = [];
|
|
49
|
+
// Promise-мьютекс: не null пока бот запущен или останавливается.
|
|
50
|
+
// Использование Promise вместо boolean-флага устраняет race condition:
|
|
51
|
+
// конкурентный вызов start() во время stop() получит актуальный статус
|
|
52
|
+
// без окна между проверкой флага и его установкой.
|
|
53
|
+
startPromise = null;
|
|
54
|
+
constructor(config) {
|
|
55
|
+
// Собираем граф зависимостей — каждый компонент получает только то, что ему нужно
|
|
56
|
+
const rateLimiter = config.rateLimiter ?? new RateLimiter_js_1.RateLimiter();
|
|
57
|
+
// Если contextFactory не задана — идентичная функция (Ctx = Context по умолчанию)
|
|
58
|
+
this._contextFactory = config.contextFactory ?? ((base) => base);
|
|
59
|
+
this.unknownUpdateHandler = config.onUnknownUpdate ?? null;
|
|
60
|
+
this.metricsHandler = config.onMetrics ?? null;
|
|
61
|
+
this.http = new HttpClient_js_1.HttpClient({
|
|
62
|
+
baseUrl: config.baseUrl ?? BASE_URL,
|
|
63
|
+
token: config.token,
|
|
64
|
+
rateLimiter,
|
|
65
|
+
});
|
|
66
|
+
// Инициализируем API-сервисы
|
|
67
|
+
const bots = new index_js_1.BotsApi(this.http);
|
|
68
|
+
const chats = new index_js_1.ChatsApi(this.http);
|
|
69
|
+
const messages = new index_js_1.MessagesApi(this.http);
|
|
70
|
+
const subscriptions = new index_js_1.SubscriptionsApi(this.http);
|
|
71
|
+
// Токен передаётся явно — UploadsApi использует его для прямых fetch-запросов
|
|
72
|
+
const uploads = new index_js_1.UploadsApi(this.http, config.token);
|
|
73
|
+
this.api = { bots, chats, messages, subscriptions, uploads };
|
|
74
|
+
this.contextApi = { bots, chats, messages, subscriptions, uploads };
|
|
75
|
+
// Выбираем стратегию транспорта — паттерн Strategy
|
|
76
|
+
this.transport =
|
|
77
|
+
config.transport === "webhook"
|
|
78
|
+
? new WebhookTransport_js_1.WebhookTransport(subscriptions, config.webhook)
|
|
79
|
+
: new LongPollingTransport_js_1.LongPollingTransport(subscriptions, config.polling);
|
|
80
|
+
const concurrency = config.concurrency ?? 10;
|
|
81
|
+
if (!(concurrency === Infinity ||
|
|
82
|
+
(Number.isInteger(concurrency) && concurrency > 0))) {
|
|
83
|
+
throw new Error("Параметр concurrency должен быть положительным целым числом или Infinity");
|
|
84
|
+
}
|
|
85
|
+
this.concurrency = concurrency;
|
|
86
|
+
this.transport.onUpdate(this.handleUpdate.bind(this));
|
|
87
|
+
this.transport.onError(this.handleError.bind(this));
|
|
88
|
+
}
|
|
89
|
+
// ==================== Управление webhook ====================
|
|
90
|
+
/**
|
|
91
|
+
* Установить URL для webhook.
|
|
92
|
+
*/
|
|
93
|
+
async setWebhookUrl(url) {
|
|
94
|
+
await this.api.subscriptions.subscribe({ url });
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Удалить webhook.
|
|
98
|
+
*/
|
|
99
|
+
async deleteWebhook() {
|
|
100
|
+
await this.api.subscriptions.unsubscribe();
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Получить информацию о текущем webhook.
|
|
104
|
+
*/
|
|
105
|
+
async getWebhookInfo() {
|
|
106
|
+
return this.api.subscriptions.getSubscriptions();
|
|
107
|
+
}
|
|
108
|
+
// ==================== Регистрация обработчиков ====================
|
|
109
|
+
/**
|
|
110
|
+
* Зарегистрировать один или несколько обработчиков для события message_created.
|
|
111
|
+
*
|
|
112
|
+
* При нескольких аргументах промежуточные middleware должны вызывать `next()`;
|
|
113
|
+
* последний аргумент — финальный обработчик (next не нужен).
|
|
114
|
+
*
|
|
115
|
+
* @example С промежуточным middleware
|
|
116
|
+
* bot.onMessage(authMw, async (ctx) => { await ctx.reply('OK'); });
|
|
117
|
+
*/
|
|
118
|
+
onMessage(...fns) {
|
|
119
|
+
return this.on("message_created", ...fns);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Зарегистрировать один или несколько обработчиков для callback-запросов.
|
|
123
|
+
*
|
|
124
|
+
* При нескольких аргументах промежуточные middleware должны вызывать `next()`.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* bot.onCallback(logMw, async (ctx) => { ... });
|
|
128
|
+
*/
|
|
129
|
+
onCallback(...fns) {
|
|
130
|
+
return this.on("message_callback", ...fns);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Зарегистрировать обработчик для события `bot_started`.
|
|
134
|
+
*
|
|
135
|
+
* Срабатывает когда пользователь нажимает Start в диалоге или переходит по deep link.
|
|
136
|
+
*
|
|
137
|
+
* @example Onboarding с deep link
|
|
138
|
+
* bot.onStart(async (ctx) => {
|
|
139
|
+
* if (isBotStartedContext(ctx) && ctx.startPayload) {
|
|
140
|
+
* await ctx.reply(`Вы пришли по реферальной ссылке: ${ctx.startPayload}`);
|
|
141
|
+
* } else {
|
|
142
|
+
* await ctx.reply('Добро пожаловать!');
|
|
143
|
+
* }
|
|
144
|
+
* });
|
|
145
|
+
*/
|
|
146
|
+
onStart(...fns) {
|
|
147
|
+
return this.on("bot_started", ...fns);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Зарегистрировать один или несколько обработчиков для любого типа обновления.
|
|
151
|
+
*
|
|
152
|
+
* При нескольких аргументах промежуточные middleware должны вызывать `next()`;
|
|
153
|
+
* последний аргумент — финальный обработчик.
|
|
154
|
+
*
|
|
155
|
+
* @example Один обработчик (прежнее поведение)
|
|
156
|
+
* bot.on('message_created', async (ctx) => { ... });
|
|
157
|
+
*
|
|
158
|
+
* @example Несколько middleware + обработчик
|
|
159
|
+
* bot.on('message_created', authMw, rateLimitMw, async (ctx) => { ... });
|
|
160
|
+
*/
|
|
161
|
+
on(event, ...fns) {
|
|
162
|
+
const composed = this.pipe(...fns);
|
|
163
|
+
const handlers = this.handlers.get(event) ?? [];
|
|
164
|
+
handlers.push(composed);
|
|
165
|
+
this.handlers.set(event, handlers);
|
|
166
|
+
return this;
|
|
167
|
+
}
|
|
168
|
+
/** Цепочка из middleware: возвращает единый EventHandler, вызывающий каждый fn по очереди. */
|
|
169
|
+
pipe(...fns) {
|
|
170
|
+
if (fns.length === 1)
|
|
171
|
+
return fns[0];
|
|
172
|
+
return (0, compose_js_1.compose)(fns, async () => { });
|
|
173
|
+
}
|
|
174
|
+
// ==================== Composer sugar ====================
|
|
175
|
+
/**
|
|
176
|
+
* Зарегистрировать обработчик команды.
|
|
177
|
+
*
|
|
178
|
+
* Срабатывает на `message_created`, если текст сообщения начинается с `/<name>` (с аргументами или без).
|
|
179
|
+
* Обработчик получает полный `Ctx` — для сужения до `MessageContext` используй `isMessageContext(ctx)`.
|
|
180
|
+
*
|
|
181
|
+
* @param name - Имя команды без слеша (`start`, `help`, и т.\u0434.)
|
|
182
|
+
* @param fns - Один или несколько middleware/обработчиков. Промежуточные должны вызывать `next()`.
|
|
183
|
+
*
|
|
184
|
+
* @example Один обработчик
|
|
185
|
+
* bot.command('start', async (ctx) => {
|
|
186
|
+
* if (isMessageContext(ctx)) await ctx.reply('Добро пожаловать!');
|
|
187
|
+
* });
|
|
188
|
+
*
|
|
189
|
+
* @example Массив команд
|
|
190
|
+
* bot.command(['start', 'begin'], async (ctx) => {
|
|
191
|
+
* await ctx.reply('Добро пожаловать!');
|
|
192
|
+
* });
|
|
193
|
+
*
|
|
194
|
+
* @example С промежуточными middleware
|
|
195
|
+
* bot.command('pay', authMw, checkBalanceMw, async (ctx) => {
|
|
196
|
+
* await ctx.reply('Оплата выполнена');
|
|
197
|
+
* });
|
|
198
|
+
*/
|
|
199
|
+
command(name, ...fns) {
|
|
200
|
+
const composed = this.pipe(...fns);
|
|
201
|
+
return this.on("message_created", async (ctx) => {
|
|
202
|
+
if (!(0, guards_js_1.isMessageContext)(ctx))
|
|
203
|
+
return;
|
|
204
|
+
if ((0, triggers_js_1.matchCommand)(name, ctx.text ?? "")) {
|
|
205
|
+
await composed(ctx);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Зарегистрировать обработчик по regexp- или строковому фильтру текста сообщения.
|
|
211
|
+
*
|
|
212
|
+
* Срабатывает на `message_created`, если `ctx.text` совпадает с `pattern`.
|
|
213
|
+
*
|
|
214
|
+
* @param pattern - Строка (точное совпадение) или `RegExp`
|
|
215
|
+
* @param fns - Один или несколько middleware/обработчиков. Промежуточные должны вызывать `next()`.
|
|
216
|
+
*
|
|
217
|
+
* @example Один обработчик
|
|
218
|
+
* bot.hears('привет', async (ctx) => { ... });
|
|
219
|
+
* bot.hears(/^\u043fр/i, async (ctx) => { ... });
|
|
220
|
+
* bot.hears(/(\d+)/, async (ctx) => {
|
|
221
|
+
* if (isMessageContext(ctx)) console.log(ctx.match?.[1]); // группа захвата
|
|
222
|
+
* });
|
|
223
|
+
*
|
|
224
|
+
* @example С промежуточными middleware
|
|
225
|
+
* bot.hears(/^\u043fоплата/, authMw, async (ctx) => { ... });
|
|
226
|
+
*/
|
|
227
|
+
hears(pattern, ...fns) {
|
|
228
|
+
const composed = this.pipe(...fns);
|
|
229
|
+
return this.on("message_created", async (ctx) => {
|
|
230
|
+
if (!(0, guards_js_1.isMessageContext)(ctx))
|
|
231
|
+
return;
|
|
232
|
+
const result = (0, triggers_js_1.matchTrigger)(pattern, ctx.text ?? "");
|
|
233
|
+
if (result !== null) {
|
|
234
|
+
if (result !== true)
|
|
235
|
+
ctx.match = result;
|
|
236
|
+
await composed(ctx);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Зарегистрировать обработчик по `callback.payload`.
|
|
242
|
+
*
|
|
243
|
+
* Срабатывает на `message_callback`, если `ctx.data` совпадает с `pattern`.
|
|
244
|
+
*
|
|
245
|
+
* @param pattern - Строка (точное совпадение) или `RegExp`
|
|
246
|
+
* @param fns - Один или несколько middleware/обработчиков. Промежуточные должны вызывать `next()`.
|
|
247
|
+
*
|
|
248
|
+
* @example Один обработчик
|
|
249
|
+
* bot.action('buy', async (ctx) => { ... });
|
|
250
|
+
* bot.action(/^action:/, async (ctx) => { ... });
|
|
251
|
+
* bot.action(/^buy:(\d+)$/, async (ctx) => {
|
|
252
|
+
* if (isCallbackContext(ctx)) console.log(ctx.match?.[1]); // id из payload
|
|
253
|
+
* });
|
|
254
|
+
*
|
|
255
|
+
* @example С промежуточными middleware
|
|
256
|
+
* bot.action(/^buy:/, authMw, checkStockMw, async (ctx) => { ... });
|
|
257
|
+
*/
|
|
258
|
+
action(pattern, ...fns) {
|
|
259
|
+
const composed = this.pipe(...fns);
|
|
260
|
+
return this.on("message_callback", async (ctx) => {
|
|
261
|
+
if (!(0, guards_js_1.isCallbackContext)(ctx))
|
|
262
|
+
return;
|
|
263
|
+
const result = (0, triggers_js_1.matchTrigger)(pattern, ctx.data);
|
|
264
|
+
if (result !== null) {
|
|
265
|
+
if (result !== true)
|
|
266
|
+
ctx.match = result;
|
|
267
|
+
await composed(ctx);
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Зарегистрировать middleware, выполняемый перед обработчиками события.
|
|
273
|
+
*
|
|
274
|
+
* Middleware выполняется **внутри** семафорного слота — backpressure применяется
|
|
275
|
+
* ко всему пайплайну целиком, а не только к финальным хендлерам.
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* bot.use(async (ctx, next) => {
|
|
279
|
+
* console.log('before handlers');
|
|
280
|
+
* await next();
|
|
281
|
+
* console.log('after handlers');
|
|
282
|
+
* });
|
|
283
|
+
*/
|
|
284
|
+
use(middleware) {
|
|
285
|
+
this.middlewares.push(middleware);
|
|
286
|
+
return this;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Подключить middleware только если предикат возвращает `true`.
|
|
290
|
+
*
|
|
291
|
+
* Сочетается с предикатами из модуля `filters` и с `ctx.has()` для type narrowing.
|
|
292
|
+
* Если предикат не сработал — обновление прозрачно перетекает к следующим middleware.
|
|
293
|
+
*
|
|
294
|
+
* @example Только сообщения с текстом
|
|
295
|
+
* ```ts
|
|
296
|
+
* bot.filter(hasText, async (ctx) => {
|
|
297
|
+
* console.log(ctx.text.toUpperCase()); // ctx.text: string
|
|
298
|
+
* });
|
|
299
|
+
* ```
|
|
300
|
+
*
|
|
301
|
+
* @example Комбинация с Composer
|
|
302
|
+
* ```ts
|
|
303
|
+
* const privateRouter = new Composer();
|
|
304
|
+
* privateRouter.command('start', handler);
|
|
305
|
+
* bot.filter(isPrivateChat, privateRouter.middleware());
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
filter(predicate, ...fns) {
|
|
309
|
+
this.use(async (ctx, next) => {
|
|
310
|
+
if (predicate(ctx)) {
|
|
311
|
+
await (0, compose_js_1.compose)(fns, async () => { })(ctx);
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
await next();
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
return this;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Зарегистрировать обработчик ошибок.
|
|
321
|
+
*/
|
|
322
|
+
onError(handler) {
|
|
323
|
+
this.errorHandler = handler;
|
|
324
|
+
return this;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Назначить коллбэк для медленных обработчиков.
|
|
328
|
+
*
|
|
329
|
+
* Если обработка обновления (включая middleware и handlers) заняла больше `thresholdMs` мс,
|
|
330
|
+
* вызывается `cb` с фактическим временем выполнения и типом обновления.
|
|
331
|
+
*
|
|
332
|
+
* Используйте для SLO-мониторинга и диагностики производительности.
|
|
333
|
+
*
|
|
334
|
+
* @param thresholdMs - Пороговое значение в миллисекундах
|
|
335
|
+
* @param cb - Коллбэк, получающий фактическое время выполнения (ms) и тип обновления
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* bot.onSlowHandler(500, (ms, type) => {
|
|
339
|
+
* log.warn({ ms, type }, 'slow handler detected');
|
|
340
|
+
* });
|
|
341
|
+
*/
|
|
342
|
+
onSlowHandler(thresholdMs, cb) {
|
|
343
|
+
this.slowThresholdMs = thresholdMs;
|
|
344
|
+
this.slowHandler = cb;
|
|
345
|
+
return this;
|
|
346
|
+
}
|
|
347
|
+
// ==================== Удобные методы ====================
|
|
348
|
+
/**
|
|
349
|
+
* Получить информацию о боте.
|
|
350
|
+
*/
|
|
351
|
+
async getMe() {
|
|
352
|
+
return this.api.bots.getMe();
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Отправить сообщение в чат.
|
|
356
|
+
*/
|
|
357
|
+
async sendMessage(chatId, text, options) {
|
|
358
|
+
const body = {
|
|
359
|
+
text,
|
|
360
|
+
format: options?.format,
|
|
361
|
+
attachments: options?.attachments,
|
|
362
|
+
notify: options?.notify,
|
|
363
|
+
};
|
|
364
|
+
const response = await this.api.messages.sendMessage({ chat_id: chatId, disable_link_preview: options?.disable_link_preview }, body);
|
|
365
|
+
return response.message;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Отправить личное сообщение пользователю.
|
|
369
|
+
*/
|
|
370
|
+
async sendPrivateMessage(userId, text, options) {
|
|
371
|
+
const body = {
|
|
372
|
+
text,
|
|
373
|
+
format: options?.format,
|
|
374
|
+
attachments: options?.attachments,
|
|
375
|
+
notify: options?.notify,
|
|
376
|
+
};
|
|
377
|
+
const response = await this.api.messages.sendMessage({ user_id: userId, disable_link_preview: options?.disable_link_preview }, body);
|
|
378
|
+
return response.message;
|
|
379
|
+
}
|
|
380
|
+
// ==================== Жизненный цикл ====================
|
|
381
|
+
/**
|
|
382
|
+
* Запустить бота.
|
|
383
|
+
*/
|
|
384
|
+
async start() {
|
|
385
|
+
// Если уже есть активный Promise запуска/остановки — бот занят.
|
|
386
|
+
// Ждём завершения и только потом решаем, можно ли стартовать.
|
|
387
|
+
if (this.startPromise !== null) {
|
|
388
|
+
await this.startPromise;
|
|
389
|
+
throw new Error("Бот уже запущен. Вызовите stop() перед повторным запуском.");
|
|
390
|
+
}
|
|
391
|
+
// Сохраняем Promise до первого await — в JS между синхронными строками
|
|
392
|
+
// нет переключения контекста, поэтому конкурентный вызов увидит startPromise
|
|
393
|
+
// уже установленным ещё до любого await внутри _doStart().
|
|
394
|
+
const startTask = this._doStart();
|
|
395
|
+
this.startPromise = startTask;
|
|
396
|
+
try {
|
|
397
|
+
await startTask;
|
|
398
|
+
}
|
|
399
|
+
catch (error) {
|
|
400
|
+
// Сбрасываем только если это всё ещё актуальный lifecycle task.
|
|
401
|
+
// Если параллельно начался stop(), startPromise уже указывает на stop-task.
|
|
402
|
+
if (this.startPromise === startTask) {
|
|
403
|
+
this.startPromise = null;
|
|
404
|
+
}
|
|
405
|
+
throw error;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
async _doStart() {
|
|
409
|
+
// Проверка токена до запуска — fail fast.
|
|
410
|
+
// Лучше узнать о невалидном токене сразу, чем при первом обновлении.
|
|
411
|
+
await this.api.bots.getMe();
|
|
412
|
+
await this.transport.start();
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Остановить бота.
|
|
416
|
+
*/
|
|
417
|
+
async stop() {
|
|
418
|
+
if (this.startPromise === null) {
|
|
419
|
+
return; // уже остановлен — идемпотентно
|
|
420
|
+
}
|
|
421
|
+
const lifecycleTask = this.startPromise;
|
|
422
|
+
const stopTask = (async () => {
|
|
423
|
+
// Дожидаемся завершения запуска перед остановкой, чтобы transport.stop()
|
|
424
|
+
// всегда вызывался после transport.start().
|
|
425
|
+
try {
|
|
426
|
+
await lifecycleTask;
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
/* start упал — transport уже не запущен */
|
|
430
|
+
}
|
|
431
|
+
await this.transport.stop();
|
|
432
|
+
})();
|
|
433
|
+
// Держим mutex до полного завершения stop() — это закрывает окно гонки,
|
|
434
|
+
// в котором параллельный start() мог пройти до фактической остановки.
|
|
435
|
+
this.startPromise = stopTask;
|
|
436
|
+
try {
|
|
437
|
+
await stopTask;
|
|
438
|
+
}
|
|
439
|
+
finally {
|
|
440
|
+
if (this.startPromise === stopTask) {
|
|
441
|
+
this.startPromise = null;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
// ==================== Внутренние методы ====================
|
|
446
|
+
handleUpdate(update) {
|
|
447
|
+
let ctx;
|
|
448
|
+
try {
|
|
449
|
+
const base = this.createContext(update);
|
|
450
|
+
// null — знак что update_type неизвестен и хук onUnknownUpdate уже вызван;
|
|
451
|
+
// пропускаем update без ошибки
|
|
452
|
+
if (base === null)
|
|
453
|
+
return;
|
|
454
|
+
ctx = this._contextFactory(base);
|
|
455
|
+
}
|
|
456
|
+
catch (error) {
|
|
457
|
+
this.handleError(error instanceof Error ? error : new Error(String(error)));
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const handlers = this.handlers.get(update.update_type) ?? [];
|
|
461
|
+
// Пропускаем только если нет ни middleware, ни handlers — тогда обрабатывать
|
|
462
|
+
// буквально нечего и мы не занимаем слот семафора впустую.
|
|
463
|
+
// Если есть хотя бы middleware — запускаем пайплайн: глобальные middleware
|
|
464
|
+
// (логирование, трейсинг) должны видеть ВСЕ update типы.
|
|
465
|
+
if (this.middlewares.length === 0 && handlers.length === 0)
|
|
466
|
+
return;
|
|
467
|
+
// Запускаем обработку через семафор — гарантируем не более concurrency
|
|
468
|
+
// параллельных задач. Каждое обновление обрабатывается как единица:
|
|
469
|
+
// все его хендлеры выполняются параллельно внутри одного слота семафора.
|
|
470
|
+
void this.runHandlersWithSemaphore(ctx, handlers, update.update_type);
|
|
471
|
+
}
|
|
472
|
+
async runHandlersWithSemaphore(ctx, handlers, updateType) {
|
|
473
|
+
const needMetrics = this.metricsHandler !== null;
|
|
474
|
+
const needSlow = this.slowHandler !== null;
|
|
475
|
+
// Размер очереди ДО захвата слота — показывает реальное давление
|
|
476
|
+
const queueSizeAtStart = this.waitQueue.length;
|
|
477
|
+
await this.acquireSemaphore();
|
|
478
|
+
const start = needMetrics || needSlow ? Date.now() : 0;
|
|
479
|
+
let handlerErrors = 0;
|
|
480
|
+
const middlewareTimes = [];
|
|
481
|
+
try {
|
|
482
|
+
// Финальный обработчик — запускает все зарегистрированные handlers параллельно
|
|
483
|
+
const finalHandler = async (c) => {
|
|
484
|
+
await Promise.all(handlers.map(async (handler) => {
|
|
485
|
+
try {
|
|
486
|
+
await handler(c);
|
|
487
|
+
}
|
|
488
|
+
catch (error) {
|
|
489
|
+
handlerErrors++;
|
|
490
|
+
this.handleError(error instanceof Error ? error : new Error(String(error)));
|
|
491
|
+
}
|
|
492
|
+
}));
|
|
493
|
+
};
|
|
494
|
+
// Весь пайплайн [middlewares... → handlers] выполняется внутри одного
|
|
495
|
+
// семафорного слота — backpressure применяется ко всему цепочке целиком.
|
|
496
|
+
const pipeline = needMetrics
|
|
497
|
+
? (0, compose_js_1.composeWithTiming)(this.middlewares, finalHandler, middlewareTimes)
|
|
498
|
+
: (0, compose_js_1.compose)(this.middlewares, finalHandler);
|
|
499
|
+
await pipeline(ctx);
|
|
500
|
+
}
|
|
501
|
+
finally {
|
|
502
|
+
const elapsed = needMetrics || needSlow ? Date.now() - start : 0;
|
|
503
|
+
if (needSlow && elapsed >= this.slowThresholdMs) {
|
|
504
|
+
try {
|
|
505
|
+
this.slowHandler?.(elapsed, updateType);
|
|
506
|
+
}
|
|
507
|
+
catch {
|
|
508
|
+
// Ошибки наблюдателей не должны влиять на основной поток
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
if (needMetrics) {
|
|
512
|
+
try {
|
|
513
|
+
this.metricsHandler?.({
|
|
514
|
+
updateType,
|
|
515
|
+
totalMs: elapsed,
|
|
516
|
+
queueSizeAtStart,
|
|
517
|
+
handlerErrors,
|
|
518
|
+
middlewareTimes,
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
catch {
|
|
522
|
+
// Ошибки наблюдателей не должны влиять на основной поток
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
this.releaseSemaphore();
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Захватить слот семафора.
|
|
530
|
+
* Если свободных слотов нет — ждём в очереди.
|
|
531
|
+
*/
|
|
532
|
+
acquireSemaphore() {
|
|
533
|
+
if (this.activeCount < this.concurrency) {
|
|
534
|
+
this.activeCount++;
|
|
535
|
+
return Promise.resolve();
|
|
536
|
+
}
|
|
537
|
+
return new Promise((resolve) => {
|
|
538
|
+
this.waitQueue.push(resolve);
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Освободить слот семафора и разбудить следующего в очереди.
|
|
543
|
+
*/
|
|
544
|
+
releaseSemaphore() {
|
|
545
|
+
const next = this.waitQueue.shift();
|
|
546
|
+
if (next) {
|
|
547
|
+
// Передаём слот напрямую — activeCount не меняется
|
|
548
|
+
next();
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
this.activeCount--;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
handleError(error) {
|
|
555
|
+
if (this.errorHandler) {
|
|
556
|
+
try {
|
|
557
|
+
this.errorHandler(error);
|
|
558
|
+
}
|
|
559
|
+
catch {
|
|
560
|
+
// Игнорируем ошибки в обработчике ошибок
|
|
561
|
+
console.error("Ошибка в обработчике ошибок:", error);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
// По умолчанию логируем в консоль
|
|
566
|
+
console.error("Ошибка бота:", error);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Создаёт типизированный контекст из сырого обновления.
|
|
571
|
+
*
|
|
572
|
+
* Возвращает `null` если `update_type` неизвестен SDK **и** задан хук
|
|
573
|
+
* {@link BotConfig.onUnknownUpdate} — хук уже вызван, update нужно пропустить.
|
|
574
|
+
* Если хук не задан — бросает ошибку через {@link assertNever} → `errorHandler`.
|
|
575
|
+
*
|
|
576
|
+
* ### Обработка неизвестных update_type
|
|
577
|
+
*
|
|
578
|
+
* TypeScript гарантирует exhaustiveness: если появится новый `update_type`
|
|
579
|
+
* в типах `Update`, компилятор выдаст ошибку в `default`-ветке через
|
|
580
|
+
* {@link assertNever}. Это предотвращает рантайм-краши при изменении типов.
|
|
581
|
+
*
|
|
582
|
+
* **Рантайм-сценарий**: Если платформа присылает `update_type`, которого
|
|
583
|
+
* **нет в типах SDK** (например, новая версия API), используй
|
|
584
|
+
* {@link BotConfig.onUnknownUpdate} для явного контроля:
|
|
585
|
+
*
|
|
586
|
+
* ```typescript
|
|
587
|
+
* const bot = new Bot({
|
|
588
|
+
* token: '...',
|
|
589
|
+
* transport: 'polling',
|
|
590
|
+
* onUnknownUpdate: (raw) => console.warn('unknown update_type:', raw.update_type),
|
|
591
|
+
* });
|
|
592
|
+
* ```
|
|
593
|
+
*/
|
|
594
|
+
createContext(update) {
|
|
595
|
+
switch (update.update_type) {
|
|
596
|
+
case "message_callback":
|
|
597
|
+
return new CallbackContext_js_1.CallbackContext(update, this.contextApi);
|
|
598
|
+
case "message_created":
|
|
599
|
+
case "message_edited":
|
|
600
|
+
case "message_removed":
|
|
601
|
+
return new MessageContext_js_1.MessageContext(update, this.contextApi);
|
|
602
|
+
case "bot_added":
|
|
603
|
+
case "bot_removed":
|
|
604
|
+
case "user_added":
|
|
605
|
+
case "user_removed":
|
|
606
|
+
case "chat_title_changed":
|
|
607
|
+
return new ChatContext_js_1.ChatContext(update);
|
|
608
|
+
case "bot_started":
|
|
609
|
+
return new BotStartedContext_js_1.BotStartedContext(update, this.contextApi);
|
|
610
|
+
default:
|
|
611
|
+
// TypeScript проверит здесь что все варианты UpdateType обработаны выше.
|
|
612
|
+
// Если появится новый update_type — будет ошибка компиляции, а не рантайм-краш.
|
|
613
|
+
if (this.unknownUpdateHandler) {
|
|
614
|
+
// Хук вызван, возвращаем null — handleUpdate пропустит update без ошибки
|
|
615
|
+
this.unknownUpdateHandler(update);
|
|
616
|
+
return null;
|
|
617
|
+
}
|
|
618
|
+
// Хук не задан — бросаем ошибку, она уйдёт в errorHandler
|
|
619
|
+
return (0, assertNever_js_1.assertNever)(update);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
exports.Bot = Bot;
|
|
624
|
+
//# sourceMappingURL=Bot.js.map
|