Discord-to-Slack bot hosted on repl.it

Discord-to-Slack bot hosted on repl.it

The story

So we started using Discord alongside Slack recently. The selling point were voice channels and screen streaming. It made voice conversations much smoother and more async friendly and made us overall closer to each other. More context here.

Basically, whenever someone joins a voice channel it means:

  • I’m available to talk, or
  • I don’t mind company.

But since we’re using Slack as the primary means of communication, not everyone in our team is used to having Discord open at all times. We need one thing: an integration that would notify us on Slack, whenever someone joins a voice channel on Discord:

Let’s do it

We’ll need to:

Now the code takes the discordrb gem and uses it to listen to voice channel updates (basically any event related to voice status, like self-mute or screen share). The updates get filtered and posted to the Slack webhook.

First, some basic setup of Discordb that will puts whenever something related to voice happens on Discord:

require "discordrb"

bot = Discordrb::Bot.new(token: "xxxx.xxx.xxxx")

bot.voice_state_update { |event| p event }

at_exit { bot.stop }

Now we only care about a specific set of events — when someone joins, leaves or changes a voice channel. That’s how we can filter them out in the main method:

bot.voice_state_update do |event|
  when event.channel.nil?
    notify_slack "✂️ #{event.user.name} disconnected"
  when event.old_channel.nil?
    notify_slack "👋 #{event.user.name} connected to #{event.channel.name}"
  when event.channel.name != event.old_channel.name
    notify_slack "🔀 #{event.user.name} switched to #{event.channel.name}"

Now we need to actually send these notifications to slack. It’s just a plain post to the configured webhook:

require "httparty"

def notify_slack(message)
    body: JSON.dump({ text: message }),
    headers: { "Content-Type" => "application/json" }

Run it from my local machine… Works!

You can find the full gist here.

Special thanks for Paweł for working on it together as a short coffee-break-hack.

Now, where do I deploy such a tiny lil’ thing?

  • Heroku charges you $7/month for a dyno that never sleeps 🤔
  • Now, for $7 I can have 5 always-on apps on repl.it which is now allegedly the fastest way to spin up a webservice. Fortunately it supports Ruby. Let’s give it a try 🚀

Click, click, click, the app is live 🎉

I have to admit it was fast. Personally I really like it when services and tools improve DX, eliminate friction and are more approachable.

Want to discuss? Leave a reply under this tweet.

Now, a plug 🔌. Join ARKADEMY.DEV and get access to our best courses: Rails Architect Masterclass, Anti-IF course, Blogging for busy programmers, Async Remote, TDD video class, Domain-Driven Rails video course and growing!

You might also like