Discord-to-Slack bot hosted on repl.it

… and check why 5600+ Rails engineers read also this

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 }
bot.run

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|
  case 
  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}"
  end
end

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)
  HTTParty.post(
    "https://hooks.slack.com/services/xxx/xxxx/xxxxx",
    body: JSON.dump({ text: message }),
    headers: { "Content-Type" => "application/json" }
  )
end

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.

You might also like