Cancelling Commands
If you have long-running command workflows (like waiting for a user to upload an image or type a long response), users can cancel them using specific cancel words.
By default, the cancel words are "cancel" (English) and "cancelar" (Spanish).
For example, if a bot is expecting the user to send an image msg via !forwardmsg, but the user changes their mind and sends "cancel", the command will immediately abort.
Global Config
Section titled “Global Config”You can configure which words should act as global cancellation keywords when you first instantiate the bot:
import Whatsbotcord, { BaileysAdapter } from "whatsbotcord";
const bot = new Whatsbotcord({ commandPrefix: ["$", "!", "/", "."], delayMilisecondsBetweenMsgs: 1, // 1. Define global cancel keywords here cancelKeywords: ["abort", "stop", "cancel"],});Now, any time your command is waiting for user input using a Wait* method, saying “abort”, “stop”, or “cancel” will exit the execution.
Local Config
Section titled “Local Config”You can temporarily override the global cancel keywords just for a single Wait*() method. This is useful if a specific step requires different fallback words, or if “stop” might be a valid answer to a specific prompt!
const imgReceived = await chat.WaitMultimedia(MsgType.Image, { timeoutSeconds: 60, wrongTypeFeedbackMsg: "Hey, send me an img, try again!",
// 2. Override for this wait action only cancelKeywords: ["cancelcustomword"],});In this specific call, only "cancelcustomword" will abort the flow. If you use another WaitMultimedia(...) or WaitMsg(...) method later down the line without providing cancelKeywords, it will fall back to the global bot config (e.g., ["abort", "stop", "cancel"]).
Full Example: An Abortable Command
Section titled “Full Example: An Abortable Command”Here is a complete example of a command that asks for a profile photo. If the user decides they don’t want to change their photo anymore and replies with "cancel", the command halts automatically without executing any further code.
import { MsgType } from "whatsbotcord";import type { AdditionalAPI, IChatContext, CommandArgs, ICommand } from "whatsbotcord/types";
export class UpdatePhotoCommand implements ICommand { public name: string = "updatephoto";
public async run(ctx: IChatContext, api: AdditionalAPI, args: CommandArgs): Promise<void> { await ctx.Loading(); await ctx.SendText("📸 Send me your new profile photo! (Or type 'cancel' to abort)");
// The command will pause here. // If the user sends "cancel" (or any registered keyword), the command is killed instantly. const imgBuffer = await ctx.WaitMultimedia(MsgType.Image, { timeoutSeconds: 60 });
if (!imgBuffer) { await ctx.SendText("You took too long!"); return; }
// This line will NEVER execute if the user sent "cancel". await ctx.SendText("✅ Photo updated successfully!"); await ctx.Ok(); }}Testing Cancellations with ChatMock
Section titled “Testing Cancellations with ChatMock”You can easily verify that your commands correctly abort using ChatMock:
import { test, expect } from "bun:test";import { SenderType } from "whatsbotcord";import { ChatMock } from "whatsbotcord/testing";import { UpdatePhotoCommand } from "./UpdatePhotoCommand.js";
test("User cancels the photo update", async () => { const chat = new ChatMock(new UpdatePhotoCommand(), { senderType: SenderType.Individual });
// Simulate the user sending the cancel keyword chat.EnqueueIncoming_Text("cancel");
await chat.StartChatSimulation();
// Assert that the bot ONLY sent the initial prompt and nothing else! expect(chat.SentFromCommand.Texts).toHaveLength(1); expect(chat.SentFromCommand.Texts[0].text).toContain("Send me your new profile photo!");
// The "Photo updated successfully!" text is never sent because execution aborted.});