Weechat for Slack

Wee-slack lets you use Slack from within Weechat. All the main features of Slack work - including threading and emojis - and the overall experience is nicely integrated with Weechat. Using Slack from Weechat is much more efficient so it's easy to monitor multiple workspaces and it's less intrusive as notifications are very configurable: Slack in the browser uses a horrifying amount of memory and CPU. If you use Weechat for IRC generally, then this means Slack no longer feels like a different universe. I use it extensively for both work and hobby Slack.

Slack running in Weechat, with two workspaces being accessed

Figure 1: Two Slack Workspaces in Weechat with multiple channels

There are plenty of blog posts on how to use Slack's IRC bridge to connect using Weechat, but Wee-slack is an improvement because it's using Slack's native protocol which gives us capabilities like threading. It's a tremendous project with over 79 contributors, led by Rawdigits and Trygveaa. In this post we'll install Slack for Weechat and cover the main features.

This post is part 3 of a four part series:

Installing Wee-Slack

Wee-Slack is available through the Scripts buffer within Weechat: if you need a reminder on how to manage Scripts see my post on configuring Weechat. The version in the Scripts buffer is the last release from the Github page. To play with the latest development release it can be installed manually.

The first thing is to install python-websocket.

$ sudo apt-get install python-websocket

# alternatively, install locally with pip
$ pip install --user websocket_client

To install Wee-slack from within Weechat do:

# make sure that python is loaded
/script
#<scroll until you find slack>
/script show slack.py
/script install slack.py

To do a manual install:

$ wget https://raw.githubusercontent.com/wee-slack/wee-slack/master/wee_slack.py
cp wee_slack.py ~/.weechat/python/autoload

When you start Weechat in the main buffer it shows scripts it has loading - it should say slack is loaded.

Joining a Slack Workspace

To use Slack we need a token for each Slack Workspace we want to login to. There are two types of token we can use - either a Session token or an OAuth token. A session token is more powerful so try to use this if you can. The main thing to bear in mind about a session token is that it can't be revoked so don't use it on a shared system (or make sure you encrypt it using the Weechat secure capability).

Firefox window with the developer console showing

Figure 2: Getting the session token for Clojurians Slack in Firefox

Let's say that you've developed an interest in the Java based functional programming language Clojure and have decided to join their Clojurians Slack. The first step is to create an account for that Slack workspace.

  • Open the Slack customization page

    Go to https://my.slack.com/customize or go to a Slack workspace in the browser and choose 'Customize Workspace' from the main menu on the left.

  • Open the developer console

    Open up the browser's developer console. In Chromium this is <Ctrl>+<Shift>+j, and in Firefox it is <Ctrl>Shift>+k.

  • Get the session token

    The prompt is at the bottom of the 'console' window. Add the code below and a small dialog window will appear with the session code in it - to highlight all of it use <Shift> and the arrow keys to grab the whole of the string.

    window.prompt("Session token:", TS.boot_data.api_token)
    
  • Secure the token

    If you'd like to keep the token secure then you can set a passphrase when you start Weechat and encrypt the token. This is the same system we used previously for storing IRC passwords.

    # when you set this you have to unlock Weechat with this password every time you start it
    /secure passphrase "this is a super secret password"
    
    # store the token in the secure area and then use it as a variable in wee-slack's configuration
    # do not put quotes around the slack_token or it will fail
    /secure set slack_token <YOUR_SLACK_TOKEN>
    /set plugins.var.python.slack.slack_api_token ${sec.data.slack_token}
    
    # save this configuration to disk
    /save
    

Note

Do Not put quote marks around the slack token when you set it, the token is something like xoxs-XXXX. It shows it with quotes around it when you display it.

  • Reload and login to Slack

    The script is now ready and we can reload or restart Weechat so it logs into the Slack workspace.

    /python reload slack
    

Multiple Slack Workspaces

To join multiple Slack Workspaces we store multiple tokens (one token per Workspace) in a comma separated list.

For our example lets say that you'd like to join the Weave Community Slack. After you've created a login there and gone through the steps above to get the token we need to add them to the slack_api_token list.

You can list the tokens that you have for the current Slack Workspaces by using the /secure buffer. Press <Alt>v and it will show them unencrypted. Then press <Alt>l to have a raw buffer that you can cut-n-paste the tokens out of. It's then easy to use a temporary file somewhere to organise the tokens.

# in Weechat get the existing tokens
/secure

# if you used a secure list
# NOTE: it is not a string: /set slack_token xoxs-XXXX,xoxs-XXX
/secure set slack_token <your_slack_token1,slack_token2,etc>

/save

# reload the slack plugin will connect to the new workspace
/python reload slack

# see the teams that are connected
/slack teams

It's very important not to set the slack_token as a string or with any spaces between the tokens or it will fail: it shows it as a string when you do /secure, but you don't send them as a string.

I had some problems logging into multiple Workspaces when my connection was slow. If this happens the best solution is to turn on debug, and to lengthen the slack_timeout. In my case, after restarting Weechat a few times it did eventually login to the Workspace, and seemed fine after it had logged in the first time.

# opens a separate debug buffer
/set plugins.var.python.slack.debug_mode on
/set plugins.var.python.slack.debug_level 0

# default is 20000
/set plugins.var.python.slack.slack_timeout 80000

Usage and Help

The main Slack commands that you type into a channel (buffer) use the /slack prefix. There are also some shortcut commands that you can type. To get help:

/slack help
/slack help <command>

Handling channels

Just like IRC Slack has channels that you can join, and each one will open a buffer.

/slack join <channel>
/join <channel>

# lists all channels - do it from the buffer specific to
# the slack workspace
/slack channels

# create a public or private channel
/slack create [-private] <channel_name>

To list the channels do /slack channels from the Slack Workspaces buffer, you can't do an IRC /list.

To leave a channel do:

/close <channel>

Chatting directly

To talk directly to one or more people use the /slack talk command.

/slack talk <username>[, <user2>, <userN>]
/query <username>

You can use the IRC command or the slack specific one.

/msg <username> message

Handling threads

Slack can display threaded conversations in a channel or a one-to-one conversation: this is the only feature that is an advantage over IRC! Weechat handles this by creating a temporary buffer for each thread that we want to view.

Weechat showing a Slack chat thread in a temporary buffer

Figure 3: A thread conversation started from the #beginners channel

When reading through a channel we'll sometimes see an indicator that there is a thread. For example in Figure 1 above we see [ Thread: 090 Replies: 1 ]. We can open this thread up as a new temporary buffer by referring to it's message ID - /thread 090. The buffer that's opened is the name of the message ID with a dollar prefix - it will be shown offset in against the channel.

# Open thread for the message in a thread buffer
# either specify a message id or it will use the last message in the channel
/thread [message_id] <message>

To start a thread reply to a message. Weechat will start a thread on the last message with /reply <message>.

Often, we want to start a thread on a message higher up in the buffer. The easiest way is start with /reply and then use the mouse and right click on the message to reply to, this will automatically put it's message ID into the reply.

Rather than using the message ID we can use a count up the buffer, so to start a thread on the third message up in the back scroll we'd do /reply 3 <message>.

# a reply will create a specific thread buffer
# as you're in a channel you don't need '/slack /reply'
/reply <count/message_id> <message>
/reply 3 a new thread

# right click with your mouse to get the message id
/reply $841 ah right lets discuss on a thread

Chatting in the thread buffer works as normal - anything sent will appear in the thread. When a thread has finished it can be shut with a normal /close.

# subscribe to a thread if you're in the thread buffer
/slack subscribe
/slack unsubscribe

# subscribe to a thread number - if you're in a channel
/slack subscribe <thread>
/slack unsubscribe <thread>

# label it with something memorable - this is for this session only
# in the thread buffer
/label <some name>

By default Wee-slack will send a notification of any new messages on the thread. To silence the thread use the /unsubscribe command in the thread buffer - this command requires a session token.

If a thread is long-running, rather having the buffer as a variable (e.g. $34a) it can be named to something:

# change the channel or thread buffer to a name
/slack label <name> -unset
/slack label birthdaygreets

Set Status

Scripts buffer showing a list of user scripts that can be installed

Figure 4: Setting /slack away and status

To set status quickly use /slack away and /slack back:

/slack away
/slack back

# set your status
/slack status [<emoji> [<status_message>] -delete]
/slack status :runner: Out running
/slack status :fork_and_knife: Lunch

# check what your status is
/slack status

# delete the status
/slack status -delete

When you do /slack away it changes the text input field in Weechat to show (manual away).

If you'd like to set a more complex message then you can use the /slack status command. Just like in Web Slack you have to give it an emoji (it defaults to :speech_balloon: when in the browser) to set a more complex status. See Figure 4 above for an example of a complex status.

To see the current status use /slack status and it will tell you.

Add a reaction

Everyone loves an emoji reaction to echo a sentiment in Slack. Weechat can show these but configuration is needed so that they display correctly - see the configuration section.

Adding an emoji character as a reaction to a chat

Figure 5: Showing an emoji reaction

Using + reacts to the last message, if you put a number in it will be the Nth previous message. Using - removes the reaction. The mouse also works, just right click on the emoji and it will add your reaction to the existing one, click on it again to remove it.

To add a reaction to a message higher up in the chat window right click on the message to get the message ID, then add a plus and the emoji you want.

# adds a :smile: reaction to the last message
+:smile:

# right click with the mouse and it will provide a message id
# then add + and the emoji you want :[emoji]:
$841+:smile:

# adds a :smile: reaction to a message that is 3 back
3+smile:

# removes the :smile: reaction from the last message
-:smile:

Modify or delete a message

Modifying and deleting the previous message uses a familiar syntax:

s/old text/new text/
s/old text/new text/g
s/old text/new text/gi

If you use g it replaces all instances of the old text in the previous message. If you use i it will ignore case, and if you use m then it enables ^ to match the start of each line and $ to match the end of the line.

To edit a message further up you need to count the position of the message up the buffer or use the message ID. It's easiest to get the message ID with the mouse by right clicking on the message, it will insert the message ID into the input line:

# search through the message 4th up and modify it
4s/old part/new part/

# right click on a message and it inserts the message id
$512s/old part/new part/

There's not a built-in command to delete a message. There are two ways:

# do a search and replace it with nothing
s///

# right click the message you want to delete to insert the message id
$544s///

Run any Slack command

As Slack can be extended with other applications it's useful to be able to run any Slack command from Weechat:

/slack slash /desiredcommand arg1 arg2

For example if you use reminders a lot:

# change to your own buffer
/slack talk <user-name>

# set a reminder and list reminders
/slack slash /remind me email Bob tomorrow
/slack slash /remind list

/slack slash /dnd until 2pm

Upload a file

To share files with a team member use the /slack upload command and it will put it into the buffer. I have to admit this is one where it's easier to open up a browser tab to do it as you have to know the path.

/slack upload [file_path]

Talk to a user group

A user group is a set of usernames in a workspace who often need to be notified at once. In the same way you can mention a specific person by using @<username>, you can form a group and then do @<group-name>.

# show all usergroups
/slack usergroups

# show members of a usergroup
/slack usergroups <usergroup>

The default is that owners and admins can create user groups - see Slack's Create a user group for more information.

Dealing with distractions

We can mute notifications from a channel with /slack mute, and then to show what was muted with /slack showmuted. There's a setting so that you can decide what you'll see, the default is that any personal highlights will still be shown to you.

If a channel is distracting you can specify that it should be added to a group called 'distractions'. Then you can tell slack that you don't want distractions.

# toggle mute on a channel
/slack mute
/slack showmuted

# Tell slack that this channel is distracting
/slack distracting

# tell slack not to show distractions
# do it again and it will switch them back on
/slack nodistractions

# hide the current channel if it's marked as distracting
/slack hide

The best option is the dnd command in native Slack. To run this you have to be in your user names buffer:

# change to your userid buffer

# run the dnd command
/slack slash /dnd until 5pm

The actual response from Slack will go to the Slack server buffer.

Disconnect from a server

Unfortunately, you can't disconnect from a server in the same way as with IRC. However, you can unload the script which will disconnect you from all the Slack Workspaces that you are connected to.

# you can't disconnect but you can unload it
/script unload slack.py

Running different Workspaces

As we can't disconnect from a Slack Workspace I run a separate configuration for my personal Slack workspaces and my work Slack workspaces: that way I don't have to be logged into work all the time. This takes advantage of the fact that Weechat can run different configurations using --dir on the command line.

#copy the Weechat configuration to a personal directory
$ cp --recursive .weechat .weechat-personal

# edit it and add the personal Slack workspaces

# run Weechat with that configuration using
weechat --dir ~/.weechat-personal

Slack Configuration

Wee-Slack has an extensive set of options, these can be viewed with:

/set plugins.var.python.slack_extension.*
/set slack

# save option changes at the end
/save

Automatically open a thread when mentioned, or in response to your own message:

/set plugins.var.python.slack.auto_open_threads true

By default it loads all history in the background. If you have a lot of channels this can be slow, and it takes a while to update all the mentions of you (if you have a mentions window). But you should not turn this setting off or you will not be updated on read status of channels: if you're tempted see the project README.

/set plugins.var.python.slack.background_load_all_history true

Changing the amount of history that the plugin downloads may speed up how long it takes to update status - but changing this will mean you won't see mentions if they are higher up in the history:

# the amount of history to download for a channel. Defaults to 200
# this is basically two screens back.
/set plugins.var.python.slack.history_fetch_count "50"

It can show you that someone is typing in a channel (changing the # to a > on the channel name). It can change channel sort order - I find this pointless so I turn it off.

/set plugins.var.python.slack.channel_name_typing_indicator false

Turns off the fact that users are shown that you're typing:

/set plugin.var.python.slack.send_typing_notice false

There's a variety of options to manage the colours of items. See the Weechat manual for how to set-up colours (the available ones are shown with /colors):

# change the '(edited)' suffix from 095 to a brighter red
/set plugins.var.python.slack.color_edited_suffix 196

# change the way it shows the number of people who have reacted to an emoji
# the default is darkgray which didn't show up for me, so I went with a brown
/set plugins.var.python.slack.color_reaction_suffix 058

# you can set this to 'multiple' and it will colour each thread indicator a
# different color. I chose a single colour, slightly brighter than the
# reactions because threads are more important to me.
/set plugins.var.python.slack.color_thread_suffix 013

Set the location for downloads of files:

/set plugins.var.python.slack.files_download_location = "~/Downloads/"

If there's no activity then Slack will show you as away. You can have Weechat explicitly poke the Slack server so you don't lose the connection:

# poke the slack server to make sure you're not marked as away.
/set plugins.var.python.slack.never_away true

Show the nickname of the person reacting:

/set plugins.var.python.slack_extension.show_reaction_nicks true

This is for displaying a short-name in the channel bar, have the channel prefix the slack subdomain:

/set plugins.var.python.slack_extension.server_alias.my-slack-subdomain "mysub"

Slack Emojis

To display Emojis we have to be using a terminal that supports them, and have the emoji fonts: see the first blog post on Weechat for the configuration details. Weechat can also do tab completion on emojis, to enable it:

cd ~/.weechat
wget https://raw.githubusercontent.com/wee-slack/wee-slack/master/weemoji.json
/set weechat.completion.default_template "%(nicks)|%(irc_channels)|%(emoji)"

Then when you type :lau<tab> Weechat will complete this to :laughing: for you.

Slack and Weechat resources

Final Thoughts

With the Wee-slack script and a good Weechat configuration then chatting on Slack is seamless. I haven't had any problems using it for work or for interacting in various personal communities. In the last post of the series we'll complete our Weechat configuration with notifications.


Posted in Tech Monday 30 November 2020
Tagged with tech weechat irc slack