@@ -10,6 +10,7 @@ import {
1010 selectCommand ,
1111 selectSessionId ,
1212 isFunction ,
13+ delay ,
1314} from './utils'
1415
1516import {
@@ -19,13 +20,17 @@ import {
1920import aliceStateMiddleware from './middlewares/aliceStateMiddleware'
2021import { configInterface } from './types/alice'
2122import { CommandInterface } from './types/command'
23+ import { CtxInterface } from './types/ctx'
2224import { WebhookResponse , WebhookRequest } from 'webhook'
2325
2426const DEFAULT_SESSIONS_LIMIT : number = 1000
27+ const DEFAULT_TIMEOUT_CALLBACK_MESSAGE = 'Извините, но я не успела найти ответ за отведенное время.'
28+ const DEFAULT_TIMEOUT_CALLBACK = 600
2529
2630export default class Alice {
27- private anyCallback : ( ctx : Ctx ) => void
28- private welcomeCallback : ( ctx : Ctx ) => void
31+ private anyCallback : ( ctx : CtxInterface ) => void
32+ private welcomeCallback : ( ctx : CtxInterface ) => void
33+ private timeoutCallback : ( ctx : CtxInterface ) => void
2934 private commands : Commands
3035 private middlewares : any [ ]
3136 private scenes : Scene [ ]
@@ -40,6 +45,10 @@ export default class Alice {
4045 constructor ( config : configInterface = { } ) {
4146 this . anyCallback = null
4247 this . welcomeCallback = null
48+ this . timeoutCallback = async ( ctx ) => {
49+ await delay ( DEFAULT_TIMEOUT_CALLBACK )
50+ ctx . reply ( DEFAULT_TIMEOUT_CALLBACK_MESSAGE )
51+ }
4352 this . commands = new Commands ( config . fuseOptions || null )
4453 this . middlewares = [ aliceStateMiddleware ( ) ]
4554 this . scenes = [ ]
@@ -240,18 +249,31 @@ export default class Alice {
240249 * При получении ответа от @handleRequestBody, результат
241250 * отправляется обратно.
242251 */
243- public async listen ( callbackUrl = '/' , port = 80 , callback ?: ( ) => void ) {
252+ public async listen ( webhookPath = '/' , port = 80 , callback ?: ( ) => void ) {
244253 return new Promise ( ( resolve ) => {
245254 const app = express ( )
246255 app . use ( express . json ( ) )
247- app . post ( callbackUrl , async ( req , res ) => {
256+ app . post ( webhookPath , async ( req , res ) => {
248257 if ( this . config . oAuthToken ) {
249258 res . setHeader ( 'Authorization' , this . config . oAuthToken )
250259 }
251260 res . setHeader ( 'Content-type' , 'application/json' )
252- const handleResponseCallback = ( response ) => res . send ( response )
261+
262+ let responseAlreadySent = false
263+ const handleResponseCallback = ( response ) => {
264+ /* dont answer twice */
265+ if ( responseAlreadySent ) {
266+ return false
267+ }
268+ res . send ( response )
269+ responseAlreadySent = true
270+ }
253271 try {
254- return await this . handleRequestBody ( req . body , handleResponseCallback )
272+ const executors = [
273+ this . handleRequestBody ( req . body , handleResponseCallback ) ,
274+ await this . timeoutCallback ( new Ctx ( { req : req . body , sendResponse : handleResponseCallback } ) ) ,
275+ ] . filter ( Boolean )
276+ return await Promise . race ( executors )
255277 } catch ( error ) {
256278 throw new Error ( error )
257279 }
0 commit comments