Giter Site home page Giter Site logo

matrix-org / matrix-appservice-slack Goto Github PK

View Code? Open in Web Editor NEW
271.0 35.0 73.0 6 MB

A Matrix <--> Slack bridge

License: Apache License 2.0

Dockerfile 0.15% Shell 0.32% TypeScript 95.70% HTML 0.16% JavaScript 1.47% Nunjucks 1.55% CSS 0.65%
hacktoberfest matrix bridge slack stable

matrix-appservice-slack's Introduction

matrix-appservice-slack

Docker Automated build #slack:half-shot.uk Documentation Status

A bridge that connects Matrix and Slack. The bridge is considered stable and mature for use in production environments.

Screenshot

Requirements

Hosting this bridge requires you to have a Matrix homeserver. In order to connect a Slack Workspace to your bridge, you will need permission to add bots to it. You will also need Node.JS 16+ or Docker on your system.

NOTE: Slack has introduced a new type of 'Slack App', which is not compatible with this bridge. Instead, you will need to create a "Classic Slack App" for this bridge. Existing installations will not need to modify their setups, as all pre-existing Slack apps became Classic Slack apps. We are looking to make the bridge compatible with both types, but in the meantime please only use Classic Slack Apps.

Setting up

See the getting started docs for instructions on how to set up the bridge.

Helping out

This bridge is a community project and welcomes issues and PRs from anyone who has the time to spare. If you want to work on the bridge, please see CONTRIBUTING.md.

matrix-appservice-slack's People

Contributors

andreasnuesslein avatar andrewferr avatar ara4n avatar auscompgeek avatar benparsons avatar berulacks avatar cadair avatar clokep avatar cotsuka avatar dependabot[bot] avatar erdnaxeli avatar ewingrj avatar half-shot avatar illicitonion avatar ineiti avatar jaller94 avatar justinbot avatar kampka avatar kegsay avatar kingoftheconnors avatar leonerd avatar mkarg avatar mmilata avatar oddvar avatar swedneck avatar tadzik avatar turt2live avatar umitalp avatar vitaly-t avatar vrutkovs avatar

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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

matrix-appservice-slack's Issues

a '#' in the matrix admin room crashes the service.

to reproduce, type # in the matrix admin room.

/home/slackbridge/matrix-appservice-slack/node_modules/olm/olm.js:18
(g=new Uint8Array(g));v(g.buffer);return g};a.load=function(a){F(read(a))};a.thisProgram||(a.thisProgram=1<process.argv.length?process.argv[1].replace(/\\/g,"/"):"unknown-program");a.arguments=process.argv.slice(2);process.on("uncaughtException",function(a){if(!(a instanceof O))throw a;});a.inspect=function(){return"[Emscripten Module object]"}}else if(ka)a.print||(a.print=print),"undefined"!=typeof printErr&&(a.printErr=printErr),a.read="undefined"!=typeof read?read:function(){throw"no read() available (jsc?)";
                                                                                                                                                                                                                                                                                       ^

TypeError: Cannot read property 'then' of undefined         
    at Main.onMatrixEvent (/home/slackbridge/matrix-appservice-slack/lib/Main.js:423:38)                             
    at Object.onEvent (/home/slackbridge/matrix-appservice-slack/lib/Main.js:66:22)                                  
    at Bridge._onConsume (/home/slackbridge/matrix-appservice-slack/node_modules/matrix-appservice-bridge/lib/bridge.js:664:30)
    at /home/slackbridge/matrix-appservice-slack/node_modules/matrix-appservice-bridge/lib/bridge.js:838:14          
    at tryCatcher (/home/slackbridge/matrix-appservice-slack/node_modules/matrix-appservice-bridge/node_modules/bluebird/js/main/util.js:26:23)
    at Promise._settlePromiseFromHandler (/home/slackbridge/matrix-appservice-slack/node_modules/matrix-appservice-bridge/node_modules/bluebird/js/main/promise.js:510:31)
    at Promise._settlePromiseAt (/home/slackbridge/matrix-appservice-slack/node_modules/matrix-appservice-bridge/node_modules/bluebird/js/main/promise.js:584:18)
    at Promise._settlePromises (/home/slackbridge/matrix-appservice-slack/node_modules/matrix-appservice-bridge/node_modules/bluebird/js/main/promise.js:700:14)
    at Async._drainQueue (/home/slackbridge/matrix-appservice-slack/node_modules/matrix-appservice-bridge/node_modules/bluebird/js/main/async.js:123:16)
    at Async._drainQueues (/home/slackbridge/matrix-appservice-slack/node_modules/matrix-appservice-bridge/node_modules/bluebird/js/main/async.js:133:10)
    at Immediate.Async.drainQueues (/home/slackbridge/matrix-appservice-slack/node_modules/matrix-appservice-bridge/node_modules/bluebird/js/main/async.js:15:14)
    at runCallback (timers.js:672:20)                       
    at tryOnImmediate (timers.js:645:5)                     
    at processImmediate [as _immediateCallback] (timers.js:617:5) 

Managing integration not possible in non-public rooms

While I can add the slackbot to a non-public (invite-only) room, if I later try to "Manage Integrations", I am told that no bridge exists (see screenshot).
screenshot
Only after I change the room to public (which I can't really do in most cases), then can I manage the bridge.

Consider "bridging isn't working" messages from bot

If a partially-configured room receives messages from Matrix, maybe the bot should announce "I can't forward this to Slack yet because ...". It should be heavily rate-limited; maybe not more than once per day, so as not to annoy people.

Refactor Slack->Matrix code path

There's lots of repeated calls to substitutions that could be neatened up. Additionally, many of the untagging operations (expanding @user #channel etc) don't happen in the case of lacking a master team key, leading to ugly message formatting a.la. #15.

Some sort of fallback parsing ought to happen for tags lacking a team key.

Create Matrix-side ghost user IDs from slack user IDs, not visible username

Users can change their visible name. If they do, this results in a new Matrix-side ghost joining the room, leaving the old now-dead one sitting there too.

Instead we should map ID->ID, displayname->displayname.

However, changing this now will cause some upset to existing rooms; an entire new set of users will join and the old ghosts will hang around forever, not being removed. Could be handled by a special one-off upgrade and cleanup operation, however.

olm.js error

When built with node:8-onbuild or node:6-onbuild, this appservice throws an error:

slack-appservice_1  | Loading config file /usr/src/app/config.yaml
slack-appservice_1  | /usr/src/app/node_modules/olm/olm.js:18
slack-appservice_1  | (g=new Uint8Array(g));v(g.buffer);return g};a.load=function(a){F(read(a))};a.thisProgram||(a.thisProgram=1<process.argv.length?process.argv[1].replace(/\\/g,"/"):"unknown-program");a.arguments=process.argv.slice(2);process.on("uncaughtException",function(a){if(!(a instanceof O))throw a;});a.inspect=function(){return"[Emscripten Module object]"}}else if(ka)a.print||(a.print=print),"undefined"!=typeof printErr&&(a.printErr=printErr),a.read="undefined"!=typeof read?read:function(){throw"no read() available (jsc?)";
slack-appservice_1  |                                                                                                                                                                                                                                                                                        ^
slack-appservice_1  | 

Pills do not highlight Slack users

It's understandable that simply typing a user's display name isn't converted to a Slack-side highlight, as that would likely result in false positives. However, the recent "Pill" behavior introduced in Riot offers a clear signal that a user was intentionally denoted. It would be nice to support this.

Currently, in order to ping a Slack user, one has to use an @ prefix to their name - and this does not work together with tab completion.

inviting slackbot user to join a room on another homeserver fails if the room has not yet been federated to the slackbot homeserver

I have the slack bridge running on the myserver.io homeserver. If the slack bot is invited to a room R on another homeserver #R:matrix.org, but a myserver.io user is not in #R:matrix.org, an error is thrown and the slackbot fails to join.

0|matrix-s | 2018-01-17 19:26: [-] POST https://matrix.giveth.io/_matrix/client/r0/join/!KqWLcRkqgZMdcVgFOV%3Amatrix.org (AS) HTTP 404 Error: {"errcode":"M_UNKNOWN","error":"No row found"}
0|matrix-s | 2018-01-17 19:26: You have triggered an unhandledRejection, you may have forgotten to catch a Promise rejection:
0|matrix-s | Error: Failed to join room
0|matrix-s |     at /opt/matrix-appservice-slack/node_modules/matrix-appservice-bridge/lib/components/intent.js:464:26
0|matrix-s |     at _rejected (/opt/matrix-appservice-slack/node_modules/q/q.js:864:24)
0|matrix-s |     at /opt/matrix-appservice-slack/node_modules/q/q.js:890:30
0|matrix-s |     at Promise.when (/opt/matrix-appservice-slack/node_modules/q/q.js:1142:31)
0|matrix-s |     at Promise.promise.promiseDispatch (/opt/matrix-appservice-slack/node_modules/q/q.js:808:41)
0|matrix-s |     at /opt/matrix-appservice-slack/node_modules/q/q.js:624:44
0|matrix-s |     at runSingle (/opt/matrix-appservice-slack/node_modules/q/q.js:137:13)
0|matrix-s |     at flush (/opt/matrix-appservice-slack/node_modules/q/q.js:125:13)
0|matrix-s |     at _combinedTickCallback (internal/process/next_tick.js:73:7)
0|matrix-s |     at process._tickDomainCallback (internal/process/next_tick.js:128:9)

Consider how "teams" will work

For a general-purpose bridge (e.g. the one matrix.org themselves run) it is insufficient to create Matrix-side ghosts named simply after the local username within one slack team - if there are many teams there will be many "Bob"s. In general the Matrix-side usernames have to include the Slack team name as well.

However, for most small-scale deployments by individuals, they will probably not want this. So consider adding a "single-team mode" to the bridge, which restricts its operation to within one Slack-side team, meaning shorter Matrix-side usernames for ghosts.

Customisable Slack-side displayname

Analogously to #18 - it ought to be possible to choose how the Matrix user messages are relayed into Slack. Displayname alone may not be sufficient - either duplicates within the Matrix room (for which hopefully we can apply the same disamb. logic as other clients use), and there might even be clashes with native Slack users. Indeed, there will likely be several overlapping humans who use both sides, so surely they alone will clash if nothing else. It might be nice to offer options on how to resolve those.

Allow users to specify OAuth2 tokens

Most of the interesting core bits of bridge functionality actually require the powerful "team token". So far those have been manually specified and stored directly in the core config file checked into internal-config. Clearly this is insufficient for regular users.

There's two parts to this problem:

  • How do users generate that token in the first place?
  • How do users tell us the token?

Slack shows user(s) as "incoming-webhook" when Matrix display name has not been set

If a matrix user hasn't set their display name, and thus it renders in Riot client as something like: "@TheDude:matrix.org" the slack bridge will show username(s) in Slack channel as "incoming-webhook". This can be problematic when several different users are getting renamed to "incoming-webhook". As soon as display name is set, bridge renders name symmetrically between Matrix/Slack.

Pass codeblock markdown

Basic markdown support has been implemented. It would be nice to extend this support to include code blocks, so that arbitrarily long code pastes do not spam the chat on either service.

Handle "edited" messages

Apparently messages in Slack can be edited after posting.

Maybe attempt to handle these similar to the way the Gitter bridge does. Steal its diff-like code.

Work out how we can identify ourselves and not ignore other webooks

The gitter relaybot acts as a real bot user with a real user ID, so it can recognise reflections via gitter of its own messages, and ignore those on the inbound path.

By comparison, there is no slack user corresponding to our own specific webhook integration. All webhook integrations always appear under the special user ID of "USLACKBOT". This means that the logic to identify our own reflections also rejects every other message from any other webhook integration.

It's possible we can use the bot_id field.

Slack message referencing to a slack user is gibberish

hey,

we have a slack bridge running, but when someone on slack references a user, it translates to something like '@U0TLNKQRL' instead of a username.
This has the side effect that person is not notified, nor no ones knows who is referenced.
We need to guess by the context. :)

If those reference id's stay the same, this seems fixable.

Cheers!
Tom

TypeError: Cannot read property 'url' of undefined

When running the cli in a Docker container, an error is thrown:

slack-appservice_1  | TypeError: Cannot read property 'url' of undefined
slack-appservice_1  |     at Function.AppServiceRegistration.fromObject (/usr/src/app/node_modules/matrix-
appservice/lib/app-service-registration.js:231:13)
slack-appservice_1  |     at Cli._startWithConfig (/usr/src/app/node_modules/matrix-appservice-bridge/lib/
components/cli.js:182:32)
slack-appservice_1  |     at Cli.run (/usr/src/app/node_modules/matrix-appservice-bridge/lib/components/cl
i.js:139:10)
slack-appservice_1  |     at Object.<anonymous> (/usr/src/app/app.js:28:5)
slack-appservice_1  |     at Module._compile (module.js:570:32)
slack-appservice_1  |     at Object.Module._extensions..js (module.js:579:10)
slack-appservice_1  |     at Module.load (module.js:487:32)
slack-appservice_1  |     at tryModuleLoad (module.js:446:12)
slack-appservice_1  |     at Function.Module._load (module.js:438:3)
slack-appservice_1  |     at Module.runMain (module.js:604:10)
slack-appservice_1  |     at run (bootstrap_node.js:389:7)
slack-appservice_1  |     at startup (bootstrap_node.js:149:9)
slack-appservice_1  |     at bootstrap_node.js:504:3

The example.sample.yaml does not contain the required field: https://github.com/matrix-org/matrix-appservice-slack/blob/master/config/config.sample.yaml

Unfortunately it is required from https://github.com/matrix-org/matrix-appservice-node/blob/master/lib/app-service-registration.js#L231

What am I missing here?

Fix the need for one integration per bridged channel

Bridging a larger Slack community onto Matrix would seemingly require one integration per channel. Since most communities are on a free plan there's a limit on the number of integrations that can be added and it's not very high (don't know the exact number but I'd guess it's below 10).

This makes bridging a larger number of rooms including user metadata not really possible.

m.image doesn't contain url property

I'm not sure if this or slackbridge is running the #DWebSummit bridge, but the m.image messages coming from the bridge aren't up to spec:

((thumbnail_url . "https://files.slack.com/files-tmb/T14KGBP17-F1G4EB0MA-cf6a09a2d5/jason_griffey_builders_day_6-7-16_360.jpg") (thumbnail_info (w . 360) (h . 240)) (msgtype . "m.image") (info (w . 750) (size . 47866) (mimetype . "image/jpeg") (h . 500)) (body . "Jason Griffey Builders Day 6-7-16.jpg"))                                                                      

Spec says that `url' is required.

"message" with image attachments doesn't bridge correctly

Apparently some messages can arrive from Slack with image attachments on, that aren't just image messages. They appear to be results out of the Slack-side Giphy integration, and look something like:

Looked up message from history as {"type":"message","user":"U123","text":"more text here","bot_id":"B456","attachments":[{"fallback":"giphy: <http://giphy.com/...>","image_url":"http://media.giphy.com/...","image_width":250,"image_height":250,"image_bytes":1234,"is_animated":true,"title":"...","id":1,"title_link":"http://giphy.com/..."}],"ts":"123456789"}

The bridge doesn't currently extract the image, just the text:

running substitutions on: more text here
[-] PUT http://matrix.org/_matrix/client/r0/rooms/!aBcDeF:domain.com/send/m.room.message/m123456789 (@_slack_domain_U123:matrix.org) Body: {"body":"more text here","msgtype":"m.text"}

How to deal with threads

Today I kept seeing messages in Matrix that I wasn't seeing in the actual Slack web client. I pulled out my hair for a while trying to figure out what was going on, thinking perhaps someone had blocked me personally or something, before eventually finding the messages in a thread from days earlier that I wasn't following. I understand if Matrix doesn't support threaded conversations (yet, I hope!), but it would be extremely helpful if there was some kind of indicator that a message was a part of a threaded conversation, even something as simple as a ↳ before the message or something might be good enough.

Work out how regular users are supposed to deal with "channel IDs"

Currently to set up an linked room in the bridge, the configuration needs to know, among other things, the slack channel ID of the relevant slack channel. Unfortunately, as far as I can tell, users can't actually know this from the slack UI. It's not made apparent to them anywhere.

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.