UNPKG

23.6 kBTypeScriptView Raw
1/**
2 * @module botkit
3 */
4/**
5 * Copyright (c) Microsoft Corporation. All rights reserved.
6 * Licensed under the MIT License.
7 */
8import { Activity, Storage, ConversationReference, TurnContext, BotAdapter } from 'botbuilder';
9import { Dialog, DialogSet } from 'botbuilder-dialogs';
10import { BotWorker } from './botworker';
11/**
12 * Defines the options used when instantiating Botkit to create the main app controller with `new Botkit(options)`
13 */
14export interface BotkitConfiguration {
15 /**
16 * Path used to create incoming webhook URI. Defaults to `/api/messages`
17 */
18 webhook_uri?: string;
19 /**
20 * Name of the dialogState property in the ConversationState that will be used to automatically track the dialog state. Defaults to `dialogState`.
21 */
22 dialogStateProperty?: string;
23 /**
24 * A fully configured BotBuilder Adapter, such as `botbuilder-adapter-slack` or `botbuilder-adapter-web`
25 * The adapter is responsible for translating platform-specific messages into the format understood by Botkit and BotBuilder.
26 */
27 adapter?: any;
28 /**
29 * If using the BotFramework service, options included in `adapterConfig` will be passed to the new Adapter when created internally.
30 * See [BotFrameworkAdapterSettings](https://docs.microsoft.com/en-us/javascript/api/botbuilder/botframeworkadaptersettings?view=azure-node-latest&viewFallbackFrom=botbuilder-ts-latest).
31 */
32 adapterConfig?: {
33 [key: string]: any;
34 };
35 /**
36 * An instance of Express used to define web endpoints. If not specified, one will be created internally.
37 * Note: only use your own Express if you absolutely must for some reason. Otherwise, use `controller.webserver`
38 */
39 webserver?: any;
40 /**
41 * An array of middlewares that will be automatically bound to the webserver.
42 * Should be in the form (req, res, next) => {}
43 */
44 webserver_middlewares?: any[];
45 /**
46 * A Storage interface compatible with [this specification](https://docs.microsoft.com/en-us/javascript/api/botbuilder-core/storage?view=botbuilder-ts-latest)
47 * Defaults to the ephemeral [MemoryStorage](https://docs.microsoft.com/en-us/javascript/api/botbuilder-core/memorystorage?view=botbuilder-ts-latest) implementation.
48 */
49 storage?: Storage;
50 /**
51 * Disable webserver. If true, Botkit will not create a webserver or expose any webhook endpoints automatically. Defaults to false.
52 */
53 disable_webserver?: boolean;
54 /**
55 * Disable messages normally sent to the console during startup.
56 */
57 disable_console?: boolean;
58 /**
59 * Limit of the size of incoming JSON payloads parsed by the Express bodyParser. Defaults to '100kb'
60 */
61 jsonLimit?: string;
62 /**
63 * Limit of the size of incoming URL encoded payloads parsed by the Express bodyParser. Defaults to '100kb'
64 */
65 urlEncodedLimit?: string;
66}
67/**
68 * Defines the expected form of a message or event object being handled by Botkit.
69 * Will also contain any additional fields including in the incoming payload.
70 */
71export interface BotkitMessage {
72 /**
73 * The type of event, in most cases defined by the messaging channel or adapter
74 */
75 type: string;
76 /**
77 * Text of the message sent by the user (or primary value in case of button click)
78 */
79 text?: string;
80 /**
81 * Any value field received from the platform
82 */
83 value?: string;
84 /**
85 * Unique identifier of user who sent the message. Typically contains the platform specific user id.
86 */
87 user: string;
88 /**
89 * Unique identifier of the room/channel/space in which the message was sent. Typically contains the platform specific designator for that channel.
90 */
91 channel: string;
92 /**
93 * A full [ConversationReference](https://docs.microsoft.com/en-us/javascript/api/botframework-schema/conversationreference?view=botbuilder-ts-latest) object that defines the address of the message and all information necessary to send messages back to the originating location.
94 * Can be stored for later use, and used with [bot.changeContext()](#changeContext) to send proactive messages.
95 */
96 reference: ConversationReference;
97 /**
98 * The original incoming [BotBuilder Activity](https://docs.microsoft.com/en-us/javascript/api/botframework-schema/activity?view=botbuilder-ts-latest) object as created by the adapter.
99 */
100 incoming_message: Activity;
101 /**
102 * Any additional fields found in the incoming payload from the messaging platform.
103 */
104 [key: string]: any;
105}
106/**
107 * A handler function passed into `hears()` or `on()` that receives a [BotWorker](#botworker) instance and a [BotkitMessage](#botkitmessage). Should be defined as an async function and/or return a Promise.
108 *
109 * The form of these handlers should be:
110 * ```javascript
111 * async (bot, message) => {
112 * // stuff.
113 * }
114 * ```
115 *
116 * For example:
117 * ```javascript
118 * controller.on('event', async(bot, message) => {
119 * // do somethign using bot and message like...
120 * await bot.reply(message,'Received an event.');
121 * });
122 * ```
123 */
124export interface BotkitHandler {
125 (bot: BotWorker, message: BotkitMessage): Promise<any>;
126}
127/**
128 * An interface for plugins that can contain multiple middlewares as well as an init function.
129 */
130export interface BotkitPlugin {
131 name: string;
132 middlewares?: {
133 [key: string]: any[];
134 };
135 init?: (botkit: Botkit) => void;
136 [key: string]: any;
137}
138/**
139 * Create a new instance of Botkit to define the controller for a conversational app.
140 * To connect Botkit to a chat platform, pass in a fully configured `adapter`.
141 * If one is not specified, Botkit will expose an adapter for the Microsoft Bot Framework.
142 */
143export declare class Botkit {
144 /**
145 * _config contains the options passed to the constructor.
146 * this property should never be accessed directly - use `getConfig()` instead.
147 */
148 private _config;
149 /**
150 * _events contains the list of all events for which Botkit has registered handlers.
151 * Each key in this object points to an array of handler functions bound to that event.
152 */
153 private _events;
154 /**
155 * _triggers contains a list of trigger patterns htat Botkit will watch for.
156 * Each key in this object points to an array of patterns and their associated handlers.
157 * Each key represents an event type.
158 */
159 private _triggers;
160 /**
161 * _interrupts contains a list of trigger patterns htat Botkit will watch for and fire BEFORE firing any normal triggers.
162 * Each key in this object points to an array of patterns and their associated handlers.
163 * Each key represents an event type.
164 */
165 private _interrupts;
166 /**
167 * conversationState is used to track and persist the state of any ongoing conversations.
168 * See https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-howto-v4-state?view=azure-bot-service-4.0&tabs=javascript
169 */
170 private conversationState;
171 /**
172 * _deps contains a list of all dependencies that Botkit must load before being ready to operate.
173 * see addDep(), completeDep() and ready()
174 */
175 private _deps;
176 /**
177 * contains an array of functions that will fire when Botkit has completely booted.
178 */
179 private _bootCompleteHandlers;
180 /**
181 * The current version of Botkit Core
182 */
183 version: string;
184 /**
185 * Middleware endpoints available for plugins and features to extend Botkit.
186 * Endpoints available are: spawn, ingest, receive, send.
187 *
188 * To bind a middleware function to Botkit:
189 * ```javascript
190 * controller.middleware.receive.use(function(bot, message, next) {
191 *
192 * // do something with bot or message
193 *
194 * // always call next, or your bot will freeze!
195 * next();
196 * });
197 * ```
198 */
199 middleware: {
200 spawn: any;
201 ingest: any;
202 send: any;
203 receive: any;
204 interpret: any;
205 };
206 /**
207 * A list of all the installed plugins.
208 */
209 private plugin_list;
210 /**
211 * A place where plugins can extend the controller object with new methods
212 */
213 private _plugins;
214 /**
215 * a BotBuilder storage driver - defaults to MemoryStorage
216 */
217 storage: Storage;
218 /**
219 * An Express webserver
220 */
221 webserver: any;
222 /**
223 * A direct reference to the underlying HTTP server object
224 */
225 http: any;
226 /**
227 * Any BotBuilder-compatible adapter - defaults to a [BotFrameworkAdapter](https://docs.microsoft.com/en-us/javascript/api/botbuilder/botframeworkadapter?view=botbuilder-ts-latest)
228 */
229 adapter: any;
230 /**
231 * A BotBuilder DialogSet that serves as the top level dialog container for the Botkit app
232 */
233 dialogSet: DialogSet;
234 /**
235 * The path of the main Botkit SDK, used to generate relative paths
236 */
237 PATH: string;
238 /**
239 * Indicates whether or not Botkit has fully booted.
240 */
241 private booted;
242 /**
243 * Create a new Botkit instance and optionally specify a platform-specific adapter.
244 * By default, Botkit will create a [BotFrameworkAdapter](https://docs.microsoft.com/en-us/javascript/api/botbuilder/botframeworkadapter?view=botbuilder-ts-latest).
245 *
246 * ```javascript
247 * const controller = new Botkit({
248 * adapter: some_adapter,
249 * webhook_uri: '/api/messages',
250 * });
251 *
252 * controller.on('message', async(bot, message) => {
253 * // do something!
254 * });
255 * ```
256 *
257 * @param config Configuration for this instance of Botkit
258 */
259 constructor(config: BotkitConfiguration);
260 /**
261 * Shutdown the webserver and prepare to terminate the app.
262 * Causes Botkit to first emit a special `shutdown` event, process any bound handlers, and then finally terminate the webserver.
263 * Bind any necessary cleanup helpers to the shutdown event - for example, close the connection to mongo.
264 *
265 * ```javascript
266 * await controller.shutdown();
267 * controller.on('shutdown', async() => {
268 * console.log('Bot is shutting down!');
269 * });
270 * ```
271 */
272 shutdown(): Promise<void>;
273 /**
274 * Get a value from the configuration.
275 *
276 * For example:
277 * ```javascript
278 * // get entire config object
279 * let config = controller.getConfig();
280 *
281 * // get a specific value from the config
282 * let webhook_uri = controller.getConfig('webhook_uri');
283 * ```
284 *
285 * @param {string} key The name of a value stored in the configuration
286 * @returns {any} The value stored in the configuration (or null if absent)
287 */
288 getConfig(key?: string): any;
289 /**
290 * Load a plugin module and bind all included middlewares to their respective endpoints.
291 * @param plugin_or_function A plugin module in the form of function(botkit) {...} that returns {name, middlewares, init} or an object in the same form.
292 */
293 usePlugin(plugin_or_function: ((botkit: Botkit) => BotkitPlugin) | BotkitPlugin): void;
294 /**
295 * Called from usePlugin -- do the actual binding of middlewares for a plugin that is being loaded.
296 * @param name name of the plugin
297 * @param endpoints the plugin object that contains middleware endpoint definitions
298 */
299 private registerPlugin;
300 /**
301 * (Plugins only) Extend Botkit's controller with new functionality and make it available globally via the controller object.
302 *
303 * ```javascript
304 *
305 * // define the extension interface
306 * let extension = {
307 * stuff: () => { return 'stuff' }
308 * }
309 *
310 * // register the extension
311 * controller.addPluginExtension('foo', extension);
312 *
313 * // call extension
314 * controller.plugins.foo.stuff();
315 *
316 *
317 * ```
318 * @param name name of plugin
319 * @param extension an object containing methods
320 */
321 addPluginExtension(name: string, extension: any): void;
322 /**
323 * Access plugin extension methods.
324 * After a plugin calls `controller.addPluginExtension('foo', extension_methods)`, the extension will then be available at
325 * `controller.plugins.foo`
326 */
327 get plugins(): {
328 [key: string]: any;
329 };
330 /**
331 * Expose a folder to the web as a set of static files.
332 * Useful for plugins that need to bundle additional assets!
333 *
334 * ```javascript
335 * // make content of the local public folder available at http://MYBOTURL/public/myplugin
336 * controller.publicFolder('/public/myplugin', __dirname + '/public);
337 * ```
338 * @param alias the public alias ie /myfiles
339 * @param path the actual path something like `__dirname + '/public'`
340 */
341 publicFolder(alias: any, path: any): void;
342 /**
343 * Convert a local path from a plugin folder to a full path relative to the webserver's main views folder.
344 * Allows a plugin to bundle views/layouts and make them available to the webserver's renderer.
345 * @param path_to_view something like path.join(__dirname,'views')
346 */
347 getLocalView(path_to_view: any): string;
348 /**
349 * (For use by Botkit plugins only) - Add a dependency to Botkit's bootup process that must be marked as completed using `completeDep()`.
350 * Botkit's `controller.ready()` function will not fire until all dependencies have been marked complete.
351 *
352 * For example, a plugin that needs to do an asynchronous task before Botkit proceeds might do:
353 * ```javascript
354 * controller.addDep('my_async_plugin');
355 * somethingAsync().then(function() {
356 * controller.completeDep('my_async_plugin');
357 * });
358 * ```
359 *
360 * @param name {string} The name of the dependency that is being loaded.
361 */
362 addDep(name: string): void;
363 /**
364 * (For use by plugins only) - Mark a bootup dependency as loaded and ready to use
365 * Botkit's `controller.ready()` function will not fire until all dependencies have been marked complete.
366
367 * @param name {string} The name of the dependency that has completed loading.
368 */
369 completeDep(name: string): boolean;
370 /**
371 * This function gets called when all of the bootup dependencies are completely loaded.
372 */
373 private signalBootComplete;
374 /**
375 * Use `controller.ready()` to wrap any calls that require components loaded during the bootup process.
376 * This will ensure that the calls will not be made until all of the components have successfully been initialized.
377 *
378 * For example:
379 * ```javascript
380 * controller.ready(() => {
381 *
382 * controller.loadModules(__dirname + '/features');
383 *
384 * });
385 * ```
386 *
387 * @param handler {function} A function to run when Botkit is booted and ready to run.
388 */
389 ready(handler: () => any): void;
390 private configureWebhookEndpoint;
391 /**
392 * Accepts the result of a BotBuilder adapter's `processActivity()` method and processes it into a Botkit-style message and BotWorker instance
393 * which is then used to test for triggers and emit events.
394 * NOTE: This method should only be used in custom adapters that receive messages through mechanisms other than the main webhook endpoint (such as those received via websocket, for example)
395 * @param turnContext {TurnContext} a TurnContext representing an incoming message, typically created by an adapter's `processActivity()` method.
396 */
397 handleTurn(turnContext: TurnContext): Promise<any>;
398 /**
399 * Save the current conversation state pertaining to a given BotWorker's activities.
400 * Note: this is normally called internally and is only required when state changes happen outside of the normal processing flow.
401 * @param bot {BotWorker} a BotWorker instance created using `controller.spawn()`
402 */
403 saveState(bot: BotWorker): Promise<void>;
404 /**
405 * Ingests a message and evaluates it for triggers, run the receive middleware, and triggers any events.
406 * Note: This is normally called automatically from inside `handleTurn()` and in most cases should not be called directly.
407 * @param bot {BotWorker} An instance of the bot
408 * @param message {BotkitMessage} an incoming message
409 */
410 private processTriggersAndEvents;
411 /**
412 * Evaluates an incoming message for triggers created with `controller.hears()` and fires any relevant handler functions.
413 * @param bot {BotWorker} An instance of the bot
414 * @param message {BotkitMessage} an incoming message
415 */
416 private listenForTriggers;
417 /**
418 * Evaluates an incoming message for triggers created with `controller.interrupts()` and fires any relevant handler functions.
419 * @param bot {BotWorker} An instance of the bot
420 * @param message {BotkitMessage} an incoming message
421 */
422 private listenForInterrupts;
423 /**
424 * Evaluates a single trigger and return true if the incoming message matches the conditions
425 * @param trigger {BotkitTrigger} a trigger definition
426 * @param message {BotkitMessage} an incoming message
427 */
428 private testTrigger;
429 /**
430 * Instruct your bot to listen for a pattern, and do something when that pattern is heard.
431 * Patterns will be "heard" only if the message is not already handled by an in-progress dialog.
432 * To "hear" patterns _before_ dialogs are processed, use `controller.interrupts()` instead.
433 *
434 * For example:
435 * ```javascript
436 * // listen for a simple keyword
437 * controller.hears('hello','message', async(bot, message) => {
438 * await bot.reply(message,'I heard you say hello.');
439 * });
440 *
441 * // listen for a regular expression
442 * controller.hears(new RegExp(/^[A-Z\s]+$/), 'message', async(bot, message) => {
443 * await bot.reply(message,'I heard a message IN ALL CAPS.');
444 * });
445 *
446 * // listen using a function
447 * controller.hears(async (message) => { return (message.intent === 'hello') }, 'message', async(bot, message) => {
448 * await bot.reply(message,'This message matches the hello intent.');
449 * });
450 * ```
451 * @param patterns {} One or more string, regular expression, or test function
452 * @param events {} A list of event types that should be evaluated for the given patterns
453 * @param handler {BotkitHandler} a function that will be called should the pattern be matched
454 */
455 hears(patterns: (string | RegExp | {
456 (message: BotkitMessage): Promise<boolean>;
457 })[] | RegExp | string | {
458 (message: BotkitMessage): Promise<boolean>;
459 }, events: string | string[], handler: BotkitHandler): void;
460 /**
461 * Instruct your bot to listen for a pattern, and do something when that pattern is heard.
462 * Interruptions work just like "hears" triggers, but fire _before_ the dialog system is engaged,
463 * and thus handlers will interrupt the normal flow of messages through the processing pipeline.
464 *
465 * ```javascript
466 * controller.interrupts('help','message', async(bot, message) => {
467 *
468 * await bot.reply(message,'Before anything else, you need some help!')
469 *
470 * });
471 * ```
472 * @param patterns {} One or more string, regular expression, or test function
473 * @param events {} A list of event types that should be evaluated for the given patterns
474 * @param handler {BotkitHandler} a function that will be called should the pattern be matched
475 */
476 interrupts(patterns: (string | RegExp | {
477 (message: BotkitMessage): Promise<boolean>;
478 })[] | RegExp | RegExp[] | string | {
479 (message: BotkitMessage): Promise<boolean>;
480 }, events: string | string[], handler: BotkitHandler): void;
481 /**
482 * Bind a handler function to one or more events.
483 *
484 * ```javascript
485 * controller.on('conversationUpdate', async(bot, message) => {
486 *
487 * await bot.reply(message,'I received a conversationUpdate event.');
488 *
489 * });
490 * ```
491 *
492 * @param events {} One or more event names
493 * @param handler {BotkitHandler} a handler function that will fire whenever one of the named events is received.
494 */
495 on(events: string | string[], handler: BotkitHandler): void;
496 /**
497 * Trigger an event to be fired. This will cause any bound handlers to be executed.
498 * Note: This is normally used internally, but can be used to emit custom events.
499 *
500 * ```javascript
501 * // fire a custom event
502 * controller.trigger('my_custom_event', bot, message);
503 *
504 * // handle the custom event
505 * controller.on('my_custom_event', async(bot, message) => {
506 * //... do something
507 * });
508 * ```
509 *
510 * @param event {string} the name of the event
511 * @param bot {BotWorker} a BotWorker instance created using `controller.spawn()`
512 * @param message {BotkitMessagE} An incoming message or event
513 */
514 trigger(event: string, bot?: BotWorker, message?: BotkitMessage): Promise<any>;
515 /**
516 * Create a platform-specific BotWorker instance that can be used to respond to messages or generate new outbound messages.
517 * The spawned `bot` contains all information required to process outbound messages and handle dialog state, and may also contain extensions
518 * for handling platform-specific events or activities.
519 * @param config {any} Preferably receives a DialogContext, though can also receive a TurnContext. If excluded, must call `bot.changeContext(reference)` before calling any other method.
520 * @param adapter {BotAdapter} An optional reference to a specific adapter from which the bot will be spawned. If not specified, will use the adapter from which the configuration object originates. Required for spawning proactive bots in a multi-adapter scenario.
521 */
522 spawn(config?: any, custom_adapter?: BotAdapter): Promise<BotWorker>;
523 /**
524 * Load a Botkit feature module
525 *
526 * @param p {string} path to module file
527 */
528 loadModule(p: string): void;
529 /**
530 * Load all Botkit feature modules located in a given folder.
531 *
532 * ```javascript
533 * controller.ready(() => {
534 *
535 * // load all modules from sub-folder features/
536 * controller.loadModules('./features');
537 *
538 * });
539 * ```
540 *
541 * @param p {string} path to a folder of module files
542 * @param exts {string[]} the extensions that you would like to load (default: ['.js'])
543 */
544 loadModules(p: string, exts?: string[]): void;
545 /**
546 * Add a dialog to the bot, making it accessible via `bot.beginDialog(dialog_id)`
547 *
548 * ```javascript
549 * // Create a dialog -- `BotkitConversation` is just one way to create a dialog
550 * const my_dialog = new BotkitConversation('my_dialog', controller);
551 * my_dialog.say('Hello');
552 *
553 * // Add the dialog to the Botkit controller
554 * controller.addDialog(my_dialog);
555 *
556 * // Later on, trigger the dialog into action!
557 * controller.on('message', async(bot, message) => {
558 * await bot.beginDialog('my_dialog');
559 * });
560 * ```
561 *
562 * @param dialog A dialog to be added to the bot's dialog set
563 */
564 addDialog(dialog: Dialog): void;
565 /**
566 * Bind a handler to the end of a dialog.
567 * NOTE: bot worker cannot use bot.reply(), must use bot.send()
568 *
569 * [Learn more about handling end-of-conversation](../docs/conversations.md#handling-end-of-conversation)
570 * @param dialog the dialog object or the id of the dialog
571 * @param handler a handler function in the form `async(bot, dialog_results) => {}`
572 */
573 afterDialog(dialog: Dialog | string, handler: BotkitHandler): void;
574}