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

omnimsg

v1.0.1

Published

Universal messaging SDK for Mattermost, Discord, and more

Readme

omnimsg

Universal messaging SDK for Mattermost, Discord, and more.

Omnimsg provides a clean, type-safe TypeScript interface for sending messages to multiple messaging platforms through a unified API.

Features

  • 🚀 Type-safe: Full TypeScript support with comprehensive type definitions
  • 🔌 Multiple Providers: Support for Mattermost and Discord (easily extensible)
  • 📦 Lightweight: Minimal dependencies, zero runtime overhead for TypeScript users
  • 🛡️ Error Handling: Comprehensive error classes and validation
  • 🔄 Retry Logic: Built-in retry support with exponential backoff
  • Modern ES: Written in TypeScript, targeting ES2020+

Installation

# npm
npm install omnimsg

# yarn
yarn add omnimsg

# pnpm
pnpm add omnimsg

Quick Start

import { Omnimsg, PROVIDER } from 'omnimsg';

const client = new Omnimsg();

// Configure Mattermost
const mattermost = client.provider(PROVIDER.MATTERMOST, {
  webhookUrl: 'https://your-mattermost.com/hooks/xxxxxxxxxxxxxxxxxxxxxxxxxx',
  channelName: 'general',
  username: 'Notifier Bot',
  iconUrl: 'https://example.com/icon.png',
  iconEmoji: ':robot_face:'
});

// Send a message to Mattermost
await mattermost.send({
  text: 'Hello from omnimsg!',
  attachments: [{
    color: 'good',
    title: 'Success',
    text: 'Message sent successfully'
  }]
});

// Configure Discord
const discord = client.provider(PROVIDER.DISCORD, {
  webhookUrl: 'https://discord.com/api/webhooks/xxxx/yyyy',
  username: 'Notifier',
  avatarUrl: 'https://example.com/avatar.png'
});

// Send an embed to Discord
await discord.send({
  content: 'Hello from omnimsg!',
  embeds: [{
    title: 'Notification',
    description: 'This is an embed from omnimsg',
    color: 0x00ff00,
    fields: [
      { name: 'Status', value: '✅ Success', inline: true },
      { name: 'Time', value: new Date().toISOString(), inline: true }
    ]
  }]
});

Provider Configuration

Mattermost

const mattermost = client.provider(PROVIDER.MATTERMOST, {
  webhookUrl: 'https://mattermost.example.com/hooks/xxxxxxxxx', // Required
  channelName: 'general',      // Optional - overrides webhook's default channel
  username: 'Bot Name',        // Optional - overrides webhook's default username
  iconUrl: 'https://...',      // Optional - bot avatar URL
  iconEmoji: ':robot_face:',   // Optional - bot emoji
  timeout: 30000,              // Optional - request timeout in ms
  retries: 3                   // Optional - number of retries
});

Mattermost Message Format

await mattermost.send({
  text: 'Hello world!',               // Optional - message text with markdown support
  channel: 'custom-channel',          // Optional - override default channel
  username: 'Custom Bot',             // Optional - override default username
  iconUrl: 'https://...',             // Optional - override avatar
  iconEmoji: ':wave:',                // Optional - override emoji
  attachments: [{
    fallback: 'This is an attachment', // Required for attachments
    color: '#36a64f',                 // Optional - hex color code
    pretext: 'Optional pretext',       // Optional - text before attachment
    author_name: 'Author',            // Optional
    author_link: 'https://...',       // Optional
    author_icon: 'https://...',       // Optional
    title: 'Attachment Title',        // Optional
    title_link: 'https://...',        // Optional
    text: 'Main attachment text',     // Optional
    fields: [                         // Optional
      {
        title: 'Field 1',
        value: 'Value 1',
        short: true
      }
    ],
    image_url: 'https://...',         // Optional
    thumb_url: 'https://...',         // Optional
    footer: 'Footer text',            // Optional
    footer_icon: 'https://...',       // Optional
    ts: Date.now() / 1000             // Optional - timestamp
  }],
  props: {                             // Optional - custom properties
    custom_field: 'value'
  }
});

Discord

const discord = client.provider(PROVIDER.DISCORD, {
  webhookUrl: 'https://discord.com/api/webhooks/xxxx/yyyy', // Required
  username: 'Bot Name',         // Optional - overrides webhook's default username
  avatarUrl: 'https://...',     // Optional - overrides webhook's default avatar
  timeout: 30000,               // Optional - request timeout in ms
  retries: 3                    // Optional - number of retries
});

Discord Message Format

await discord.send({
  content: 'Hello world!',           // Optional - message text (max 2000 chars)
  username: 'Custom Bot',            // Optional - override default username
  avatarUrl: 'https://...',          // Optional - override avatar
  tts: false,                        // Optional - text-to-speech
  embeds: [{                         // Optional - array of embeds (max 10)
    title: 'Embed Title',            // Optional (max 256 chars)
    description: 'Embed description', // Optional (max 4096 chars)
    url: 'https://...',              // Optional
    color: 0x00ff00,                 // Optional - hex color
    timestamp: new Date().toISOString(), // Optional
    footer: {                        // Optional
      text: 'Footer text',
      icon_url: 'https://...'
    },
    image: {                         // Optional
      url: 'https://...'
    },
    thumbnail: {                     // Optional
      url: 'https://...'
    },
    author: {                        // Optional
      name: 'Author Name',
      url: 'https://...',
      icon_url: 'https://...'
    },
    fields: [                        // Optional (max 25 fields)
      {
        name: 'Field Name',          // Required (max 256 chars)
        value: 'Field Value',        // Required (max 1024 chars)
        inline: true                 // Optional
      }
    ]
  }],
  allowed_mentions: {                // Optional
    parse: ['users', 'roles'],
    users: ['user-id'],
    roles: ['role-id'],
    replied_user: true
  },
  components: [{                     // Optional - UI components
    type: 1,
    components: [{
      type: 2,
      style: 1,                      // 1=primary, 2=secondary, 3=success, 4=danger, 5=link
      label: 'Button',
      custom_id: 'button_click',
      emoji: {
        name: '👍'
      }
    }]
  }]
});

Error Handling

Omnimsg provides comprehensive error handling with specific error types:

import {
  MessagingError,
  ConfigurationError,
  ValidationError,
  NetworkError,
  RateLimitError,
  AuthenticationError
} from 'omnimsg';

try {
  await provider.send(message);
} catch (error) {
  if (error instanceof ConfigurationError) {
    console.error('Configuration error:', error.message);
  } else if (error instanceof ValidationError) {
    console.error('Validation error:', error.message);
  } else if (error instanceof RateLimitError) {
    console.error('Rate limited, retry after:', error.retryAfter);
  }
  // ... handle other error types
}

Advanced Usage

Managing Multiple Providers

const client = new Omnimsg();

// Configure multiple providers
client.provider(PROVIDER.MATTERMOST, mattermostConfig);
client.provider(PROVIDER.DISCORD, discordConfig);

// Get configured providers
const configured = client.getConfiguredProviders();
console.log(configured); // ['mattermost', 'discord']

// Check if a provider is configured
if (client.isProviderConfigured(PROVIDER.MATTERMOST)) {
  // Use the provider
}

// Remove a provider
client.removeProvider(PROVIDER.MATTERMOST);

Sending Messages Directly

const client = new Omnimsg();

// Configure providers first
client.provider(PROVIDER.MATTERMOST, mattermostConfig);
client.provider(PROVIDER.DISCORD, discordConfig);

// Send messages using the client
const result1 = await client.send(PROVIDER.MATTERMOST, mattermostMessage);
const result2 = await client.send(PROVIDER.DISCORD, discordMessage);

Custom Configuration

const mattermost = client.provider(PROVIDER.MATTERMOST, {
  webhookUrl: 'https://...',
  timeout: 60000,    // 60 second timeout
  retries: 5,        // 5 retries on failure
  channelName: 'alerts',
  username: 'Alert Bot'
});

API Reference

Classes

  • Omnimsg - Main client class for managing providers
  • MattermostProvider - Mattermost-specific provider implementation
  • DiscordProvider - Discord-specific provider implementation

Types

  • PROVIDER - Enum of available providers
  • MattermostConfig - Mattermost provider configuration
  • MattermostMessage - Mattermost message format
  • DiscordConfig - Discord provider configuration
  • DiscordMessage - Discord message format
  • SendResult - Result of a send operation

Errors

  • MessagingError - Base error class
  • ConfigurationError - Invalid configuration
  • ValidationError - Invalid message format
  • NetworkError - Network-related errors
  • RateLimitError - Rate limit exceeded
  • AuthenticationError - Authentication failed

Development

# Install dependencies
pnpm install

# Build the project
pnpm build

# Run tests
pnpm test

# Watch mode
pnpm dev

# Type checking
pnpm type-check

# Linting
pnpm lint

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT © Ashik

Related Projects