Tool CallingE-commerceAutomation

Tool Calling in JestBot: How Your AI Bot Actually Sells Products and Takes Action

Jatin SinghAugust 30, 2026
Tool Calling in JestBot: How Your AI Bot Actually Sells Products and Takes Action

Answering vs. doing

Most chatbots stop at answering FAQs. Ask them about a product's return policy and they'll do fine. Ask them to actually check whether a specific size is in stock right now, apply a discount code, and place the order — and they fall apart, because they were never given a way to reach outside the conversation and touch real systems. JestBot supports tool calling, which is what closes that gap: the bot can call real functions against your inventory system, your CRM, your calendar, or your payment provider, instead of just describing what it would theoretically do.

How tool calling works under the hood

Modern language models can be given a list of available "tools" — essentially function signatures with a name, a description, and a set of typed parameters. When the model decides a tool is needed to answer accurately, it doesn't guess an answer; it emits a structured call to that tool instead. Your backend executes the actual function, returns the result to the model, and the model folds that real data into its final reply to the customer. This loop can repeat several times in a single turn if the model needs more than one piece of live data to answer properly.

Defining a tool

A tool definition in JestBot looks like a small JSON schema describing what the function does and what arguments it needs.

const checkStockTool = {
  name: "check_product_stock",
  description: "Checks live stock for a product SKU and size",
  parameters: {
    type: "object",
    properties: {
      sku: { type: "string" },
      size: { type: "string" },
    },
    required: ["sku"],
  },
};

The description matters more than it looks — it's what the model reads to decide when this tool is relevant. A vague description leads to a bot that either never calls the tool when it should, or calls it when it shouldn't. Writing a clear, specific description is the single highest-leverage thing you can do when defining a new tool.

Letting the model decide when to call it

You don't hard-code "if the user mentions stock, call this function." Instead, you hand the model the full list of available tools for the conversation, and it decides — based on what the customer actually asked — whether a tool call is needed at all.

const result = await toolOrchestrator.run({
  tools: [checkStockTool, applyCouponTool, createOrderTool],
  onToolCall: async (call) => {
    if (call.name === "check_product_stock") return inventoryService.getStock(call.args.sku, call.args.size);
    if (call.name === "apply_coupon") return couponService.validateAndApply(call.args.code, call.args.orderId);
    if (call.name === "create_order") return orderService.create(call.args);
  },
});

If the customer just asks "what's your return policy?", no tool gets called at all — the answer comes straight from the retrieved documentation, the same as any other RAG-grounded reply. Tools only fire when the question genuinely needs live data or a real action.

Chaining multiple tools into a real sale

The real value shows up when tools chain together. A single customer message like "I want the medium in blue, and I have a discount code SAVE10" can trigger a sequence: check stock for that SKU and size, validate the coupon, create the order, and send a confirmation — all inside one conversational turn.

// Simplified multi-step flow inside one conversation
const stock = await inventoryService.getStock(sku, "M");
if (stock.available > 0) {
  const coupon = await couponService.validateAndApply("SAVE10", null);
  const order = await orderService.create({ sku, size: "M", couponId: coupon.id, customerId });
  await whatsappSender.send(customerPhone, `Order confirmed! ${order.id} — total ₹${order.total}`);
}

From the customer's point of view, they just had one conversation and walked away with a confirmed order — on the website widget, on WhatsApp, or over a phone call with the AI calling agent, since the same tool orchestrator runs behind every channel.

Beyond checkout: lead capture and scheduling tools

Not every business sells a physical product through a bot — plenty use the exact same tool-calling mechanism to qualify and capture leads, or to book a call instead of closing a sale directly. A create_lead tool can push a qualified conversation straight into your CRM with the details the bot already gathered, and a schedule_demo tool can check a sales rep's real calendar availability and lock in a slot without anyone touching a scheduling link.

const scheduleDemoTool = {
  name: "schedule_demo",
  description: "Books a product demo on the sales team's shared calendar",
  parameters: {
    type: "object",
    properties: { date: { type: "string" }, time: { type: "string" }, email: { type: "string" } },
    required: ["date", "time", "email"],
  },
};

Guardrails: not every action should be fully automatic

Not every tool should execute without a check. For higher-risk actions — issuing a refund above a certain amount, canceling a subscription, or making changes to account-level settings — JestBot supports requiring human approval before the tool actually runs, so the bot can prepare the action and hand it to an agent to confirm rather than executing it blind.

const refundTool = {
  name: "issue_refund",
  description: "Issues a refund for an order",
  requiresApproval: (args) => args.amount > 2000,
  parameters: { type: "object", properties: { orderId: { type: "string" }, amount: { type: "number" } } },
};

Handling tool failures gracefully

Real systems fail — an inventory API times out, a payment provider is briefly down, a webhook returns an error. A tool call that fails shouldn't crash the conversation or leave the customer staring at a blank reply. JestBot's tool orchestrator catches failures and lets the model explain the situation honestly and offer a fallback, such as taking the order manually or trying again in a moment, instead of pretending the action succeeded.

try {
  return await inventoryService.getStock(call.args.sku);
} catch (err) {
  return { error: true, message: "Stock system is temporarily unavailable" };
}

Extending with custom tools and webhooks

Your inventory system, CRM, and payment provider are all different, so JestBot doesn't lock you into a fixed set of tools. Any tool can be backed by a webhook to your own backend, meaning you can connect a bot to essentially any internal system that exposes an API — a booking system, a ticketing platform, a Google Sheet, or a custom microservice.

const bookMeetingTool = {
  name: "book_meeting",
  description: "Books a meeting slot on the sales team's calendar",
  webhookUrl: "https://yourapp.com/api/webhooks/book-meeting",
  parameters: { type: "object", properties: { date: { type: "string" }, time: { type: "string" } } },
};

Real-world example: the full checkout flow

Put together, a typical selling conversation looks like this: the bot answers a product question from the knowledge base, checks live stock when the customer asks about a specific variant, applies a coupon if one is mentioned, creates the order once the customer confirms, and sends a receipt — either through WhatsApp, the website widget, or read aloud on a call. None of this requires the customer to leave the conversation and go find a checkout page, which is exactly why tool-calling bots convert better than FAQ-only ones.

Measuring the impact

Because every tool call is logged against the conversation, your analytics dashboard can show not just "messages sent" but outcomes: how many conversations resulted in a completed order, how often a coupon tool was triggered, and where in the funnel customers drop off before a sale completes — data a plain FAQ bot simply can't give you.

Tools that read vs. tools that write

It helps to mentally split your tools into two categories. Read tools — checking stock, looking up an order status, fetching a customer's plan details — carry very little risk if the bot calls them a bit too eagerly, since they don't change anything. Write tools — creating an order, applying a coupon, issuing a refund, canceling a subscription — change real state and deserve more scrutiny, tighter parameter validation, and in many cases the approval step described above. A useful rule when designing a new tool is to ask what the worst case looks like if the model calls it with slightly wrong arguments; for a read tool the answer is usually "a slightly odd reply," while for a write tool it can be "a real order nobody wanted." Size your guardrails accordingly.

Selling across channels with the same tools

A tool defined once works identically whether the customer is on the website widget, messaging on WhatsApp, chatting inside your mobile app through the SDK, or talking to the AI calling agent on the phone. That means a discount code you're running as a WhatsApp-only campaign this week can be extended to every channel by simply mentioning it in the bot's instructions — no separate integration work for each surface. This is also what makes cross-channel promotions practical: a customer who hears about a sale through an outbound reminder call can complete the purchase over WhatsApp minutes later, with the same coupon tool validating the same code either way.

Testing tools before they go live

A tool that's wrong in production doesn't just give a bad answer — it can create a real order, apply a coupon that shouldn't exist, or issue a refund nobody approved. Before turning a new tool on for real customers, it's worth running it against a sandbox version of your inventory, CRM, or payment system, or at minimum a set of test SKUs and test coupon codes, and deliberately trying to break it: ask for an out-of-stock item, apply an expired coupon, request a quantity larger than what's available. A tool that fails cleanly and lets the model explain the situation is ready; a tool that throws an unhandled error or silently does the wrong thing needs another pass.

Rate limiting and abuse prevention

Once a bot can take real actions like creating orders or applying coupons, it becomes a target the same way any checkout flow is — someone might try to spam a coupon-application tool to find a working code, or flood an order-creation tool as a denial-of-service attempt. JestBot rate-limits tool calls per conversation and per customer, and higher-risk tools like coupon redemption and refunds can be configured with their own tighter limits, so a single conversation can't hammer a sensitive action beyond what a normal customer interaction would ever need.

Frequently asked questions

Can a tool call real payment providers, not just check inventory? Yes — any external API your business already uses, including payment providers, can be wired up as a tool through a webhook.

What stops the bot from taking a risky action by mistake? The requiresApproval option lets you force human confirmation on any tool above a threshold you define, so higher-risk actions never execute unattended.

Do tools work the same on every channel? Yes — the tool orchestrator is shared across the widget, WhatsApp, the mobile SDK, and the AI calling agent, so a tool you define once works identically everywhere.

Is there protection against someone spamming a tool like coupon redemption? Yes — tool calls are rate-limited per conversation and per customer, with tighter limits available for sensitive actions.

Where to start

Start with one high-value tool — usually stock checking or order creation — get it working reliably on the widget, then extend to a second tool like coupon application. Once a small chain of tools is solid, the same configuration works identically on WhatsApp, the mobile SDK, and the AI calling agent, since they all run through the same tool orchestrator.

Tool Calling in JestBot: How Your AI Bot Actually Sells Products and Takes Action | JestBot