Giter VIP home page Giter VIP logo

irc-slack's Introduction

IRC-to-Slack gateway

irc-slack is an IRC-to-Slack gateway. It is an IRC server that lets you connect to your Slack teams with your IRC client.

(That guy is me)

Slack has ended support for IRC and XMPP gateway on the 15th of May 2018. So what's left to do for people like me, who want to still be able to log in via IRC? Either you use wee-slack (but I don't use WeeChat), or you implement your own stuff.

NOTE: after Slack turned down their IRC gateway I got a lot of contacts from users of irc-slack asking me to fix and improve it. I didn't expect people to actually use it, but thanks to your feedback I'm now actively developing it again :-) Please keep reporting bugs and sending PRs!

How to use it

cd cmd/irc-slack
make # use `make` instead of `go build` to include build information when running with `-v`
./irc-slack # by default on port 6666

Then configure your IRC client to connect to localhost:6666 and use one of the methods in the Tokens section to set the connection password.

You can also run it with Docker.

Feature matrix

public channel private channel multiparty IM IM
from me works works doesn't work (#168) works
to me works works works works
thread from me doesn't work (#168) doesn't work (#168) untested doesn't work (#166)
thread to me works works untested works but sends in the IM chat (#167)

Encryption

irc-slack by default does not use encryption when communicating with your IRC client (but the communication between irc-slack and the Slack servers is encrypted). If you want to use TLS, you can use the -key and -cert command line parameters, and point them to a TLS certificate that you own. This is useful if you plan to connect to to irc-slack over the internet.

For example, you can generate a valid certificate with LetsEncrypt (adjust the relevant fields of course):

sudo certbot certonly \
    -n \
    -d your.domain.example.com \
    --test-cert \
    --standalone \
    -m [email protected] \
    --agree-tos

Then your key and certificate will be generated under /etc/letsencrypt/live/your.domain.example.com with the names privkey.pem and cert.pem respectively.

Authentication

To connect to Slack via irc-slack you need an authentication string. There are three possible methods:

  • User tokens with auth cookies (recommended)
  • Slack app tokens (if you can install apps on your slack team)
  • legacy tokens (soon to be deprecated)

These options are discussed in more detail below. Then just add -key <path/to/privkey.pem> -cert <path/to/cert.pem> to enable TLS on irc-slack, and enable TLS on your IRC client.

User tokens with auth cookie

This approach does not require legacy tokens nor installing any app, but in order to get the token there are a few manual steps to execute.

This type of token starts with xoxc-, and requires an auth cookie to be paired to it in order to work.

There are two possible procedures, an entirely manual one, using the browser console, and a semi-automated one, which requires Chrome or Chromium in headless mode.

manual procedure via browser

This is the same procedure as described in two similar projects, see:

But in short, log via browser on the Slack team, open the browser's network tab in the developer tools, and look for an XHR transaction. Then look for

  • the token (it starts with xoxc-) in the request data
  • the auth cookie, contained in the d key-value in the request cookies (it looks like d=XXXX;)

Then concatenate the token and the auth cookie using a | character, like this:

xoxc-XXXX|d=XXXX;

and use the above as your IRC password.

semi-automated procedure using Chrome/Chromium in headless mode

See autotoken. Just build it with go build and run with ./autotoken -h to see the usage help.

If you prefer to run autotoken via Docker, you can test your luck with:

docker build -t insomniacslk/irc-slack/tools-autotoken -f Dockerfile.autotoken .
docker run --rm -it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix insomniacslk/irc-slack/tools-autotoken autotoken -h

Slack App tokens

As an alternative, you can install the irc-slack app on your workspace, and use the token that it returns after you authorize it.

In order to run the application, you need to do the following steps:

  • create a Slack app using their v1 OauthV2 API (note: not their v2 version) at https://api.slack.com/apps
  • configure the redirect URL to your endpoint (in this case https://my-server/irc-slack/auth/)
  • run the web app under slackapp passing your app client ID and client secret, you can find them in the Basic Information tab at the link at the previous step

The token starts with xoxp-, and you can use it as your IRC password when connecting to irc-slack.

This is a Slack app with full user permissions, that is used to generate a Slack user token. Note that you need to install this app on every workspace you want to use it for, and the workspace owners may reject it.

This app exchanges your temporary authentication code with a permanent token.

Legacy tokens

This is the easiest method, but it's deprecated and Slack will soon disable it. Slack has announced that they will stop issuing legacy tokens starting the 4th of May 2020, so this section will stay here for historical reasons.

Get you Slack legacy token at https://api.slack.com/custom-integrations/legacy-tokens , and set it as your IRC password when connecting to irc-slack.

Run it with Docker

Thanks to halkeye you can run irc-slack via Docker. The Dockerfile is published on https://hub.docker.com/r/insomniacslk/irc-slack and will by default listen on 0.0.0.0:6666. You can pull and run it with:

docker run --rm -p 6666:6666 insomniacslk/irc-slack

If you want to build it locally, just run:

docker build -f Dockerfile . -t insomniacslk/irc-slack

Connecting with irssi

/network add yourteam.slack.com
/server add -auto -network yourteam.slack.com localhost 6666 xoxp-<your-slack-token>
/connect yourteam.slack.com

Remember to add -tls to the /connect command if you're running irc-slack with TLS. Also remember to replace localhost with the name of the host you're connecting to, if different.

Connecting with WeeChat

/server add yourteam.slack.com localhost/6666
/set irc.server.yourteam.slack.com.password xoxp-<your-slack-token>
/connect yourteam.slack.com

To enable TLS, also run the following before the /connect command:

/set irc.server.yourteam.slack.com.ssl on
/set irc.server.yourteam.slack.com.ssl_verify on

Also remember to replace localhost with the name of the host you're connecting to, if different.

Gateway usage

There are a few options that you can pass to the server, e.g. to change the listener port, or the server name:

$ ./irc-slack -h
Usage of ./irc-slack:
  -c, --cert string         TLS certificate for HTTPS server. Requires -key
  -C, --chunk int           Maximum size of a line to send to the client. Only works for certain reply types (default 512)
  -D, --debug               Enable debug logging of the Slack API
  -d, --download string     If set will download attachments to this location
  -l, --fileprefix string   If set will overwrite urls to attachments with this prefix and local file name inside the path set with -d
  -H, --host string         IP address to listen on (default "127.0.0.1")
  -k, --key string          TLS key for HTTPS server. Requires -cert
  -L, --loglevel string     Log level. One of [none debug info warning error fatal] (default "info")
  -P, --pagination int      Pagination value for API calls. If 0 or unspecified, use the recommended default (currently 200). Larger values can help on large Slack teams
  -p, --port int            Local port to listen on (default 6666)
  -s, --server string       IRC server name (i.e. the host name to send to clients)
pflag: help requested
exit status 2

Deploying with Puppet

You can use the irc-slack module for Puppet by John Bond.

TODO

A lot of things. Want to help? Grep "TODO", "FIXME" and "XXX" in the code and send me a PR :)

This currently "works for me", but I published it in the hope that someone would use it so we can find and fix bugs.

BUGS

Plenty of them. I wrote this project while on a plane (like many other projects of mine) so this is hack-level quality - no proper design, no RFC compliance, no testing. I just fired up an IRC client until I could reasonably chat on a few Slack teams. Please report all the bugs you find on the Github issue tracker, or privately to me.

Authors

Thanks

Special thanks to

  • Stefan Stasik for helping me find, fix and troubleshoot a zillion of bugs :)
  • Mauro Codella for patiently reading and replying for two hours in a private conversation that I used to test the fix at pull/23 :D

irc-slack's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

irc-slack's Issues

IRC Nicknames aren't showing up properly

The nickname, or username of the person chatting on each slack channel is not working properly.

In most cases, it is just sending a "U#######" string for each person, altho it does occasionally send a person's username:

10:34 < U9X9H2KPG> post/notice/message
15:14 < U5WQ1RXLL> That's me in the middle
15:15 < moxuz> the octopus?

I assume this is a Slack internal ID being sent out.

This is the number one bug/issue for me, makes chatting in the Slack channels almost useless, if I cant hilite people back in response in IRSSI.

Thanks!!

-- Stefan S

Supporting threads

Are there already any ideas of how threads could be supported in irc-slack? Eg: creating a new virtual irc channel per thread or something similar?

Sending messages to self on slack creates PMs with message as username

Found an odd bug:

When sending messages to yourself on the Slack web client, it results in the words you sent created as users. To be more specific -- if you send the words Hello World to yourself on slack, a "user" Hello World sends an empty message.

image

Here's what I pulled from my logs.

localhost 400 :Exactly two users expected in direct message, got 1 (conversation ID: <removed>)
:<slack username>!<slack user id>@localhost PRIVMSG :Hello World

Messages posted to threads show up in 1-on-1 channels

Thanks for this project, makes slack much nicer to use than with their web UI :)

It seems that if someone responds to a thread while there is also a 1-on-1 chat open for that same user (for example from /QUERY), then the message they posted to the thread will appear in the 1-on-1 chat rather than under the thread. Note that the thread "channel" still opens, but the messages aren't posted to it.

Can provide debug logs or testing as needed.

Add feature matrix on README

We should remove the sentence that says "The code quality is currently at the works-for-me level, but it's improving steadily." because that's not true anymore (irc-slack is pretty solid now), and replace it with a feature matrix so people know what works and what not, and we know what needs to be implemented next

Clean up resources after disconnecting from a team

Currently the IRC Context is not cleaned up upon disconnection, and leaks memory until irc-slack is restarted. This increases memory pressure when disconnecting from large teams (e.g. on the Gophers team, currently ~65k people, it takes ~200MB of RSS)

My own messages are shown twice

Hi. First off thanks for the great app!

I use Quassel IRC and when I send a message a split second later the same message appears again. As if I sent it twice.

Others do not see doubled messages, even I don't see it in native slack client. So it is probably something between Quassel and irc-slack that makes Qassel show my own message 2 times.

Getting Connection Timeout Trying to Setup new Connection

Hey! Thanks for this tool. I'm just getting started, so I may be doing something wrong, but I seem to be running into an issue trying to setup a connection.

I've gone ahead, and grabbed a token/cookie value from my browser, and set them as my IRC Password, however I'm still getting a failure to conenct. Upon turning on debug logging I see:

Jul 10 19:47:30 znc ircslack[22422]: time="2020-07-10T19:47:30Z" level=info msg="Starting Slack client" prefix=main
Jul 10 19:47:30 znc ircslack[22422]: time="2020-07-10T19:47:30Z" level=info msg="Connecting to RTM" prefix=slack-api
Jul 10 19:47:31 znc ircslack[22422]: time="2020-07-10T19:47:31Z" level=info msg="Using URL: 
Jul 10 19:47:31 znc ircslack[22422]: " prefix=slack-api
Jul 10 19:47:31 znc ircslack[22422]: time="2020-07-10T19:47:31Z" level=info msg="Failed to start or connect to RTM: invalid_auth" prefix=slack-api
Jul 10 19:47:31 znc ircslack[22422]: time="2020-07-10T19:47:31Z" level=info msg="invalid auth when connecting with RTM: invalid_auth" prefix=slack-api
Jul 10 19:47:31 znc ircslack[22422]: time="2020-07-10T19:47:31Z" level=info msg="Failed to connect with RTM on try 0: invalid_auth" prefix=slack-api
Jul 10 19:47:40 znc ircslack[22422]: time="2020-07-10T19:47:40Z" level=warning msg="Cannot connect to Slack: Connection to Slack timed out after 10s" prefix=main
Jul 10 19:47:40 znc ircslack[22422]: time="2020-07-10T19:47:40Z" level=warning msg="Error handling connection from 127.0.0.1:25416: read tcp 127.0.0.1:6666->127.0.0.1:25416: use of closed network connection" prefix=main

I'm pretty certain I've copied both the cookie, and token correctly, but am unsure of how to validate the rest of the setup/the token itself. Any help is appreciated,

thanks!

Fix direct messages

Direct messages (IMs in Slack / PRIVMSG to an user in IRC) are not working correctly if writing/reading from different sources (e.g. the web UI, the IRC gateway)

Use slacks 'away' flag when loading slack users

I am having an issue with irc-slack when connecting to public, highly trafficked slacks with lots of users, who are now inactive on the slack. Thousands of mostly inactive users create memory usage in the app which is excessive on the small VPS server I run this app on.

Slack seems to have a concept of an 'away' slack user when they have been away/logged out of the slack for an extended time.

Is there a way to set a flag to have irc-slack connect and use a list of slack users who are not away?

It might make the loading of thousands of slack users a lot less if this flag could be set.

Thank you, Stefan S

Sending single word to channel / privmsg throws error

When I'm trying to send single word/url to user or to channel, message is not relayed and console log throws "Invalid PRIVMSG command args" error:

2019/12/10 09:51:01 127.0.0.1:51172: PRIVMSG user https://github.com/insomniacslk/irc-slack/issues
2019/12/10 09:51:01 Invalid PRIVMSG command args: [user https://github.com/insomniacslk/irc-slack/issues]
2019/12/10 09:51:01 Got new message {@user }

The moment I append whitespace at the end it gets through:
2019/12/10 09:51:09 127.0.0.1:51172: PRIVMSG user :https://github.com/insomniacslk/irc-slack/issues .
2019/12/10 09:51:09 Got new message {@user https://github.com/insomniacslk/irc-slack/issues .}

Improve WHOIS command

Currently WHOIS shows only basic information, e.g.:

00:10 -!- insomniac [UAND64XSM@localhost]
00:10 -!-  ircname  : Andrea
00:10 -!-  server   : localhost []
00:10 -!-  channels : 

Slack supports additional information, e.g. Title, Email, Phone. It'd be nice to show them too.

Speed up channel join upon connection

When connected to a Slack team, joining channels/groups seems to be slower than necessary. This is done in two steps:

  1. get the list of slack channels and groups (via GetChannels and GetGroups on the slack API object)
  2. for each channel, reply to the client with the various chan info.

This can be slow on larger teams - look for what can be sped up.

ZNC having issues with too long of a message

Today I was trying to connect to a slack where a channel that I was forced to belong to had 450+ users in it. The problem is that my ZNC bouncer was disconnecting because a command was being sent to the client that exceeded its limits. Here is an example of the messages that are being sent:

Sending numeric reply: :irc-slack-name-here 353 myUsername = #general :(list of users that is 450+ characters)

According to this bug report that the server shouldn't send over 512 total bytes per message in total (according to the RFC). I believe that ZNC (further on in that bug) allows up to 1024 total bytes per message.

I believe the solution would be to chunk the data (512 byte chunks) sent to the client so that they don't freak out in any manner. The method in question is here.

Sorry for the multiple bugs today.

Sending messages over slack results in a PM from self on IRC

Found another interesting bug --

Appears to be implemented properly for channels, but seems to be broken on PMs.

Reproduction steps:

  1. Send message on the official slack client to another user JohnDoe over PM
  2. receive message on the buffer labeled with your slack username as opposed to the buffer w/ user JohnDoe

Here's what I pulled from tcpdump -- (although I think this is correct? Might be a quassel issue on my end.)
<slack.username>!<slack.id>@10.9.2.201 PRIVMSG JohnDoe :asdfasdfa asdfasdfas asdfasdf asdfasdfa

Fix join/part

currently join/part doesn't work:

21:42 < nickname> @nickname has left the channel

and the user remains in the chan list

Notices for users

This is definitely a feature request more than a bug. But when I issue a @usernameOnIRC it just comes across as just that straight text. Is there a way to do a translation so that the people on slack get the proper notification when messaging them?

It would appear that this translation already happens from slack to IRC, so half of the work is already done.

Use Conversations API

Use the Conversations API rather than the various channels/groups/IMs/multi-person APIs. This will simplify the code a lot, and make the missing types of conversation work

irssi channel window duplicated on slack reconnect

Hi,

thanks for this! This is much better than the bitlbee purple-slack gateway I had been using until. . . today, in a lot of small details, which I like.

I just have an issue when the server disconnects (happens pretty often from experience, remote closed the connection on slack side - I used to see this about once or twice a day), this also disconnects the irc client which reconnects 5 mins later.. and the new force join channels are recreated in different windows.
I'm not sure what's different, on most servers if I do e.g. /reconnect then channels are reused.
I figured many here would be using irssi and it probably doesn't do that for you, would you have a guess at what's different?

Ideally I'd also like to not have the 5 minutes of lost messages, so something like the irc-slack gateway trying to reconnect immediately after connection closed would just solve both issues.

I might try just calling connectToSlack(ctx); from the slack.DisconnectedEvent handler and see how this works out... :P

Thanks!

Private channels not being allowed to join

After setting this up I noticed that when I tried to join a "private" channel on slack that it reported in the server log (and not to the client):

Cannot join channel #secret-channel-here: name_taken

I assume this is because secret/private channels on slack are treated in a completely different way. Is there a workaround for this?

Irssi server add command does not work

Problem

If I use the Irssi command to add the server as described in the Readme, it results in a wrong entry in the Irssi config file.

Commands in Readme:

/network add SlackYourTeamName
/server add -auto SlackYourTeamName localhost 6666 xoxp-<your-slack-token>

Results in Irssi config:

servers = (
  {
    address = "SlackYourTeamName";
    port = "0";
    password = "6666";
    use_tls = "no";
    tls_verify = "no";
    autoconnect = "yes";
  }
);
chatnets = {
  "SlackYourTeamName = { type = "IRC"; };
};

Running /connect SlackYourTeamName afterwards results in:

No servers defined for this network, see /help server for how to add one

Solution

Add -network to the /server add command.

/network add SlackYourTeamName
/server add -auto -network SlackYourTeamName localhost 6666 xoxp-<your-slack-token>

Which results in this:

servers = (
  {
    chatnet = "SlackYourTeamName"
    address = "localhost";
    port = "6666";
    password = "xoxp-<your-slack-token>";
    use_tls = "no";
    tls_verify = "no";
    autoconnect = "yes";
  }
);
chatnets = {
  "SlackYourTeamName = { type = "IRC"; };
};

Add TLS support

Currently there is no TLS support, but it has to be added

unrecornized import when running go get

Hello,

I get the following error when trying to install on Debian:

$ go get ./...
package github.com/nlopes/slack
        imports context: unrecognized import path "context"

I'm running debian 8 with go installed from debian packages:

$ go version
go version go1.3.3 linux/amd64
$ dpkg --list | grep golang
ii  golang                          2:1.3.3-1                          all          Go programming language compiler - metapackage
ii  golang-doc                      2:1.3.3-1                          all          Go programming language compiler - documentation
ii  golang-go                       2:1.3.3-1                          amd64        Go programming language compiler
ii  golang-go-linux-amd64           2:1.3.3-1                          amd64        Go standard library compiled for linux_amd64
ii  golang-go.tools                 0.0~hg20140703-4                   amd64        supplementary Go tools
ii  golang-src                      2:1.3.3-1                          amd64        Go programming language compiler - source files

Fix bug when reacting to multi-line messages

When a user reacts to a multi-line message, the reaction is reported (via notice) on the first line, but not on the subsequent lines, which trigger an invalid IRC command (visible in the status window of most clients).

Repro: react on a multi-line message, and observe the notice only on the first line and the error messages in the status window

Queries not showing up in chat lists.

First of all, thanks for the project!

When I connect to my IRC gateway using Quassel, queries don't show up in my chat list, only rooms. I haven't yet tried with other clients, but will try to do so.

High memory pressure

irc-slack uses too much memory. Without any connection it takes around 1MB RSS, but a large Slack team (thousands of people) that I'm testing on is taking 200 MB RSS.
Furthermore, upon disconnection it does not release the used memory.

Docker does not listen

Problem

$ docker run insomniacslk/irc-slack
time="2020-04-29T16:02:00Z" level=info msg="Setting log level to 'info'" prefix=main
time="2020-04-29T16:02:00Z" level=info msg="Starting server on 127.0.0.1:6666" prefix=main
time="2020-04-29T16:02:00Z" level=info msg="Listening on 127.0.0.1:6666" prefix=main

However, the Docker container process does not listen on port 6666, as stated in the log.

$ sudo ss -tulwn | grep 6666
<no results>

If I use the git repo and build and run it myself it works:

$ ./irc-slack
[2020-04-29T17:55:32+02:00]  INFO main: Setting log level to 'info'
[2020-04-29T17:55:32+02:00]  INFO main: Starting server on 127.0.0.1:6666
[2020-04-29T17:55:32+02:00]  INFO main: Listening on 127.0.0.1:6666
$ sudo ss -tulwn | grep 6666
tcp   LISTEN 0      4096       127.0.0.1:6666       0.0.0.0:*

ACTION displaying incorrectly

This is probably more of a feature request than a bug. But when you issue a /me command from your IRC client it shows up as:

ACTION is bored

And likewise in the IRC client, a /me command in slack just shows as a regular PRIVMSG. No rush or hurry on it it's just something to think about in the future.

Thanks again for making this app.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.