PageSourceSearch

https://builderbot.vercel.app/_next/static/chunks/pages/en/showcases/multiple-messages-113c07e1b0fc7b9e.js

js builderbot.vercel.app collected 2026-10-03 06:20:35 UTC 43,939 bytes, 1 lines download raw bytes

1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6932],{55498:function(s,o,n){(window.__NEXT_P=window.__NEXT_P||[]).push(["/en/showcases/multiple-messages",function(){return n(88200)}])},88200:function(s,o,n){"use strict";n.r(o),n.d(o,{__N_SSG:function(){return l},default:function(){return MDXContent}});var t=n(97997),a=n(11151),e=n(38706),r=n(99686),i=n(86156);function _createMdxContent(s){let o={code:"code",h1:"h1",h2:"h2",hr:"hr",p:"p",pre:"pre",...(0,a.ah)(),...s.components},{CodeGroup:n}=o;return n||function(s,o){throw Error("Expected "+(o?"component":"object")+" `"+s+"` to be defined: you likely forgot to import, pass, or provide it.")}("CodeGroup",!0),(0,t.BX)(t.HY,{children:[(0,t.tZ)(o.h1,{children:"Multiple messages"}),"\n",(0,t.tZ)(o.h2,{id:"issue",children:"Issue",not:"true"}),"\n",(0,t.tZ)(o.p,{children:"Sometimes, you need the bot to generate responses based on an event such as receiving images from users, but you don't want the bot to throw multiple and redundant responses if the user quickly sends several images."}),"\n",(0,t.tZ)(e.T,{mode:!0,users:["Jorgelet"]}),"\n",(0,t.tZ)(o.hr,{}),"\n",(0,t.tZ)(o.h2,{id:"possible-solution",children:"Possible Solution",not:"true"}),"\n",(0,t.tZ)(o.p,{children:"To ensure that the bot responds only once despite receiving too many calls in a short period of time, a debounce decorator could be implemented around the gotoFlow and endFlow methods."}),"\n",(0,t.tZ)(o.p,{children:"In the example below I will show you how I implemented this solution in my bot to analyze several images and depending on whether they are images of furniture or not, terminate the flow with an error message or send it to another registration flow"}),"\n",(0,t.BX)(n,{children:[(0,t.tZ)(o.pre,{language:"ts",code:"import path from \"node:path\";\nimport fs from \"node:fs/promises\";\nimport process from \"node:process\";\nimport { addKeyword, EVENTS } from \"@builderbot/bot\";\nimport { BaileysProvider } from \"@builderbot/provider-baileys\";\nimport { UrlToBase64 } from \"@builderbot-plugins/url-to-base64\";\n\nimport { PROMPT_IMAGE } from \"./prompt\";\nimport { debounce } from \"~/utils/debounce\";\nimport AIClass from \"~/services/OpenAIService\";\nimport { registerFlow } from \"../order/register.flow\";\n\n\nconst localPaths = [];\nlet debouncedEndFlow:(...args: any[]) => void;\nlet debouncedGoToFlow:(...args: any[]) => void;\nconst filePath = path.join(process.cwd(), 'src', 'database', 'images');\n\nexport const mediaFlow = addKeyword<BaileysProvider>(EVENTS.MEDIA)\n.addAction(async(ctx, { provider, queue }) => { \n  await queue.enqueue('processImage', async () => {\n    const localPath = await provider.saveFile(ctx, { path: filePath });\n    localPaths.push(localPath);\n  }, 'imageProcessingTask');\n\n  await queue.processQueue('processImage');\n  await queue.clearQueue('processImage');\n  queue.clearAndDone('processImage', {fingerIdRef: 'imageProcessingTask'});\n})\n.addAction(async (_, { extensions, gotoFlow, endFlow }) => {\n\n  const ai = extensions.ai as AIClass;  \n  if(!debouncedEndFlow && !debouncedGoToFlow){\n    debouncedEndFlow = debounce(endFlow, 1500);\n    debouncedGoToFlow = debounce(gotoFlow, 1500);\n  }\n    \n  for(const path of localPaths) {\n    const { data, mimetype } = UrlToBase64.fromFilePath(path);    \n    const aiResponse = await ai.readImage(data, PROMPT_IMAGE, mimetype);\n\n    if(aiResponse.includes('NOT_FURNITURE')) {\n      for(const filePath of localPaths) {\n        await fs.unlink(filePath);\n      }\n      localPaths.length = 0;\n      return debouncedEndFlow('Ups! Asegurate de enviar una foto correcta de un mueble');\n    }   \n  }\n\n  localPaths.length = 0;\n  return debouncedGoToFlow(registerFlow)\n})\n\n",children:(0,t.tZ)(o.code,{className:"language-ts",children:'<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> path </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;node:path&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-token-keyword)">
1import</span><span style="color: var(--shiki-color-text)"> fs </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;node:fs/promises&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> process </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;node:process&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { addKeyword</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> EVENTS } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@builderbot/bot&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { BaileysProvider } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@builderbot/provider-baileys&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { UrlToBase64 } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@builderbot-plugins/url-to-base64&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span></span>\n<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { PROMPT_IMAGE } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;./prompt&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { debounce } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;~/utils/debounce&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> AIClass </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;~/services/OpenAIService&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { registerFlow } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;../order/register.flow&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span></span>\n<span></span>\n<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">localPaths</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [];</span></span>\n<span><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">debouncedEndFlow</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-keyword)">...</span><span style="color: var(--shiki-color-text)">args</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-color-text)">[]) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">void</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">debouncedGoToFlow</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-keyword)">...</span><span style="color: var(--shiki-color-text)">args</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-color-text)">[]) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">void</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">filePath</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">path</span><span style="color: var(--shiki-token-function)">.join</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-constant)">process</span><span style="color: var(--shiki-token-function)">.cwd</span><span style="color: var(--shiki-color-text)">()</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&#39;src&#39;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&#39;database&#39;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&#39;images&#39;</span><span style="color: var(--shiki-color-text)">);</span></span>\n<span></span>\n<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">mediaFlow</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">addKeyword</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">BaileysProvider</span><span style="color: var(--shiki-color-text)">&gt;(</span><span style="color: var(--shiki-token-constant)">EVENTS</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">MEDIA</span><span style="color: var(--shiki-color-text)">)</span></span>\n<span><span style="color: var(--shiki-token-function)">.addAction</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-keyword)">async</span><span style="color: var(--shiki-color-text)">(ctx</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> { provider</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> queue }) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> { </span></span>\n<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">await</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">queue</span><span style="color: var(--shiki-token-function)">.enqueue</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&#39;processImage&#39;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">async</span><span style="color: var(--shiki-color-text)"> () </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> {</span></span>\n<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">localPath</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">await</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">provider</span><span style="color: var(--shiki-token-function)">.saveFile</span><span style="color: var(--shiki-color-text)">(ctx</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> { path</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> filePath });</span></span>\n<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-constant)">localPaths</span><span style="color: var(--shiki-token-function)">.push</span><span style="color: var(--shiki-color-text)">(localPath);</span></span>\n<span><span style="color: var(--shiki-color-text)">  }</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&#39;imageProcessingTask&#39;</span><span style="color: var(--shiki-color-text)">);</span></span>\n<span></span>\n<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">await</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">queue</span><span style="color: var(--shiki-token-function)">.processQueue</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&#39;processImage&#39;</span><span style="color: var(--shiki-color-text)">);</span></span>\n<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">await</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">queue</span><span style="color: var(--shiki-token-function)">.clearQueue</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&#39;processImage&#39;</span><span style="color: var(--shiki-color-text)">);</span></span>\n<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-constant)">queue</span><span style="color: var(--shiki-token-function)">.clearAndDone</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&#39;processImage&#39;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> {fingerIdRef</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&#39;imageProcessingTask&#39;</span><span style="color: var(--shiki-color-text)">});
1</span></span>\n<span><span style="color: var(--shiki-color-text)">})</span></span>\n<span><span style="color: var(--shiki-token-function)">.addAction</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-keyword)">async</span><span style="color: var(--shiki-color-text)"> (_</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> { extensions</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> gotoFlow</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> endFlow }) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> {</span></span>\n<span></span>\n<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">ai</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">extensions</span><span style="color: var(--shiki-color-text)">.ai </span><span style="color: var(--shiki-token-keyword)">as</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">AIClass</span><span style="color: var(--shiki-color-text)">;  </span></span>\n<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-color-text)">debouncedEndFlow </span><span style="color: var(--shiki-token-keyword)">&amp;&amp;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-color-text)">debouncedGoToFlow){</span></span>\n<span><span style="color: var(--shiki-color-text)">    debouncedEndFlow </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">debounce</span><span style="color: var(--shiki-color-text)">(endFlow</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">1500</span><span style="color: var(--shiki-color-text)">);</span></span>\n<span><span style="color: var(--shiki-color-text)">    debouncedGoToFlow </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">debounce</span><span style="color: var(--shiki-color-text)">(gotoFlow</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">1500</span><span style="color: var(--shiki-color-text)">);</span></span>\n<span><span style="color: var(--shiki-color-text)">  }</span></span>\n<span><span style="color: var(--shiki-color-text)">    </span></span>\n<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">for</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">path</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">of</span><span style="color: var(--shiki-color-text)"> localPaths) {</span></span>\n<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> { </span><span style="color: var(--shiki-token-constant)">data</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">mimetype</span><span style="color: var(--shiki-color-text)"> } </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">UrlToBase64</span><span style="color: var(--shiki-token-function)">.fromFilePath</span><span style="color: var(--shiki-color-text)">(path);    </span></span>\n<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">aiResponse</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">await</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">ai</span><span style="color: var(--shiki-token-function)">.readImage</span><span style="color: var(--shiki-color-text)">(data</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">PROMPT_IMAGE</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> mimetype);</span></span>\n<span></span>\n<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-constant)">aiResponse</span><span style="color: var(--shiki-token-function)">.includes</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&#39;NOT_FURNITURE&#39;</span><span style="color: var(--shiki-color-text)">)) {</span></span>\n<span><span style="color: var(--shiki-color-text)">      </span><span style="color: var(--shiki-token-keyword)">for</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">filePath</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">of</span><span style="color: var(--shiki-color-text)"> localPaths) {</span></span>\n<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">await</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">fs</span><span style="color: var(--shiki-token-function)">.unlink</span><span style="color: var(--shiki-color-text)">(filePath);</span></span>\n<span><span style="color: var(--shiki-color-text)">      }</span></span>\n<span><span style="color: var(--shiki-color-text)">      </span><span style="color: var(--shiki-token-constant)">localPaths</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">length</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">0</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-color-text)">      </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">debouncedEndFlow</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&#39;Ups! Asegurate de enviar una foto correcta de un mueble&#39;</span><span style="color: var(--shiki-color-text)">);</span></span>\n<span><span style="color: var(--shiki-color-text)">    }   </span></span>\n<span><span style="color: var(--shiki-color-text)">  }</span></span>\n<span></span>\n<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-constant)">localPaths</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">length</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">0</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">debouncedGoToFlow</span><span style="color: var(--shiki-color-text)">(registerFlow)</span></span>\n<span><span style="color: var(--shiki-color-text)">})</span></span>\n<span></span>\n<span></span>'}),title:"media-flow.ts"}),(0,t.tZ)(o.pre,{language:"ts",code:'import { TFlow } from "@builderbot/bot/dist/types";\n\ntype DebounceFunction<P = any> = \n((message?: string) => void) | // this is the endFlow type\n((flow: TFlow<P>, step?: number) => Promise<void>) // this is the gotoFlow type\n\nexport function debounce(func: DebounceFunction, ms: number) {\n  let timeout:NodeJS.Timeout;\n  return function(...args: any[]) {\n    clearTimeout(timeout);\n    timeout = setTimeout(() => func.apply(this, args), ms)\n  }\n}\n\n',children:(0,t.tZ)(o.code,{className:"language-ts",children:'<span><span style="color: var(--shiki-token-keyword)">
1import</span><span style="color: var(--shiki-color-text)"> { TFlow } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@builderbot/bot/dist/types&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span></span>\n<span><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">DebounceFunction</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">P</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-color-text)">&gt; </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span></span>\n<span><span style="color: var(--shiki-color-text)">((message</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">void</span><span style="color: var(--shiki-color-text)">) </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-comment)">// this is the endFlow type</span></span>\n<span><span style="color: var(--shiki-color-text)">((flow</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">TFlow</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">P</span><span style="color: var(--shiki-color-text)">&gt;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> step</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Promise</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-constant)">void</span><span style="color: var(--shiki-color-text)">&gt;) </span><span style="color: var(--shiki-token-comment)">// this is the gotoFlow type</span></span>\n<span></span>\n<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">debounce</span><span style="color: var(--shiki-color-text)">(func</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">DebounceFunction</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> ms</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">) {</span></span>\n<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">let</span><span style="color: var(--shiki-color-text)"> timeout</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-token-function)">NodeJS</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-function)">Timeout</span><span style="color: var(--shiki-color-text)">;</span></span>\n<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-keyword)">...</span><span style="color: var(--shiki-color-text)">args</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">any</span><span style="color: var(--shiki-color-text)">[]) {</span></span>\n<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-function)">clearTimeout</span><span style="color: var(--shiki-color-text)">(timeout);</span></span>\n<span><span style="color: var(--shiki-color-text)">    timeout </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">setTimeout</span><span style="color: var(--shiki-color-text)">(() </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">func</span><span style="color: var(--shiki-token-function)">.apply</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-constant)">this</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> args)</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> ms)</span></span>\n<span><span style="color: var(--shiki-color-text)">  }</span></span>\n<span><span style="color: var(--shiki-color-text)">}</span></span>\n<span></span>\n<span></span>'}),title:"debounce.ts"})]}),"\n",(0,t.tZ)(o.p,{children:"Remember that this is an alternative solution, and it is possible that its implementation could be improved."}),"\n",(0,t.tZ)(o.hr,{}),"\n",(0,t.tZ)(i.t,{}),"\n",(0,t.tZ)(r._,{})]})}var l=!0;function MDXContent(){let s=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:o}={...(0,a.ah)(),...s.components};return o?(0,t.tZ)(o,{...s,children:(0,t.tZ)(_createMdxContent,{...s})}):_createMdxContent(s)}},38706:function(s,o,n){"use strict";n.d(o,{T:function(){return Contributors}});var t=n(97997),a=n(11720),e=n(25675),r=n.n(e),i=n(93077);let l=(0,i.createCache)((0,i.memoryStore)(),{max:100,ttl:864e5,ttlAutopurge:!0}),getProfiles=async function(){let s,o=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];o=o.map(s=>s.toLowerCase());let fetchUser=async s=>{let o=await l.get(`contributors-${s}`);if(o)return o;let n=await fetch(`https://api.github.com/users/${s}`,{next:{revalidate:3600}});if(!n.ok)throw Error(`Failed to fetch GitHub user: ${s}`);let t=await n.json();return await l.set(`contributors-${s}`,t,864e5),t};s=await Promise.all(o.map(async s=>{try{let o=await fetchUser(s);return{id:o.id,name:o.login.toLowerCase(),avatar:o.avatar_url,profile:o.html_url,contributions:o.contributions}}catch(s){return console.error(s.message),null}}));let n=s.filter(s=>null!==s);return n};function Contributors(s){let{users:o,mode:n}=s,[e,i]=(0,a.useState)([]);return((0,a.useEffect)(()=>{(async function(){try{let s=await getProfiles(o);i(s)}catch(s){console.error("Error fetching profiles:",s)}})()},[]),e.length)?(0,t.tZ)("div",{className:"place-content-center",children:(0,t.tZ)("ul",{className:"flex flex-wrap gap-2 p-0 m-0",children:e.map(s=>(0,t.BX)("li",{className:"list-none p-0 m-0 flex gap-2 bg-gray-100 dark:bg-white/2.5 dark:ring-1 dark:ring-white/10 rounded-2xl",children:[(0,t.tZ)("a",{href:s.profile,target:"_blank",children:(0,t.tZ)(r(),{src:s.avatar,alt:s.name,width:30,height:30,className:"rounded-full hover:shadow-md transition-all shadow-slate-400 m-0 bg-fuchsia-200"})}),n?(0,t.tZ)("span",{className:"lowercase mr-3",children:s.name}):(0,t.tZ)(t.HY,{})]},"contributor-"+s.id))})}):(0,t.tZ)("div",{className:"min-h-[30px]"})}},86049:function(s,o,n){"use strict";n.d(o,{K:function(){return GridPattern}});var t=n(97997),a=n(11720);function GridPattern(s){let{width:o,height:n,x:e,y:r,squares:i,...l}=s,p=(0,a.useId)();return(0,t.BX)("svg",{"aria-hidden":"true",...l,children:[(0,t.tZ)("defs",{children:(0,t.tZ)("pattern",{id:p,width:o,height:n,patternUnits:"userSpaceOnUse",x:e,y:r,children:(0,t.tZ)("path",{d:`M.5 ${n}V.5H${o}`,fill:"none"})})}),(0,t.tZ)("rect",{width:"100%",height:"100%",strokeWidth:0,fill:`url(#${p})`}),i&&(0,t.tZ)("svg",{x:e,y:r,className:"overflow-visible",children:i.map(s=>{let[a,e]=s;return(0,t.tZ)("rect",{strokeWidth:"0",width:o+1,height:n+1,x:a*o,y:e*n},`${a}-${e}`)})})]})}},86156:function(s,o,n){"use strict";n.d(o,{t:function(){return Guides}});var t=n(97997),a=n(5682),e=n(68289);let r=[{href:"/uses-cases#my-first-bot",name:"My first chatbot",description:"Learn how build your first chatbot in few minutes"},{href:"/concepts",name:"Concepts",description:"Understand the essential concepts for building bots"},{href:"/add-functions",name:"Add Functions",description:"The key to learning how to write flows is add-functions."},{href:"/plugins",name:"Plugins",description:"Unlimitate and start implementing the community plugins."}];function Guides(){return(0,t.BX)("div",{className:"my-16 xl:max-w-none",children:[(0,t.tZ)(e.X,{level:2,id:"guides",children:"Guides"}),(0,t.tZ)("div",{className:"not-prose mt-4 grid grid-cols-1 gap-8  border-zinc-900/5 pt-10 dark:border-white/5 sm:grid-cols-2 xl:grid-cols-4",children:r.map(s=>(0,t.BX)("div",{children:[(0,t.tZ)("h3",{className:"text-sm font-semibold text-zinc-900 dark:text-white",children:s.name}),(0,t.tZ)("p",{className:"mt-1 text-sm text-zinc-600 dark:text-zinc-400",children:s.description}),(0,t.tZ)("p",{className:"mt-4",children:(0,t.tZ)(a.z,{href:s.href,variant:"text",arrow:"right",children:"Read more"})})]},s.href))})]})}},99686:function(s,o,n){"use strict";n.d(o,{_:function(){return Resources}});var t=n(97997),a=n(41664),e=n.n(a),r=n(65512),i=n(40406);function useMotionTemplate(s,...o){let n=s.length;return(0,r.N)(o.filter(i.i),function(){let t="";for(let a=0;a<n;a++){t+=s[a];let n=o[a];n&&(t+=(0,i.i)(n)?n.get():n)}return t})}var l=n(50508),p=n(4960),c=n(86049),k=n(68289);let h=[{href:"/showcases/modularize",name:"Modularize",description:"Learn how to modularise flows so that you can have a more maintainable bot.",icon:function(s){return(0,t.BX)("svg",{viewBox:"0 0 20 20","aria-hidden":"true",...s,children:[(0,t.tZ)("path",{strokeWidth:"0",fillRule:"evenodd",clipRule:"evenodd",d:"M10 .5a9.5 9.5 0 0 1 5.598 17.177C14.466 15.177 12.383 13.5 10 13.5s-4.466 1.677-5.598 4.177A9.5 9.5 0 0 1 10 .5ZM12.5 8a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z"}),(0,t.tZ)("path",{fill:"none",strokeLinecap:"round",strokeLinejoin:"round",d:"M10 .5a9.5 9.5 0 0 1 5.598 17.177A9.458 9.458 0 0 1 10 19.5a9.458 9.458 0 0 1-5.598-1.823A9.5 9.5 0 0 1 10 .5Z"}),(0,t.tZ)("path",{fill:"none",strokeLinecap:"round",strokeLinejoin:"round",d:"M4.402 17.677C5.534 15.177 7.617 13.5 10 13.5s4.466 1.677 5.598 4.177M10 5.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5Z"})]})},pattern:{y:16,squares:[[0,1],[1,3]]}},{href:"/tutorials/api-use",name:"Send Message",description:"How to send a message via HTTP to start conversations, you can send multimedia as well.",icon:function(s){return(0,t.BX)("svg",{viewBox:"0 0 20 20","aria-hidden":"true",...s,children:[(0,t.tZ)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 16.5c4.142 0 7.5-3.134 7.5-7s-3.358-7-7.5-7c-4.142 0-7.5 3.134-7.5 7 0 1.941.846 3.698 2.214 4.966L3.5 17.5c2.231 0 3.633-.553 4.513-1.248A8.014 8.014 0 0 0 10 16.5Z"}),(0,t.tZ)("path",{fill:"none",strokeLinecap:"round",strokeLinejoin:"round",d:"M7.5 8.5h5M8.5 11.5h3"})]})},pattern:{y:-6,squares:[[-1,2],[1,3]]}},{href:"/deploy/docker",name:"Dockerizer",description:"A good practice is to dockerise your bots to make them more maintainable and effective.",icon:function(s){return(0,t.BX)("svg",{viewBox:"0 0 20 20","aria-hidden":"true",...s,children:[(0,t.tZ)("path",{fill:"none",strokeLinecap:"round",strokeLinejoin:"round",d:"M2.5 5.5a2 2 0 0 1 2-2h11a2 2 0 0 1 2 2v8a3 3 0 0 1-3 3h-9a3 3 0 0 1-3-3v-8Z"}),(0,t.tZ)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 10 4.526 5.256c-.7-.607-.271-1.756.655-1.756h9.638c.926 0 1.355 1.15.655 1.756L10 10Z"})]})},pattern:{y:32,squares:[[0,2],[1,4]]}},{href:"/events",name:"Events",description:"Learning about events will make us more fluent when creating chatbots.",icon:function(s){return(0,t.BX)("svg",{viewBox:"0 0 20 20","aria-hidden":"true",...s,children:[(0,t.tZ)("path",{fill:"none",strokeLinecap:"round",strokeLinejoin:"round",d:"M10.046 16H1.955a.458.458 0 0 1-.455-.459C1.5 13.056 3.515 11 6 11h.5"}),(0,t.tZ)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M7.5 15.454C7.5 12.442 9.988 10 13 10s5.5 2.442 5.5 5.454a.545.545 0 0 1-.546.546H8.045a.545.545 0 0 1-.545-.546Z"}),(0,t.tZ)("path",{fill:"none",strokeLinecap:"round",strokeLinejoin:"round",d:"M6.5 4a2 2 0 1 1 0 4 2 2 0 0 1 0-4Z"}),(0,t.tZ)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M13 2a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5Z"})]})},pattern:{y:22,squares:[[0,1]]}}];function ResourceIcon(s){let{icon:o}=s;return(0,t.tZ)("div",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-zinc-900/5 ring-1 ring-zinc-900/25 backdrop-blur-[2px] transition duration-300 group-hover:bg-white/50 group-hover:ring-zinc-900/25 dark:bg-white/7.5 dark:ring-white/15 dark:group-hover:bg-teal-300/10 dark:group-hover:ring-teal-400",children:(0,t.tZ)(o,{className:"h-5 w-5 fill-zinc-700/10 stroke-zinc-700 transition-colors duration-300 group-hover:stroke-zinc-900 dark:fill-white/10 dark:stroke-zinc-400 dark:group-hover:fill-teal-300/10 dark:group-hover:stroke-teal-400"})})}function ResourcePattern(s){let{mouseX:o,mouseY:n,...a}=s,e=useMotionTemplate`radial-gradient(180px at ${o}px ${n}px, white, transparent)`,r={maskImage:e,WebkitMaskImage:e};return(0,t.BX)("div",{className:"pointer-events-none",children:[(0,t.tZ)("div",{className:"absolute inset-0 rounded-2xl transition duration-300 [mask-image:linear-gradient(white,transparent)] group-hover:opacity-50",children:(0,t.tZ)(c.K,{width:72,height:56,x:"50%",className:"absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/[0.02] stroke-black/5 dark:fill-white/1 dar
1k:stroke-white/2.5",...a})}),(0,t.tZ)(l.E.div,{className:"absolute inset-0 rounded-2xl bg-gradient-to-r from-[#D7EDEA] to-[#F4FBDF] opacity-0 transition duration-300 group-hover:opacity-100 dark:from-[#202D2E] dark:to-[#303428]",style:r}),(0,t.tZ)(l.E.div,{className:"absolute inset-0 rounded-2xl opacity-0 mix-blend-overlay transition duration-300 group-hover:opacity-100",style:r,children:(0,t.tZ)(c.K,{width:72,height:56,x:"50%",className:"absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/50 stroke-black/70 dark:fill-white/2.5 dark:stroke-white/10",...a})})]})}function Resource(s){let{resource:o}=s,n=(0,p.c)(0),a=(0,p.c)(0);return(0,t.BX)("div",{onMouseMove:function(s){let{currentTarget:o,clientX:t,clientY:e}=s,{left:r,top:i}=o.getBoundingClientRect();n.set(t-r),a.set(e-i)},className:"group relative flex rounded-2xl bg-zinc-50 transition-shadow hover:shadow-md hover:shadow-zinc-900/5 dark:bg-white/2.5 dark:hover:shadow-black/5",children:[(0,t.tZ)(ResourcePattern,{...o.pattern,mouseX:n,mouseY:a}),(0,t.tZ)("div",{className:"absolute inset-0 rounded-2xl ring-1 ring-inset ring-zinc-900/7.5 group-hover:ring-zinc-900/10 dark:ring-white/10 dark:group-hover:ring-white/20"}),(0,t.BX)("div",{className:"relative rounded-2xl px-4 pb-4 pt-16",children:[(0,t.tZ)(ResourceIcon,{icon:o.icon}),(0,t.tZ)("h3",{className:"mt-4 text-sm font-semibold leading-7 text-zinc-900 dark:text-white",children:(0,t.BX)(e(),{href:o.href,children:[(0,t.tZ)("span",{className:"absolute inset-0 rounded-2xl"}),o.name]})}),(0,t.tZ)("p",{className:"mt-1 text-sm text-zinc-600 dark:text-zinc-400",children:o.description})]})]},o.href)}function Resources(){return(0,t.BX)("div",{className:"my-16 xl:max-w-none",children:[(0,t.tZ)(k.X,{level:2,id:"resources",children:"Resources"}),(0,t.tZ)("div",{className:"not-prose mt-4 grid grid-cols-1 gap-8 border-zinc-900/5 pt-10 dark:border-white/5 sm:grid-cols-2 xl:grid-cols-4",children:h.map(s=>(0,t.tZ)(Resource,{resource:s},s.href))})]})}}},function(s){s.O(0,[3077,2888,179],function(){return s(s.s=55498)}),_N_E=s.O()}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.