npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@manyducks.co/bot-kit

v0.0.3

Published

Chatbot Toolkit for https://chat.manyducks.co

Readme

@manyducks.co/bot-kit

BotKit is a simple toolkit for building 🦆Chat Bots. Bots are comprised of a webhook handler and an API for interacting with chat. This library abstracts away the gnarly details of handling webhooks and lets you focus on responding to events.

import { Bot } from "@manyducks.co/bot-kit";

// Define your bot.
const bot = new Bot({
  apiKey: process.env.BOT_API_KEY,
  webhookSecret: process.env.BOT_WEBHOOK_SECRET,
  userAgent: "MyBot/1.0"
});

// Handle events sent via webhook.
bot.webhook.on("botMentioned", async (data, api) => {
  // Use the Bot API to respond to messages.
  await api.messages.create({
    roomId: data.room.id,
    replyToMessageId: data.message.id,
    markdown: "You called?"
  });
});

export default {
  fetch(req) {
    // Handler takes a `Request` and returns a `Promise<Response>`.
    return bot.webhook.handle(req);
  }
}

This library should run on any modern JavaScript runtime that supports WebCrypto and fetch:

  • Node 18+
  • Deno 1.11+
  • Bun
  • Cloudflare Workers
  • Supabase Edge Functions

Hono Adapter

A Hono middleware is included so you can mount a bot in an existing Hono app.

import { Hono } from "hono";
import { handleWebhook } from "@manyducks.co/bot-kit/hono";

// ... bot setup ...

const app = new Hono();

app.use(handleWebhook(bot, { path: "/webhook" }));

// ... other routes ...

export default app;

Handling Webhooks

Bots can respond to events that occur in rooms they're in. You create handlers for these events using the .webhook.on method on the Bot instance.

bot.webhook.on("<eventName>", async (data, api) => {
  // Handle <eventName>
});

Event handlers take two arguments; the event data object and a Bot API client. The data object includes info about the room and message, and you can use the api to respond to these events.

Events

This section lists the event types you can listen for. Each event type must be enabled in the Bot's settings within the Chat app in order to be received.

messageSent

Emitted when a message is sent to a room the bot is in.

Data
{
  "room": {
    "id": "<uuid>",
    "emoji": "",
    "name": "Room Name",
    "description": "Description of a room."
  },
  "message": {
    "id": "<uuid>",
    "author": {
      "type": "user", // or "bot"
      "id": "<uuid>",
      "name": "User/Bot Name",
      "hue": 172, // User or bot's accent color in OKLCH hue (0 to 360)
    },
    "text": "The message body in plain text. If it includes mentions they will look like @[this](mention://<type>/<uuid>).",
    "attachments": [
      // TODO: Define this.
    ]
  }
}

botMentioned

Emitted when a message is sent in a room this bot is in, and that message explicitly mentions this bot.

If your bot is also set up to receive messageSent you will get both a messageSent and a botMentioned for one message that mentions the bot.

Data

Same as messageSent

API

The API is accessible in two ways; on the Bot instance, and passed as the second argument to webhook handlers.

If your bot doesn't use webhooks, or if you want to send a message unprompted by a webhook, the API methods are accessible on the api property of a Bot instance.

const bot = new Bot({ /* settings */ });

bot.api.messages.create({
  roomId: "...",
  markdown: "HELLO!"
});

If you want to make API calls in response to a webhook event, you can use the api object passed to the webhook handler. Calling the API this way will associate those calls with the webhook that triggered them, which you will be able to see this in the event log on the Bot settings page in Chat.

bot.webhook.on("messageSent", async (data, api) => {
  return api.messages.create({
    roomId: "...",
    markdown: "HELLO!"
  })
});

Messages API

.messages.create({
  roomId: string,
  markdown: string,
  replyToMessageId?: string
})