2.4.6 • Public • Published

💬 pico-slack

An incredibly tiny Slack bot library



npm install pico-slack


const Slack = require('pico-slack');

Slack.bot.name = 'greetingsbot';
Slack.bot.icon = 'wave';

    .then(()=>Slack.send('general', 'hello world!'))

    if(Slack.has(msg.text, ['hey', 'hello'])){
        Slack.react(msg, 'wave');
        Slack.thread(msg, `Right back at you ${msg.user}!`);


  • simple interface for receiving and sending messages, adding reactions, and starting threads.
  • processes all slack events to be easier to use, reflects them on node event mitters
  • handles all ping events and keeping the connection alive
  • simplifies interface to the most common slack tasks
  • provides advanced error reporting and logging right into slack with smart stack traces
  • comes with an optional bot loader to easily load in several bot scripts
  • under 250 lines!




Creates a web socket connection with Slack using the provided token. On connect, pico-slack will parse and store all team data, see "info". The slack_token will be stored and automatically attached to any API calls. Any events from Slack will be emitted using the .emitter.


Closes the socket.


.send(target, text, [opts])

Sends a message of text to the target. The target can be username, user id, channel name, channel id, or event object. If the event object is in a thread, it will message in that thread.

It uses the chat.postMessage Slack API call, and will pass any opts through to that call, including attachments, custom usernames and icons.

    Slack.send(msg, 'yo!'); //Sends to the same channel as the incoming message

    Slack.send('cool-things-channel', 'complex message', {
        attachments : [{
            "color": "#2eb886",
            "fields": [
                    "title": "Priority",
                    "value": "High",
                    "short": false

.thread(event, text, [opts])

Starts, or continues, a thread on the event with a message of text.

It uses the chat.postMessage Slack API call, and will pass any opts through to that call, including attachments, custom usernames and icons.

    if(Slack.has(msg, 'start a thread here!')){
        Slack.thread(msg, 'can do!');

.react(event, emoji/emojis)

Reacts to an event with the provided emoji. The emoji can be wrapped in : or not, eg. :wave:. If given an array of emojis, it will call .react on each with a small delay between calls to ensure the order in which the emojis were given is ensured.

const movieVote = async (movieName)=>{
    return Slack.send('general', `What did everyone think of ${movieName}?`)
            return Slack.react(movieMsg, ['thumbsdown', ':thumbsup:', ':fire:'])

    if(Slack.has(msg, ['turtle', 'slow'])){
        Slack.react(msg, 'turtle');


event object

The event object is generated from Slack's RTM events and passed to pico-slack's event emitter. All event hanlders will receive an object that has a similar structure. The library does a fair bit of processing to make the data much easier to use. Here's what an event object looks like:

    type        : 'message',
    text        : 'test message',

    user        : 'scott',
    user_id     : 'U0VL783MX',
    channel     : 'general',
    channel_id  : 'C0VL784KT',

    event_ts    : '1564019772.001300',
    ts          : '1564019772.001300',
    team        : 'T0VKSC1BN',

    mentionsBot : false,  //true if the event is in a DM with the bot, or mentions the bot's name
    isDirect    : false,  //true if the event is in a DM


Create a handler for when pico-slack connects/reconnects. If pico-slack is already connected when .onConnect() is called the hanlder will be fired immediately.

Slack.onConnect(()=>Slack.log('I am alive!!'));


Creates a handler for all message events. Most common way to interact with pico-slack.

    if(Slack.has(msg, ['turtle', 'slow'])){
        Slack.react(msg, 'turtle');


Creates a handler for all reaction_added events. If you also want to listen for when reactions are removed, create a custom event handler: .onEvent('reaction_removed', ()=>{}).

    if(event.reaction === 'ice_cream'){
        Slack.send(event, 'Yes please!');

.onChannelMessage(channel_name, handler)

Same as .onMessage() but only fires for specific channels.

Slack.onChannelMessage('super-secret', (event)=>{
    Slack.react(event, 'shushing_face');

.onEvent(event_name, handler)

Creates a handler for any Slack event.

Slack.onEvent('user_typing', (event)=>{
    Slack.send(event, `Watcha typing ${event.user}???`);


Direct access to pico-slack's Event Emitter. Useful if you need to bump the the max number of listeners or do more interesting things.



When pico-slack connects, Slack returns a massive dump of all the team information. pico-slack processes this information and attaches the extracts the most useful bits. Here's an example:

Slack.connected = true
Slack.channels = {
     C0VL2BUUX: 'diagnostics',
     C0VL784KT: 'general',
Slack.channel_ids = {
     diagnostics: 'C0VL2BUUX',
     general : 'C0VL784KT',

Slack.users = {
     U0VKSFTB6: 'higgins',
     U0VL783MX: 'scott'
Slack.user_ids = {
     higgins : 'U0VKSFTB6',
     scott : 'U0VL783MX'

Slack.dms = {
     D0VKSFTBN : 'scott',
     D0VLD2KGA : 'slackbot'
Slack.dm_ids = {
     scott: 'D0VKSFTBN',
     slackbot: 'D0VLD2KGA'

Slack.bot = {
     id: 'U0VKSFTB6',
     name: 'higgins',
     icon: ':robot_face:'
Slack.bots = {
     B0VKVBSQ6: 'U0VKSFTB6',


Your bot information is stored on the .bot object. If you want to change the name of your bot or it's icon, you can simply overwrite the values there

Slack.bot.name = 'butlerbot';
Slack.bot.icon = 'top_hat';


pico-slack uses the channel name stored at .log_channel to determine where to write it's log messags to. You can overwrite this value to change that channel.

Slack.log_channel = 'bot_noise';


.has(text/event, ...filters)

Checks if the given text (or text on the event) passes the filters. The filters can be any number of strings or array of strings. The text must have a substring from each parameter, or at least of one them if it's an array. Case-insenstive.

This is very useful for picking up on various

Slack.has('Hey cool guy', ['greetings', /* OR */ 'hey'], /* AND */ 'cool guy') == true

Slack.has('Hey there!', 'hey') == true //case insensitive

    if(Slack.has(event, ['get', 'grab', 'pick up'], ['lunch', 'food', 'grub'])){
        /* Matches:
            'hey, wanna grab some grub?'
            'Anyone want to pick up some lunch?'
            'FOOD! ME GET FOOD!'

.api(method, arguments)

Direct access to Slack's API. Automatically applies the Slack token to the query.

Slack.api('channels.history', { channel : 'C0VL784KT', count : 5})
        //Fetches the 5 most recent messages from the channel

.alias(bot_name, icon_emoji) -> pico-slack instance

Returns an aliased instance with a different bot name and icon. Useful for making multi-bots that have different identities.

const TriviaBot = Slack.alias('triviabot', 'dice');

    TriviaBot.send(msg, 'Hey!');


pico-slack comes with a pretty useful logging engine. If your bot is connected, when you call Slack.log(args) it will log to the console, but it will also log a slack message to the channel defined at Slack.log_channel. This log message is code formatted and pico-slack runs a trace to give you the file name, line number and function name where the log originated from in the footer of the message.

If any of the values are Error objects, it will instead use their stack trace for the footer information.


Exact same as .log() except it uses console.error() instead of console.log() and colors the slack message red.


One of the most common ways to use pico-slack is to set up a "multi-bot". A single slack bot for your team but each of it's functions are separated into smaller micro-bots.

This is very useful if you want to make something simple, like a bot to check if a website it up and message a channel if it's not. A person on your team can add a uptime.bot.js to your bot witha small script and you are good to go.

What does the bot loader do:

  • Iterates through a folder and all sub-folders to find all files named *.bot.js.
  • requires and loads them. If any experience errors of syntax issues, they will be caught and logged with .error()
  • sets up listeners for unhandledRejection and uncaughtException, and will log them with stack traces.
  • returns an array with an object for each bot; it's name, path, return value and/or error objects.


All opts will be passed through to the internal reference to glob.


    pattern : '**/*.bots.js',
    ignore  : '**/disabled/**' //will ignore any bots in a folder called 'disabled'
const express = require('express');
const app = express();
const Slack = require('pico-slack');
const BotLoader = require('pico-slack/bot-loader.js');

//If a bot returns an express router, load it.
            if(Object.getPrototypeOf(bot.result) == express.Router){
    .then(()=>console.log('test server running: localhost:8000'));
result_bots = [
        name   : 'test',
        path   : 'C:/pico-slack/bots/test.bot.js',
        result : {},
        error  : null



Package Sidebar


npm i pico-slack

Weekly Downloads






Unpacked Size

21.8 kB

Total Files


Last publish


  • stolksdorf