Skip to content

Commit

Permalink
Merge pull request #132 from codigoencasa/master
Browse files Browse the repository at this point in the history
fix
  • Loading branch information
leifermendez authored Sep 17, 2024
2 parents 05227db + 53ec55b commit e99cf33
Showing 1 changed file with 77 additions and 57 deletions.
134 changes: 77 additions & 57 deletions src/pages/en/showcases/fast-entires.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,110 +34,130 @@ In this example, we use __3000ms__ (equal to 3 seconds) as the default gap, but

```ts {{ title: 'fast-entires.ts' }}
/**
* @file messageQueue.ts
* @description A functional implementation of a message queueing system with debounce functionality.
* @file multiUserMessageQueue.ts
* @description An improved functional implementation of a multi-user message queueing system with debounce functionality,
* ensuring separate conversation handling for each user.
*/

import { BotContext } from "@builderbot/bot/dist/types";

interface Message {
text: string;
timestamp: number;
}

interface QueueConfig {
gapSeconds: number;
gapMilliseconds: number;
}

interface QueueState {
queue: Message[];
interface UserQueue {
messages: Message[];
timer: NodeJS.Timeout | null;
callback: ((body: string) => void) | null;
callback: ((body: string, from: string) => void) | null;
}

interface QueueState {
queues: Map<string, UserQueue>;
}

function createInitialState(): QueueState {
return {
queue: [],
timer: null,
callback: null
queues: new Map()
};
}

function resetTimer(state: QueueState): QueueState {
if (state.timer) {
clearTimeout(state.timer);
function resetTimer(userQueue: UserQueue): UserQueue {
if (userQueue.timer) {
clearTimeout(userQueue.timer);
}
return { ...state, timer: null };
return { ...userQueue, timer: null };
}

function processQueue(state: QueueState): [string, QueueState] {
const result = state.queue.map(message => message.text).join(" ");
function processQueue(messages: Message[]): string {
const result = messages.map(message => message.text).join(" ");
console.log('Accumulated messages:', result);

const newState = {
...state,
queue: [],
timer: null
};

return [result, newState];
return result;
}

function createMessageQueue(config: QueueConfig) {
let state = createInitialState();

return function enqueueMessage(messageText: string, callback: (body: string) => void): void {
console.log('Enqueueing:', messageText);

state = resetTimer(state);
state.queue.push({ text: messageText, timestamp: Date.now() });
state.callback = callback;

state.timer = setTimeout(() => {
const [result, newState] = processQueue(state);
state = newState;
if (state.callback) {
state.callback(result);
state.callback = null;
}
}, config.gapSeconds);
let state: QueueState = createInitialState();

return function enqueueMessage(ctx: BotContext, callback: (body: string, from: string) => void): void {
const from = ctx.from;
const messageBody = ctx.body;

if (!from || !messageBody) {
console.error('Invalid message context:', ctx);
return;
}

console.log('Enqueueing:', messageBody, 'from:', from);

let userQueue = state.queues.get(from);
if (!userQueue) {
userQueue = { messages: [], timer: null, callback: null };
state.queues.set(from, userQueue);
}

userQueue = resetTimer(userQueue);
userQueue.messages.push({ text: messageBody, timestamp: Date.now() });
userQueue.callback = callback;

console.log('Messages for', from, ':', userQueue.messages);

if (!userQueue.timer) {
userQueue.timer = setTimeout(() => {
const currentQueue = state.queues.get(from);
if (currentQueue) {
const result = processQueue(currentQueue.messages);
if (currentQueue.callback) {
currentQueue.callback(result, from);
}
state.queues.set(from, { ...currentQueue, messages: [], timer: null });
}
}, config.gapMilliseconds);
}

state.queues.set(from, userQueue);
};
}

export { createMessageQueue, QueueConfig };
```

```ts {{ title: 'app.ts' }}
import { createMessageQueue, QueueConfig } from './fast-entires'
import { createMessageQueue, QueueConfig } from './fast'

import { createBot, createProvider, createFlow, addKeyword, MemoryDB } from '@builderbot/bot'
import { createBot, createProvider, createFlow, addKeyword, MemoryDB, EVENTS } from '@builderbot/bot'
import { BaileysProvider } from '@builderbot/provider-baileys'

const queueConfig: QueueConfig = { gapSeconds: 3000 };
const queueConfig: QueueConfig = { gapMilliseconds: 3000 };
const enqueueMessage = createMessageQueue(queueConfig);

const welcomeFlow = addKeyword<BaileysProvider, MemoryDB>(['hello', 'hi'])
.addAction(async (ctx, { flowDynamic }) => {
try {
enqueueMessage(ctx.body, async (body) => {
console.log('Processed messages:', body);
await flowDynamic(`Received messages: ${body}`);
});
} catch (error) {
console.error('Error processing message:', error);
}
});
const welcomeFlow = addKeyword<BaileysProvider, MemoryDB>(EVENTS.WELCOME)
.addAction(async (ctx, { flowDynamic }) => {
try {
enqueueMessage(ctx, async (body) => {
console.log('Processed messages:', body, ctx.from);
await flowDynamic(`Received messages: ${body}`);
});
} catch (error) {
console.error('Error processing message:', error);
}
});

const main = async () => {
const adapterDB = new MemoryDB()
const adapterFlow = createFlow([welcomeFlow])
const adapterProvider = createProvider(BaileysProvider)

adapterProvider.initHttpServer(3000)

await createBot({
const bot = await createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})

bot.httpServer(3005)
}

main()
Expand Down

0 comments on commit e99cf33

Please sign in to comment.