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 🙏

© 2026 – Pkg Stats / Ryan Hefner

allsend

v0.1.0

Published

Open-source multi-channel communication hub for AI projects

Readme

Allsend

Open-source, self-hostable multi-channel communication hub for AI projects

License: MIT TypeScript Bun

What is allsend?

Allsend provides a unified API for communicating across multiple messaging platforms. Instead of building custom integrations for each platform, use Allsend's normalized message protocol and pluggable adapters.

✨ Features

  • 🔌 Pluggable Adapters - Telegram, Discord, WhatsApp, iMessage
  • 📊 Real-time Dashboard - Monitor all channels in one place
  • 💾 Convex Integration - Real-time database with automatic sync
  • 🐳 Self-Hostable - Run on your own infrastructure
  • 🔄 Unified Protocol - One API for all platforms
  • Built with Bun - Fast, modern TypeScript runtime

Supported Channels

| Channel | Status | Official API | Notes | |---------|--------|--------------|-------| | Telegram | ✅ Ready | ✅ Yes | Full Bot API support | | Discord | ✅ Ready | ✅ Yes | Gateway + REST API | | WhatsApp | ✅ Ready | ⚠️ Business API | Via whatsapp-web.js | | iMessage | ✅ Ready | ❌ Via BlueBubbles | Requires macOS |

Quick Start

Prerequisites

  • Bun v1.0 or later
  • Node.js 18+ (for some dependencies)

Installation

# Clone the repository
git clone https://github.com/yaantow/allsend.git
cd allsend

# Install dependencies
bun install

# Build all packages
bun run build

Setup Your First Bot

  1. Configure environment variables:
cp .env.example .env
# Edit .env with your bot tokens
  1. Start the API server:
bun run dev:api
  1. Start the dashboard (optional):
# In a new terminal
bun run dev:dashboard
# Open http://localhost:5173

Usage

Basic Example

import { createHub } from '@allsend/core';
import { TelegramAdapter } from '@allsend/adapter-telegram';

// Create the hub
const hub = createHub();

// Register a Telegram adapter
hub.registerAdapter(new TelegramAdapter({
  id: 'my-telegram-bot',
  type: 'telegram',
  name: 'My Bot',
  enabled: true,
  credentials: {
    token: process.env.TELEGRAM_BOT_TOKEN!,
  },
}));

// Listen for messages from any channel
hub.on('message', (message) => {
  console.log(`[${message.channelType}] ${message.sender.displayName}: ${message.content}`);
  
  // Reply back
  if (message.content.type === 'text' && message.content.text === '/hello') {
    hub.reply(message, { type: 'text', text: 'Hello from Allsend! 🚀' });
  }
});

// Start all adapters
await hub.start();

Multi-Channel Setup

import { createHub } from '@allsend/core';
import { TelegramAdapter } from '@allsend/adapter-telegram';
import { DiscordAdapter } from '@allsend/adapter-discord';

const hub = createHub();

// Register multiple adapters
hub.registerAdapter(new TelegramAdapter({
  id: 'telegram-main',
  type: 'telegram',
  name: 'Telegram Bot',
  enabled: true,
  credentials: { token: process.env.TELEGRAM_BOT_TOKEN! },
}));

hub.registerAdapter(new DiscordAdapter({
  id: 'discord-main',
  type: 'discord',
  name: 'Discord Bot',
  enabled: true,
  credentials: { token: process.env.DISCORD_BOT_TOKEN! },
}));

// Same message handler works for all channels!
hub.on('message', (message) => {
  hub.reply(message, { 
    type: 'text', 
    text: `Received on ${message.channelType}: ${message.content.text}` 
  });
});

await hub.start();

Architecture

┌─────────────────────────────────────────────┐
│              Your Application               │
└─────────────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────┐
│           Allsend Unified API               │
│  ┌─────────────────────────────────────┐   │
│  │     Normalized Message Protocol      │   │
│  └─────────────────────────────────────┘   │
└─────────────────────────────────────────────┘
         │         │         │         │
         ▼         ▼         ▼         ▼
    ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
    │Telegram│ │Discord │ │WhatsApp│ │iMessage│
    └────────┘ └────────┘ └────────┘ └────────┘

Project Structure

allsend/
├── packages/
│   ├── core/                 # Unified protocol & ChannelHub
│   ├── adapter-telegram/     # Telegram Bot API adapter
│   ├── adapter-discord/      # Discord.js adapter
│   ├── adapter-whatsapp/     # WhatsApp Web adapter
│   └── adapter-imessage/     # BlueBubbles integration
├── apps/
│   ├── api/                  # Production API server
│   └── dashboard/            # Real-time admin dashboard
├── convex/                   # Convex backend (schema, functions)
├── docs/                     # Documentation files
└── docker-compose.yml        # Self-hosting config

Self-Hosting

Using Docker

# Start all services
docker-compose up -d

# Access dashboard at http://localhost:5173
# API server at http://localhost:3000

Manual Setup

# 1. Install dependencies
bun install

# 2. Setup Convex (optional, for dashboard)
npx convex dev

# 3. Start the server
bun run examples/server.ts

# 4. Start dashboard (in another terminal)
cd apps/dashboard && bun run dev

Environment Variables

Create a .env file in the root directory:

# Telegram
TELEGRAM_BOT_TOKEN=your_telegram_bot_token

# Discord
DISCORD_BOT_TOKEN=your_discord_bot_token

# BlueBubbles (for iMessage)
BLUEBUBBLES_URL=http://localhost:1234
BLUEBUBBLES_PASSWORD=your_password

# Convex (auto-generated by `npx convex dev`)
CONVEX_URL=https://your-project.convex.cloud

API Reference

ChannelHub

The central hub that manages all adapters.

const hub = createHub();

// Register adapters
hub.registerAdapter(adapter);

// Events
hub.on('message', (message) => {});
hub.on('event', (event) => {});
hub.on('adapter:connected', (adapterId, type) => {});
hub.on('adapter:disconnected', (adapterId, type, reason) => {});
hub.on('adapter:error', (adapterId, error, context) => {});

// Send messages
hub.reply(message, content);
hub.send(channelType, conversationId, content);

// Lifecycle
await hub.start();
await hub.stop();

Unified Message Format

interface UnifiedMessage {
  id: string;
  platformMessageId: string;
  channelType: 'telegram' | 'discord' | 'whatsapp' | 'imessage';
  conversationId: string;
  sender: {
    platformId: string;
    displayName: string;
    username?: string;
  };
  content: MessageContent;
  timestamp: Date;
  isOutgoing: boolean;
  replyTo?: string;
}

type MessageContent =
  | { type: 'text'; text: string }
  | { type: 'image'; url: string; caption?: string }
  | { type: 'video'; url: string; caption?: string }
  | { type: 'audio'; url: string; isVoiceNote?: boolean }
  | { type: 'file'; url: string; filename: string }
  | { type: 'location'; latitude: number; longitude: number }
  | { type: 'sticker'; url: string };

Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Development

# Run in development mode
bun run dev

# Build all packages
bun run build

# Run tests
bun test

License

MIT © Allsend Contributors