Idle
Issue
I need to wait for the customer's response but only for a limited time.
Possible Solution
The inactivity of flows in our business logic can become a nuisance, that is why we share the following resources as an alternative solution to this situation.
Create a file named idle-custom.ts
and paste the following code:
idle-custom.ts
import { EVENTS, addKeyword } from '@builderbot/bot'
import { BotContext, TFlow } from '@builderbot/bot/dist/types';
// Object to store timers for each user
const timers = {};
// Flow for handling inactivity
const idleFlow = addKeyword(EVENTS.ACTION).addAction(
async (_, { endFlow }) => {
return endFlow("Response time has expired");
}
);
// Function to start the inactivity timer for a user
const start = (ctx: BotContext, gotoFlow: (a: TFlow) => Promise<void>, ms: number) => {
timers[ctx.from] = setTimeout(() => {
console.log(`User timeout: ${ctx.from}`);
return gotoFlow(idleFlow);
}, ms);
}
// Function to reset the inactivity timer for a user
const reset = (ctx: BotContext, gotoFlow: (a: TFlow) => Promise<void>, ms: number) => {
stop(ctx);
if (timers[ctx.from]) {
console.log(`reset countdown for the user: ${ctx.from}`);
clearTimeout(timers[ctx.from]);
}
start(ctx, gotoFlow, ms);
}
// Function to stop the inactivity timer for a user
const stop = (ctx: BotContext) => {
if (timers[ctx.from]) {
clearTimeout(timers[ctx.from]);
}
}
export {
start,
reset,
stop,
idleFlow,
}
Remember to add this flow to your project's main flow array
app.ts
import { idleFlow } from './idle-custom'
const main = async () => {
const adapterFlow = createFlow([welcomeFlow, registerFlow, idleFlow])
const adapterProvider = createProvider(Provider)
const adapterDB = new Database()
const { httpServer } = await createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
httpServer(+PORT)
}
Start Inactivity
- Name
ctx
- Type
- BotContext
- Description
Current execution context
- Name
gotoFlow
- Type
- TFlow
- Description
Function providing the execution flow
- Name
ms
- Type
- number
- Description
Number of milliseconds to be set
const questionFlow = addKeyword("hello")
.addAction(async (ctx, { gotoFlow }) => {
start(ctx, gotoFlow, 10000)
})
Reset Inactivity
- Name
ctx
- Type
- BotContext
- Description
Current execution context
- Name
gotoFlow
- Type
- TFlow
- Description
Function providing the execution flow
- Name
ms
- Type
- number
- Description
Number of milliseconds to be set
// ...
.addAnswer(
"Give me your last name",
{ capture: true },
async (ctx, { gotoFlow, state }) => {
reset(ctx, gotoFlow, 10000);
await state.update({ lastName: ctx.body });
}
)
// ...
Stop Inactivity
- Name
ctx
- Type
- BotContext
- Description
Current execution context
// ...
.addAnswer(
"Thank you!",
null,
async (ctx, { gotoFlow, state }) => {
stop(ctx);
}
)
// ...
app.ts
import { createBot, createProvider, createFlow, addKeyword } from '@bot-whatsapp/bot'
import { MemoryDB as Database } from '@bot-whatsapp/bot'
import { BaileysProvider as Provider } from '@bot-whatsapp/provider-baileys'
import { idleFlow, reset, start, stop, } from './idle-custom'
const PORT = process.env.PORT ?? 3008
const questionFlow = addKeyword("hello")
.addAction(async (ctx, { gotoFlow }) => start(ctx, gotoFlow, 10000))
.addAnswer(
[
"This is a test of the Home idle, if you do not respond within 10 seconds I will end the flow.",
"Give me your name",
],
{ capture: true },
async (ctx, { gotoFlow, state }) => {
reset(ctx, gotoFlow, 10000);
await state.update({ name: ctx.body });
}
)
.addAnswer(
"Give me your last name",
{ capture: true },
async (ctx, { gotoFlow, state }) => {
reset(ctx, gotoFlow, 10000);
await state.update({ lastName: ctx.body });
}
)
.addAnswer("Finally, answer this simple question by typing the number between [1, 2].",
{ capture: true },
async (ctx, { gotoFlow, endFlow, fallBack }) => {
reset(ctx, gotoFlow, 10000);
switch (ctx.body) {
case "1":
stop(ctx);
return endFlow(`Nice 1`);
case "2":
stop(ctx);
return endFlow(`Ok 2`);
default:
return fallBack(`I only accept *numbers* that are between [1, 2].`);
}
}
);
const main = async () => {
const adapterFlow = createFlow([questionFlow, idleFlow])
const adapterProvider = createProvider(Provider)
const adapterDB = new Database()
const { httpServer } = await createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
httpServer(+PORT)
}
main()