Skip to content
This repository was archived by the owner on Oct 21, 2024. It is now read-only.

Repository files navigation

Charon

GitHub versionCI/CDRelease Pipeline

Bridge between Slack and Wire

Charon is proxy converting Slack Bot API calls to Wire (using Roman) and back and thus allows to use subset of Slack Bots in the Wire.

Please note that this is simple proof of concept work, that was developed in few days just to prove that it is possible to use existing Slack Bot and connect it to the Wire API. The code looks accordingly.

How does Charon work

It exposes Slack-like API which is called by the Slack Bot. Then it transforms the API call to one that can be processed by Roman. The very same thing happens when new message is received from the Roman, the message is transformed (some information are missing in the default calls from the Roman, so the proxy ask for them) to the Slack version of message and sent to the Slack Bot API.

Is it slow?

Not really, it is slower than running native Lithium, but when I was testing raw Slack Bot with Slack API, the response time was between 1.4 and 2.5 seconds. The setup with Charon and Roman had response times around 1.2 and 2.5 seconds, so no leg basically.

Security & Privacy

Please note that the requests from the bots and the bots communication through Charon & Roman is not end-to-end encrypted. Whole idea of using Charon & Roman is to provide most simple way how to send data to the Wire environment and therefore all encryption is leveraged to the Roman. In other words, requests sent to the Charon are not encrypted, Charon sends them to Roman, then Roman encrypts them (Roman uses Lithium) and send them to Wire backend.

However, Charon does not store content of conversations in the database (but when debug log level is enabled, part of the messages can be printed to logs). The only data, that are stored, are access keys to Roman and to Slack bot. All database related operation can be found in Repository.

If the e2e encryption is necessary, one can either deploy Roman and Charon to one's infrastructure or to use directly Lithium.

Slack bot onboarding

To add new Slack bot instance to Charon one must register the bot in the Roman and in the Charon. Both services have Swagger API for registration process or one can use CLI from the repository with example.

Charon have support for Slack webhook API as well as event API, therefore the bot can either just post messages via webhook API or have complete access to communication with event API.

Webhook API

One must register the bot in Roman and then on /registration/hook endpoint in the Charon. Due to Wire security limitations, webhook links are generated when the bot is added to the conversation. Therefore in order to get the webhook link, one must add the bot to the conversation, where should be the bot posting the messages. After adding the bot to the conversation, you will receive generated link for that specific conversation.

Minimal working example is:

curl -X POST http://charon.wire.com/slack/webhook/<api-key-per-bot>/<generated-conversation-id> \
--header "content-type: application/json"\ 
--data '{"text": "hello world"}'

For registering new bot, one can use CLI.

Example

Example bot with complete CLI and description can be found here. It is based on the official tutorial, where we changed just the backend URL (from Slack to Charon). In that repo, there's also CLI, which allows to run the bot targeting Slacks API or Wire with single command.

make run-wire

To target Wire or to target Slack:

make run-slack

Known issues

This is just a PoC project, to show that it is indeed possible to partially map Slack API and to use Slack bots in the Wire infrastructure. However, there are some limitations and therefore mapping between API can't be 1:1.

Known limitations so far:

  • Wire does not have concept of Slack's channel
    • channels are in Slack public and all bots can read from them even though they are not part of that channel, Wire does not have concept of public channels as public channels couldn't be encrypted
    • Charon therefore maps channel to group, where group is Slack's concept of private conversations
  • Wire does not support commands
    • Slack has special type of the message which is called command that is basically /do something
    • This can be implemented in Charon in the future by simply parsing incoming message from the Roman and if it starts with /, Charon would transform that into the command message.
  • Bot can not initiate conversation
    • In the Slack, bot can create conversation with anyone, Wire does not allow conversations initiated by bot for security reasons.
  • Various events
    • Wire does not support messages pins yet
    • Wire has only hearth reaction, so no other emojis can be used for reactions.
    • In general, vast majority of events from Slack are not, or even couldn't be, mapped to Wire events as Wire tries to limit the API and events because of security. However, that shouldn't be problem in the future, because bot should react only to events that we want it to react, therefore we are able to simulate almost anything.

There are, for sure, more limitation then those listed here, but we haven't found out yet.

Running Charon

Charon needs following configuration - ROMAN_URL, REDIS_URL, REDIS_PORT, REDIS_USERNAME, REDIS_PASSWORD and CHARON_URL. To run Charon locally, please create file config.py which contains following runtime variables:

ROMAN_URL='http://proxy.services.zinfra.io'REDIS_URL='localhost'REDIS_PORT='6379'REDIS_USERNAME=''REDIS_PASSWORD=''CHARON_URL='http://localhost:8080'

and spin the Redis instance - there's one in the docker-compose. To run Charon inside docker-compose, just execute docker-compose up.

Configuration

  • CHARON_URL - is URL under which is Charon visible from public internet, it is used to generate unique URLs for the webhook only bots

Docker Images

Charon has public docker image.

lukaswire/charon

Tag latest is current master branch - each commit is build and tagged as latest. Releases have then images with corresponding tag.

Development

Master branch is used as bleeding edge which is deployed as latest to staging environment. Stable releases are tagged and deployed to production. Significant or notable changes that would break current behavior are developed in separate branches and merged to master through the PR. Squashing is not necessary.

Charon uses pipenv for dependencies management. Currently build on top of:

  • Flask - development server and facade
  • gunicorn - production server
  • flask-restx - requests processing, swagger
  • requests - sending HTTP requests to Roman/Bot
  • emoji - emoji processing (from Slack to Wire)
  • redis - storage for information about bots and services
  • dacite - simple Dataclass parsing from JSON

Releases

See releases page for more info.

alt text

About

Proxy mapping requests from Slack bots to Roman and back

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - wireapp/charon: Proxy mapping requests from Slack bots to Roman and back · GitHub
Skip to content
This repository was archived by the owner on Oct 21, 2024. It is now read-only.

Repository files navigation

Charon

GitHub versionCI/CDRelease Pipeline

Bridge between Slack and Wire

Charon is proxy converting Slack Bot API calls to Wire (using Roman) and back and thus allows to use subset of Slack Bots in the Wire.

Please note that this is simple proof of concept work, that was developed in few days just to prove that it is possible to use existing Slack Bot and connect it to the Wire API. The code looks accordingly.

How does Charon work

It exposes Slack-like API which is called by the Slack Bot. Then it transforms the API call to one that can be processed by Roman. The very same thing happens when new message is received from the Roman, the message is transformed (some information are missing in the default calls from the Roman, so the proxy ask for them) to the Slack version of message and sent to the Slack Bot API.

Is it slow?

Not really, it is slower than running native Lithium, but when I was testing raw Slack Bot with Slack API, the response time was between 1.4 and 2.5 seconds. The setup with Charon and Roman had response times around 1.2 and 2.5 seconds, so no leg basically.

Security & Privacy

Please note that the requests from the bots and the bots communication through Charon & Roman is not end-to-end encrypted. Whole idea of using Charon & Roman is to provide most simple way how to send data to the Wire environment and therefore all encryption is leveraged to the Roman. In other words, requests sent to the Charon are not encrypted, Charon sends them to Roman, then Roman encrypts them (Roman uses Lithium) and send them to Wire backend.

However, Charon does not store content of conversations in the database (but when debug log level is enabled, part of the messages can be printed to logs). The only data, that are stored, are access keys to Roman and to Slack bot. All database related operation can be found in Repository.

If the e2e encryption is necessary, one can either deploy Roman and Charon to one's infrastructure or to use directly Lithium.

Slack bot onboarding

To add new Slack bot instance to Charon one must register the bot in the Roman and in the Charon. Both services have Swagger API for registration process or one can use CLI from the repository with example.

Charon have support for Slack webhook API as well as event API, therefore the bot can either just post messages via webhook API or have complete access to communication with event API.

Webhook API

One must register the bot in Roman and then on /registration/hook endpoint in the Charon. Due to Wire security limitations, webhook links are generated when the bot is added to the conversation. Therefore in order to get the webhook link, one must add the bot to the conversation, where should be the bot posting the messages. After adding the bot to the conversation, you will receive generated link for that specific conversation.

Minimal working example is:

curl -X POST http://charon.wire.com/slack/webhook/<api-key-per-bot>/<generated-conversation-id> \
--header "content-type: application/json"\ 
--data '{"text": "hello world"}'

For registering new bot, one can use CLI.

Example

Example bot with complete CLI and description can be found here. It is based on the official tutorial, where we changed just the backend URL (from Slack to Charon). In that repo, there's also CLI, which allows to run the bot targeting Slacks API or Wire with single command.

make run-wire

To target Wire or to target Slack:

make run-slack

Known issues

This is just a PoC project, to show that it is indeed possible to partially map Slack API and to use Slack bots in the Wire infrastructure. However, there are some limitations and therefore mapping between API can't be 1:1.

Known limitations so far:

  • Wire does not have concept of Slack's channel
    • channels are in Slack public and all bots can read from them even though they are not part of that channel, Wire does not have concept of public channels as public channels couldn't be encrypted
    • Charon therefore maps channel to group, where group is Slack's concept of private conversations
  • Wire does not support commands
    • Slack has special type of the message which is called command that is basically /do something
    • This can be implemented in Charon in the future by simply parsing incoming message from the Roman and if it starts with /, Charon would transform that into the command message.
  • Bot can not initiate conversation
    • In the Slack, bot can create conversation with anyone, Wire does not allow conversations initiated by bot for security reasons.
  • Various events
    • Wire does not support messages pins yet
    • Wire has only hearth reaction, so no other emojis can be used for reactions.
    • In general, vast majority of events from Slack are not, or even couldn't be, mapped to Wire events as Wire tries to limit the API and events because of security. However, that shouldn't be problem in the future, because bot should react only to events that we want it to react, therefore we are able to simulate almost anything.

There are, for sure, more limitation then those listed here, but we haven't found out yet.

Running Charon

Charon needs following configuration - ROMAN_URL, REDIS_URL, REDIS_PORT, REDIS_USERNAME, REDIS_PASSWORD and CHARON_URL. To run Charon locally, please create file config.py which contains following runtime variables:

ROMAN_URL='http://proxy.services.zinfra.io'REDIS_URL='localhost'REDIS_PORT='6379'REDIS_USERNAME=''REDIS_PASSWORD=''CHARON_URL='http://localhost:8080'

and spin the Redis instance - there's one in the docker-compose. To run Charon inside docker-compose, just execute docker-compose up.

Configuration

  • CHARON_URL - is URL under which is Charon visible from public internet, it is used to generate unique URLs for the webhook only bots

Docker Images

Charon has public docker image.

lukaswire/charon

Tag latest is current master branch - each commit is build and tagged as latest. Releases have then images with corresponding tag.

Development

Master branch is used as bleeding edge which is deployed as latest to staging environment. Stable releases are tagged and deployed to production. Significant or notable changes that would break current behavior are developed in separate branches and merged to master through the PR. Squashing is not necessary.

Charon uses pipenv for dependencies management. Currently build on top of:

  • Flask - development server and facade
  • gunicorn - production server
  • flask-restx - requests processing, swagger
  • requests - sending HTTP requests to Roman/Bot
  • emoji - emoji processing (from Slack to Wire)
  • redis - storage for information about bots and services
  • dacite - simple Dataclass parsing from JSON

Releases

See releases page for more info.

alt text

About

Proxy mapping requests from Slack bots to Roman and back

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - wireapp/charon: Proxy mapping requests from Slack bots to Roman and back · GitHub
Skip to content
This repository was archived by the owner on Oct 21, 2024. It is now read-only.

Repository files navigation

Charon

GitHub versionCI/CDRelease Pipeline

Bridge between Slack and Wire

Charon is proxy converting Slack Bot API calls to Wire (using Roman) and back and thus allows to use subset of Slack Bots in the Wire.

Please note that this is simple proof of concept work, that was developed in few days just to prove that it is possible to use existing Slack Bot and connect it to the Wire API. The code looks accordingly.

How does Charon work

It exposes Slack-like API which is called by the Slack Bot. Then it transforms the API call to one that can be processed by Roman. The very same thing happens when new message is received from the Roman, the message is transformed (some information are missing in the default calls from the Roman, so the proxy ask for them) to the Slack version of message and sent to the Slack Bot API.

Is it slow?

Not really, it is slower than running native Lithium, but when I was testing raw Slack Bot with Slack API, the response time was between 1.4 and 2.5 seconds. The setup with Charon and Roman had response times around 1.2 and 2.5 seconds, so no leg basically.

Security & Privacy

Please note that the requests from the bots and the bots communication through Charon & Roman is not end-to-end encrypted. Whole idea of using Charon & Roman is to provide most simple way how to send data to the Wire environment and therefore all encryption is leveraged to the Roman. In other words, requests sent to the Charon are not encrypted, Charon sends them to Roman, then Roman encrypts them (Roman uses Lithium) and send them to Wire backend.

However, Charon does not store content of conversations in the database (but when debug log level is enabled, part of the messages can be printed to logs). The only data, that are stored, are access keys to Roman and to Slack bot. All database related operation can be found in Repository.

If the e2e encryption is necessary, one can either deploy Roman and Charon to one's infrastructure or to use directly Lithium.

Slack bot onboarding

To add new Slack bot instance to Charon one must register the bot in the Roman and in the Charon. Both services have Swagger API for registration process or one can use CLI from the repository with example.

Charon have support for Slack webhook API as well as event API, therefore the bot can either just post messages via webhook API or have complete access to communication with event API.

Webhook API

One must register the bot in Roman and then on /registration/hook endpoint in the Charon. Due to Wire security limitations, webhook links are generated when the bot is added to the conversation. Therefore in order to get the webhook link, one must add the bot to the conversation, where should be the bot posting the messages. After adding the bot to the conversation, you will receive generated link for that specific conversation.

Minimal working example is:

curl -X POST http://charon.wire.com/slack/webhook/<api-key-per-bot>/<generated-conversation-id> \
--header "content-type: application/json"\ 
--data '{"text": "hello world"}'

For registering new bot, one can use CLI.

Example

Example bot with complete CLI and description can be found here. It is based on the official tutorial, where we changed just the backend URL (from Slack to Charon). In that repo, there's also CLI, which allows to run the bot targeting Slacks API or Wire with single command.

make run-wire

To target Wire or to target Slack:

make run-slack

Known issues

This is just a PoC project, to show that it is indeed possible to partially map Slack API and to use Slack bots in the Wire infrastructure. However, there are some limitations and therefore mapping between API can't be 1:1.

Known limitations so far:

  • Wire does not have concept of Slack's channel
    • channels are in Slack public and all bots can read from them even though they are not part of that channel, Wire does not have concept of public channels as public channels couldn't be encrypted
    • Charon therefore maps channel to group, where group is Slack's concept of private conversations
  • Wire does not support commands
    • Slack has special type of the message which is called command that is basically /do something
    • This can be implemented in Charon in the future by simply parsing incoming message from the Roman and if it starts with /, Charon would transform that into the command message.
  • Bot can not initiate conversation
    • In the Slack, bot can create conversation with anyone, Wire does not allow conversations initiated by bot for security reasons.
  • Various events
    • Wire does not support messages pins yet
    • Wire has only hearth reaction, so no other emojis can be used for reactions.
    • In general, vast majority of events from Slack are not, or even couldn't be, mapped to Wire events as Wire tries to limit the API and events because of security. However, that shouldn't be problem in the future, because bot should react only to events that we want it to react, therefore we are able to simulate almost anything.

There are, for sure, more limitation then those listed here, but we haven't found out yet.

Running Charon

Charon needs following configuration - ROMAN_URL, REDIS_URL, REDIS_PORT, REDIS_USERNAME, REDIS_PASSWORD and CHARON_URL. To run Charon locally, please create file config.py which contains following runtime variables:

ROMAN_URL='http://proxy.services.zinfra.io'REDIS_URL='localhost'REDIS_PORT='6379'REDIS_USERNAME=''REDIS_PASSWORD=''CHARON_URL='http://localhost:8080'

and spin the Redis instance - there's one in the docker-compose. To run Charon inside docker-compose, just execute docker-compose up.

Configuration

  • CHARON_URL - is URL under which is Charon visible from public internet, it is used to generate unique URLs for the webhook only bots

Docker Images

Charon has public docker image.

lukaswire/charon

Tag latest is current master branch - each commit is build and tagged as latest. Releases have then images with corresponding tag.

Development

Master branch is used as bleeding edge which is deployed as latest to staging environment. Stable releases are tagged and deployed to production. Significant or notable changes that would break current behavior are developed in separate branches and merged to master through the PR. Squashing is not necessary.

Charon uses pipenv for dependencies management. Currently build on top of:

  • Flask - development server and facade
  • gunicorn - production server
  • flask-restx - requests processing, swagger
  • requests - sending HTTP requests to Roman/Bot
  • emoji - emoji processing (from Slack to Wire)
  • redis - storage for information about bots and services
  • dacite - simple Dataclass parsing from JSON

Releases

See releases page for more info.

alt text

About

Proxy mapping requests from Slack bots to Roman and back

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - wireapp/charon: Proxy mapping requests from Slack bots to Roman and back · GitHub
Skip to content
This repository was archived by the owner on Oct 21, 2024. It is now read-only.

Repository files navigation

Charon

GitHub versionCI/CDRelease Pipeline

Bridge between Slack and Wire

Charon is proxy converting Slack Bot API calls to Wire (using Roman) and back and thus allows to use subset of Slack Bots in the Wire.

Please note that this is simple proof of concept work, that was developed in few days just to prove that it is possible to use existing Slack Bot and connect it to the Wire API. The code looks accordingly.

How does Charon work

It exposes Slack-like API which is called by the Slack Bot. Then it transforms the API call to one that can be processed by Roman. The very same thing happens when new message is received from the Roman, the message is transformed (some information are missing in the default calls from the Roman, so the proxy ask for them) to the Slack version of message and sent to the Slack Bot API.

Is it slow?

Not really, it is slower than running native Lithium, but when I was testing raw Slack Bot with Slack API, the response time was between 1.4 and 2.5 seconds. The setup with Charon and Roman had response times around 1.2 and 2.5 seconds, so no leg basically.

Security & Privacy

Please note that the requests from the bots and the bots communication through Charon & Roman is not end-to-end encrypted. Whole idea of using Charon & Roman is to provide most simple way how to send data to the Wire environment and therefore all encryption is leveraged to the Roman. In other words, requests sent to the Charon are not encrypted, Charon sends them to Roman, then Roman encrypts them (Roman uses Lithium) and send them to Wire backend.

However, Charon does not store content of conversations in the database (but when debug log level is enabled, part of the messages can be printed to logs). The only data, that are stored, are access keys to Roman and to Slack bot. All database related operation can be found in Repository.

If the e2e encryption is necessary, one can either deploy Roman and Charon to one's infrastructure or to use directly Lithium.

Slack bot onboarding

To add new Slack bot instance to Charon one must register the bot in the Roman and in the Charon. Both services have Swagger API for registration process or one can use CLI from the repository with example.

Charon have support for Slack webhook API as well as event API, therefore the bot can either just post messages via webhook API or have complete access to communication with event API.

Webhook API

One must register the bot in Roman and then on /registration/hook endpoint in the Charon. Due to Wire security limitations, webhook links are generated when the bot is added to the conversation. Therefore in order to get the webhook link, one must add the bot to the conversation, where should be the bot posting the messages. After adding the bot to the conversation, you will receive generated link for that specific conversation.

Minimal working example is:

curl -X POST http://charon.wire.com/slack/webhook/<api-key-per-bot>/<generated-conversation-id> \
--header "content-type: application/json"\ 
--data '{"text": "hello world"}'

For registering new bot, one can use CLI.

Example

Example bot with complete CLI and description can be found here. It is based on the official tutorial, where we changed just the backend URL (from Slack to Charon). In that repo, there's also CLI, which allows to run the bot targeting Slacks API or Wire with single command.

make run-wire

To target Wire or to target Slack:

make run-slack

Known issues

This is just a PoC project, to show that it is indeed possible to partially map Slack API and to use Slack bots in the Wire infrastructure. However, there are some limitations and therefore mapping between API can't be 1:1.

Known limitations so far:

  • Wire does not have concept of Slack's channel
    • channels are in Slack public and all bots can read from them even though they are not part of that channel, Wire does not have concept of public channels as public channels couldn't be encrypted
    • Charon therefore maps channel to group, where group is Slack's concept of private conversations
  • Wire does not support commands
    • Slack has special type of the message which is called command that is basically /do something
    • This can be implemented in Charon in the future by simply parsing incoming message from the Roman and if it starts with /, Charon would transform that into the command message.
  • Bot can not initiate conversation
    • In the Slack, bot can create conversation with anyone, Wire does not allow conversations initiated by bot for security reasons.
  • Various events
    • Wire does not support messages pins yet
    • Wire has only hearth reaction, so no other emojis can be used for reactions.
    • In general, vast majority of events from Slack are not, or even couldn't be, mapped to Wire events as Wire tries to limit the API and events because of security. However, that shouldn't be problem in the future, because bot should react only to events that we want it to react, therefore we are able to simulate almost anything.

There are, for sure, more limitation then those listed here, but we haven't found out yet.

Running Charon

Charon needs following configuration - ROMAN_URL, REDIS_URL, REDIS_PORT, REDIS_USERNAME, REDIS_PASSWORD and CHARON_URL. To run Charon locally, please create file config.py which contains following runtime variables:

ROMAN_URL='http://proxy.services.zinfra.io'REDIS_URL='localhost'REDIS_PORT='6379'REDIS_USERNAME=''REDIS_PASSWORD=''CHARON_URL='http://localhost:8080'

and spin the Redis instance - there's one in the docker-compose. To run Charon inside docker-compose, just execute docker-compose up.

Configuration

  • CHARON_URL - is URL under which is Charon visible from public internet, it is used to generate unique URLs for the webhook only bots

Docker Images

Charon has public docker image.

lukaswire/charon

Tag latest is current master branch - each commit is build and tagged as latest. Releases have then images with corresponding tag.

Development

Master branch is used as bleeding edge which is deployed as latest to staging environment. Stable releases are tagged and deployed to production. Significant or notable changes that would break current behavior are developed in separate branches and merged to master through the PR. Squashing is not necessary.

Charon uses pipenv for dependencies management. Currently build on top of:

  • Flask - development server and facade
  • gunicorn - production server
  • flask-restx - requests processing, swagger
  • requests - sending HTTP requests to Roman/Bot
  • emoji - emoji processing (from Slack to Wire)
  • redis - storage for information about bots and services
  • dacite - simple Dataclass parsing from JSON

Releases

See releases page for more info.

alt text

About

Proxy mapping requests from Slack bots to Roman and back

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - wireapp/charon: Proxy mapping requests from Slack bots to Roman and back · GitHub
Skip to content
This repository was archived by the owner on Oct 21, 2024. It is now read-only.

Repository files navigation

Charon

GitHub versionCI/CDRelease Pipeline

Bridge between Slack and Wire

Charon is proxy converting Slack Bot API calls to Wire (using Roman) and back and thus allows to use subset of Slack Bots in the Wire.

Please note that this is simple proof of concept work, that was developed in few days just to prove that it is possible to use existing Slack Bot and connect it to the Wire API. The code looks accordingly.

How does Charon work

It exposes Slack-like API which is called by the Slack Bot. Then it transforms the API call to one that can be processed by Roman. The very same thing happens when new message is received from the Roman, the message is transformed (some information are missing in the default calls from the Roman, so the proxy ask for them) to the Slack version of message and sent to the Slack Bot API.

Is it slow?

Not really, it is slower than running native Lithium, but when I was testing raw Slack Bot with Slack API, the response time was between 1.4 and 2.5 seconds. The setup with Charon and Roman had response times around 1.2 and 2.5 seconds, so no leg basically.

Security & Privacy

Please note that the requests from the bots and the bots communication through Charon & Roman is not end-to-end encrypted. Whole idea of using Charon & Roman is to provide most simple way how to send data to the Wire environment and therefore all encryption is leveraged to the Roman. In other words, requests sent to the Charon are not encrypted, Charon sends them to Roman, then Roman encrypts them (Roman uses Lithium) and send them to Wire backend.

However, Charon does not store content of conversations in the database (but when debug log level is enabled, part of the messages can be printed to logs). The only data, that are stored, are access keys to Roman and to Slack bot. All database related operation can be found in Repository.

If the e2e encryption is necessary, one can either deploy Roman and Charon to one's infrastructure or to use directly Lithium.

Slack bot onboarding

To add new Slack bot instance to Charon one must register the bot in the Roman and in the Charon. Both services have Swagger API for registration process or one can use CLI from the repository with example.

Charon have support for Slack webhook API as well as event API, therefore the bot can either just post messages via webhook API or have complete access to communication with event API.

Webhook API

One must register the bot in Roman and then on /registration/hook endpoint in the Charon. Due to Wire security limitations, webhook links are generated when the bot is added to the conversation. Therefore in order to get the webhook link, one must add the bot to the conversation, where should be the bot posting the messages. After adding the bot to the conversation, you will receive generated link for that specific conversation.

Minimal working example is:

curl -X POST http://charon.wire.com/slack/webhook/<api-key-per-bot>/<generated-conversation-id> \
--header "content-type: application/json"\ 
--data '{"text": "hello world"}'

For registering new bot, one can use CLI.

Example

Example bot with complete CLI and description can be found here. It is based on the official tutorial, where we changed just the backend URL (from Slack to Charon). In that repo, there's also CLI, which allows to run the bot targeting Slacks API or Wire with single command.

make run-wire

To target Wire or to target Slack:

make run-slack

Known issues

This is just a PoC project, to show that it is indeed possible to partially map Slack API and to use Slack bots in the Wire infrastructure. However, there are some limitations and therefore mapping between API can't be 1:1.

Known limitations so far:

  • Wire does not have concept of Slack's channel
    • channels are in Slack public and all bots can read from them even though they are not part of that channel, Wire does not have concept of public channels as public channels couldn't be encrypted
    • Charon therefore maps channel to group, where group is Slack's concept of private conversations
  • Wire does not support commands
    • Slack has special type of the message which is called command that is basically /do something
    • This can be implemented in Charon in the future by simply parsing incoming message from the Roman and if it starts with /, Charon would transform that into the command message.
  • Bot can not initiate conversation
    • In the Slack, bot can create conversation with anyone, Wire does not allow conversations initiated by bot for security reasons.
  • Various events
    • Wire does not support messages pins yet
    • Wire has only hearth reaction, so no other emojis can be used for reactions.
    • In general, vast majority of events from Slack are not, or even couldn't be, mapped to Wire events as Wire tries to limit the API and events because of security. However, that shouldn't be problem in the future, because bot should react only to events that we want it to react, therefore we are able to simulate almost anything.

There are, for sure, more limitation then those listed here, but we haven't found out yet.

Running Charon

Charon needs following configuration - ROMAN_URL, REDIS_URL, REDIS_PORT, REDIS_USERNAME, REDIS_PASSWORD and CHARON_URL. To run Charon locally, please create file config.py which contains following runtime variables:

ROMAN_URL='http://proxy.services.zinfra.io'REDIS_URL='localhost'REDIS_PORT='6379'REDIS_USERNAME=''REDIS_PASSWORD=''CHARON_URL='http://localhost:8080'

and spin the Redis instance - there's one in the docker-compose. To run Charon inside docker-compose, just execute docker-compose up.

Configuration

  • CHARON_URL - is URL under which is Charon visible from public internet, it is used to generate unique URLs for the webhook only bots

Docker Images

Charon has public docker image.

lukaswire/charon

Tag latest is current master branch - each commit is build and tagged as latest. Releases have then images with corresponding tag.

Development

Master branch is used as bleeding edge which is deployed as latest to staging environment. Stable releases are tagged and deployed to production. Significant or notable changes that would break current behavior are developed in separate branches and merged to master through the PR. Squashing is not necessary.

Charon uses pipenv for dependencies management. Currently build on top of:

  • Flask - development server and facade
  • gunicorn - production server
  • flask-restx - requests processing, swagger
  • requests - sending HTTP requests to Roman/Bot
  • emoji - emoji processing (from Slack to Wire)
  • redis - storage for information about bots and services
  • dacite - simple Dataclass parsing from JSON

Releases

See releases page for more info.

alt text

About

Proxy mapping requests from Slack bots to Roman and back

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - wireapp/charon: Proxy mapping requests from Slack bots to Roman and back · GitHub
Skip to content
This repository was archived by the owner on Oct 21, 2024. It is now read-only.

Repository files navigation

Charon

GitHub versionCI/CDRelease Pipeline

Bridge between Slack and Wire

Charon is proxy converting Slack Bot API calls to Wire (using Roman) and back and thus allows to use subset of Slack Bots in the Wire.

Please note that this is simple proof of concept work, that was developed in few days just to prove that it is possible to use existing Slack Bot and connect it to the Wire API. The code looks accordingly.

How does Charon work

It exposes Slack-like API which is called by the Slack Bot. Then it transforms the API call to one that can be processed by Roman. The very same thing happens when new message is received from the Roman, the message is transformed (some information are missing in the default calls from the Roman, so the proxy ask for them) to the Slack version of message and sent to the Slack Bot API.

Is it slow?

Not really, it is slower than running native Lithium, but when I was testing raw Slack Bot with Slack API, the response time was between 1.4 and 2.5 seconds. The setup with Charon and Roman had response times around 1.2 and 2.5 seconds, so no leg basically.

Security & Privacy

Please note that the requests from the bots and the bots communication through Charon & Roman is not end-to-end encrypted. Whole idea of using Charon & Roman is to provide most simple way how to send data to the Wire environment and therefore all encryption is leveraged to the Roman. In other words, requests sent to the Charon are not encrypted, Charon sends them to Roman, then Roman encrypts them (Roman uses Lithium) and send them to Wire backend.

However, Charon does not store content of conversations in the database (but when debug log level is enabled, part of the messages can be printed to logs). The only data, that are stored, are access keys to Roman and to Slack bot. All database related operation can be found in Repository.

If the e2e encryption is necessary, one can either deploy Roman and Charon to one's infrastructure or to use directly Lithium.

Slack bot onboarding

To add new Slack bot instance to Charon one must register the bot in the Roman and in the Charon. Both services have Swagger API for registration process or one can use CLI from the repository with example.

Charon have support for Slack webhook API as well as event API, therefore the bot can either just post messages via webhook API or have complete access to communication with event API.

Webhook API

One must register the bot in Roman and then on /registration/hook endpoint in the Charon. Due to Wire security limitations, webhook links are generated when the bot is added to the conversation. Therefore in order to get the webhook link, one must add the bot to the conversation, where should be the bot posting the messages. After adding the bot to the conversation, you will receive generated link for that specific conversation.

Minimal working example is:

curl -X POST http://charon.wire.com/slack/webhook/<api-key-per-bot>/<generated-conversation-id> \
--header "content-type: application/json"\ 
--data '{"text": "hello world"}'

For registering new bot, one can use CLI.

Example

Example bot with complete CLI and description can be found here. It is based on the official tutorial, where we changed just the backend URL (from Slack to Charon). In that repo, there's also CLI, which allows to run the bot targeting Slacks API or Wire with single command.

make run-wire

To target Wire or to target Slack:

make run-slack

Known issues

This is just a PoC project, to show that it is indeed possible to partially map Slack API and to use Slack bots in the Wire infrastructure. However, there are some limitations and therefore mapping between API can't be 1:1.

Known limitations so far:

  • Wire does not have concept of Slack's channel
    • channels are in Slack public and all bots can read from them even though they are not part of that channel, Wire does not have concept of public channels as public channels couldn't be encrypted
    • Charon therefore maps channel to group, where group is Slack's concept of private conversations
  • Wire does not support commands
    • Slack has special type of the message which is called command that is basically /do something
    • This can be implemented in Charon in the future by simply parsing incoming message from the Roman and if it starts with /, Charon would transform that into the command message.
  • Bot can not initiate conversation
    • In the Slack, bot can create conversation with anyone, Wire does not allow conversations initiated by bot for security reasons.
  • Various events
    • Wire does not support messages pins yet
    • Wire has only hearth reaction, so no other emojis can be used for reactions.
    • In general, vast majority of events from Slack are not, or even couldn't be, mapped to Wire events as Wire tries to limit the API and events because of security. However, that shouldn't be problem in the future, because bot should react only to events that we want it to react, therefore we are able to simulate almost anything.

There are, for sure, more limitation then those listed here, but we haven't found out yet.

Running Charon

Charon needs following configuration - ROMAN_URL, REDIS_URL, REDIS_PORT, REDIS_USERNAME, REDIS_PASSWORD and CHARON_URL. To run Charon locally, please create file config.py which contains following runtime variables:

ROMAN_URL='http://proxy.services.zinfra.io'REDIS_URL='localhost'REDIS_PORT='6379'REDIS_USERNAME=''REDIS_PASSWORD=''CHARON_URL='http://localhost:8080'

and spin the Redis instance - there's one in the docker-compose. To run Charon inside docker-compose, just execute docker-compose up.

Configuration

  • CHARON_URL - is URL under which is Charon visible from public internet, it is used to generate unique URLs for the webhook only bots

Docker Images

Charon has public docker image.

lukaswire/charon

Tag latest is current master branch - each commit is build and tagged as latest. Releases have then images with corresponding tag.

Development

Master branch is used as bleeding edge which is deployed as latest to staging environment. Stable releases are tagged and deployed to production. Significant or notable changes that would break current behavior are developed in separate branches and merged to master through the PR. Squashing is not necessary.

Charon uses pipenv for dependencies management. Currently build on top of:

  • Flask - development server and facade
  • gunicorn - production server
  • flask-restx - requests processing, swagger
  • requests - sending HTTP requests to Roman/Bot
  • emoji - emoji processing (from Slack to Wire)
  • redis - storage for information about bots and services
  • dacite - simple Dataclass parsing from JSON

Releases

See releases page for more info.

alt text

About

Proxy mapping requests from Slack bots to Roman and back

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - wireapp/charon: Proxy mapping requests from Slack bots to Roman and back · GitHub
Skip to content
This repository was archived by the owner on Oct 21, 2024. It is now read-only.

Repository files navigation

Charon

GitHub versionCI/CDRelease Pipeline

Bridge between Slack and Wire

Charon is proxy converting Slack Bot API calls to Wire (using Roman) and back and thus allows to use subset of Slack Bots in the Wire.

Please note that this is simple proof of concept work, that was developed in few days just to prove that it is possible to use existing Slack Bot and connect it to the Wire API. The code looks accordingly.

How does Charon work

It exposes Slack-like API which is called by the Slack Bot. Then it transforms the API call to one that can be processed by Roman. The very same thing happens when new message is received from the Roman, the message is transformed (some information are missing in the default calls from the Roman, so the proxy ask for them) to the Slack version of message and sent to the Slack Bot API.

Is it slow?

Not really, it is slower than running native Lithium, but when I was testing raw Slack Bot with Slack API, the response time was between 1.4 and 2.5 seconds. The setup with Charon and Roman had response times around 1.2 and 2.5 seconds, so no leg basically.

Security & Privacy

Please note that the requests from the bots and the bots communication through Charon & Roman is not end-to-end encrypted. Whole idea of using Charon & Roman is to provide most simple way how to send data to the Wire environment and therefore all encryption is leveraged to the Roman. In other words, requests sent to the Charon are not encrypted, Charon sends them to Roman, then Roman encrypts them (Roman uses Lithium) and send them to Wire backend.

However, Charon does not store content of conversations in the database (but when debug log level is enabled, part of the messages can be printed to logs). The only data, that are stored, are access keys to Roman and to Slack bot. All database related operation can be found in Repository.

If the e2e encryption is necessary, one can either deploy Roman and Charon to one's infrastructure or to use directly Lithium.

Slack bot onboarding

To add new Slack bot instance to Charon one must register the bot in the Roman and in the Charon. Both services have Swagger API for registration process or one can use CLI from the repository with example.

Charon have support for Slack webhook API as well as event API, therefore the bot can either just post messages via webhook API or have complete access to communication with event API.

Webhook API

One must register the bot in Roman and then on /registration/hook endpoint in the Charon. Due to Wire security limitations, webhook links are generated when the bot is added to the conversation. Therefore in order to get the webhook link, one must add the bot to the conversation, where should be the bot posting the messages. After adding the bot to the conversation, you will receive generated link for that specific conversation.

Minimal working example is:

curl -X POST http://charon.wire.com/slack/webhook/<api-key-per-bot>/<generated-conversation-id> \
--header "content-type: application/json"\ 
--data '{"text": "hello world"}'

For registering new bot, one can use CLI.

Example

Example bot with complete CLI and description can be found here. It is based on the official tutorial, where we changed just the backend URL (from Slack to Charon). In that repo, there's also CLI, which allows to run the bot targeting Slacks API or Wire with single command.

make run-wire

To target Wire or to target Slack:

make run-slack

Known issues

This is just a PoC project, to show that it is indeed possible to partially map Slack API and to use Slack bots in the Wire infrastructure. However, there are some limitations and therefore mapping between API can't be 1:1.

Known limitations so far:

  • Wire does not have concept of Slack's channel
    • channels are in Slack public and all bots can read from them even though they are not part of that channel, Wire does not have concept of public channels as public channels couldn't be encrypted
    • Charon therefore maps channel to group, where group is Slack's concept of private conversations
  • Wire does not support commands
    • Slack has special type of the message which is called command that is basically /do something
    • This can be implemented in Charon in the future by simply parsing incoming message from the Roman and if it starts with /, Charon would transform that into the command message.
  • Bot can not initiate conversation
    • In the Slack, bot can create conversation with anyone, Wire does not allow conversations initiated by bot for security reasons.
  • Various events
    • Wire does not support messages pins yet
    • Wire has only hearth reaction, so no other emojis can be used for reactions.
    • In general, vast majority of events from Slack are not, or even couldn't be, mapped to Wire events as Wire tries to limit the API and events because of security. However, that shouldn't be problem in the future, because bot should react only to events that we want it to react, therefore we are able to simulate almost anything.

There are, for sure, more limitation then those listed here, but we haven't found out yet.

Running Charon

Charon needs following configuration - ROMAN_URL, REDIS_URL, REDIS_PORT, REDIS_USERNAME, REDIS_PASSWORD and CHARON_URL. To run Charon locally, please create file config.py which contains following runtime variables:

ROMAN_URL='http://proxy.services.zinfra.io'REDIS_URL='localhost'REDIS_PORT='6379'REDIS_USERNAME=''REDIS_PASSWORD=''CHARON_URL='http://localhost:8080'

and spin the Redis instance - there's one in the docker-compose. To run Charon inside docker-compose, just execute docker-compose up.

Configuration

  • CHARON_URL - is URL under which is Charon visible from public internet, it is used to generate unique URLs for the webhook only bots

Docker Images

Charon has public docker image.

lukaswire/charon

Tag latest is current master branch - each commit is build and tagged as latest. Releases have then images with corresponding tag.

Development

Master branch is used as bleeding edge which is deployed as latest to staging environment. Stable releases are tagged and deployed to production. Significant or notable changes that would break current behavior are developed in separate branches and merged to master through the PR. Squashing is not necessary.

Charon uses pipenv for dependencies management. Currently build on top of:

  • Flask - development server and facade
  • gunicorn - production server
  • flask-restx - requests processing, swagger
  • requests - sending HTTP requests to Roman/Bot
  • emoji - emoji processing (from Slack to Wire)
  • redis - storage for information about bots and services
  • dacite - simple Dataclass parsing from JSON

Releases

See releases page for more info.

alt text

About

Proxy mapping requests from Slack bots to Roman and back

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - wireapp/charon: Proxy mapping requests from Slack bots to Roman and back · GitHub
Skip to content
This repository was archived by the owner on Oct 21, 2024. It is now read-only.

Repository files navigation

Charon

GitHub versionCI/CDRelease Pipeline

Bridge between Slack and Wire

Charon is proxy converting Slack Bot API calls to Wire (using Roman) and back and thus allows to use subset of Slack Bots in the Wire.

Please note that this is simple proof of concept work, that was developed in few days just to prove that it is possible to use existing Slack Bot and connect it to the Wire API. The code looks accordingly.

How does Charon work

It exposes Slack-like API which is called by the Slack Bot. Then it transforms the API call to one that can be processed by Roman. The very same thing happens when new message is received from the Roman, the message is transformed (some information are missing in the default calls from the Roman, so the proxy ask for them) to the Slack version of message and sent to the Slack Bot API.

Is it slow?

Not really, it is slower than running native Lithium, but when I was testing raw Slack Bot with Slack API, the response time was between 1.4 and 2.5 seconds. The setup with Charon and Roman had response times around 1.2 and 2.5 seconds, so no leg basically.

Security & Privacy

Please note that the requests from the bots and the bots communication through Charon & Roman is not end-to-end encrypted. Whole idea of using Charon & Roman is to provide most simple way how to send data to the Wire environment and therefore all encryption is leveraged to the Roman. In other words, requests sent to the Charon are not encrypted, Charon sends them to Roman, then Roman encrypts them (Roman uses Lithium) and send them to Wire backend.

However, Charon does not store content of conversations in the database (but when debug log level is enabled, part of the messages can be printed to logs). The only data, that are stored, are access keys to Roman and to Slack bot. All database related operation can be found in Repository.

If the e2e encryption is necessary, one can either deploy Roman and Charon to one's infrastructure or to use directly Lithium.

Slack bot onboarding

To add new Slack bot instance to Charon one must register the bot in the Roman and in the Charon. Both services have Swagger API for registration process or one can use CLI from the repository with example.

Charon have support for Slack webhook API as well as event API, therefore the bot can either just post messages via webhook API or have complete access to communication with event API.

Webhook API

One must register the bot in Roman and then on /registration/hook endpoint in the Charon. Due to Wire security limitations, webhook links are generated when the bot is added to the conversation. Therefore in order to get the webhook link, one must add the bot to the conversation, where should be the bot posting the messages. After adding the bot to the conversation, you will receive generated link for that specific conversation.

Minimal working example is:

curl -X POST http://charon.wire.com/slack/webhook/<api-key-per-bot>/<generated-conversation-id> \
--header "content-type: application/json"\ 
--data '{"text": "hello world"}'

For registering new bot, one can use CLI.

Example

Example bot with complete CLI and description can be found here. It is based on the official tutorial, where we changed just the backend URL (from Slack to Charon). In that repo, there's also CLI, which allows to run the bot targeting Slacks API or Wire with single command.

make run-wire

To target Wire or to target Slack:

make run-slack

Known issues

This is just a PoC project, to show that it is indeed possible to partially map Slack API and to use Slack bots in the Wire infrastructure. However, there are some limitations and therefore mapping between API can't be 1:1.

Known limitations so far:

  • Wire does not have concept of Slack's channel
    • channels are in Slack public and all bots can read from them even though they are not part of that channel, Wire does not have concept of public channels as public channels couldn't be encrypted
    • Charon therefore maps channel to group, where group is Slack's concept of private conversations
  • Wire does not support commands
    • Slack has special type of the message which is called command that is basically /do something
    • This can be implemented in Charon in the future by simply parsing incoming message from the Roman and if it starts with /, Charon would transform that into the command message.
  • Bot can not initiate conversation
    • In the Slack, bot can create conversation with anyone, Wire does not allow conversations initiated by bot for security reasons.
  • Various events
    • Wire does not support messages pins yet
    • Wire has only hearth reaction, so no other emojis can be used for reactions.
    • In general, vast majority of events from Slack are not, or even couldn't be, mapped to Wire events as Wire tries to limit the API and events because of security. However, that shouldn't be problem in the future, because bot should react only to events that we want it to react, therefore we are able to simulate almost anything.

There are, for sure, more limitation then those listed here, but we haven't found out yet.

Running Charon

Charon needs following configuration - ROMAN_URL, REDIS_URL, REDIS_PORT, REDIS_USERNAME, REDIS_PASSWORD and CHARON_URL. To run Charon locally, please create file config.py which contains following runtime variables:

ROMAN_URL='http://proxy.services.zinfra.io'REDIS_URL='localhost'REDIS_PORT='6379'REDIS_USERNAME=''REDIS_PASSWORD=''CHARON_URL='http://localhost:8080'

and spin the Redis instance - there's one in the docker-compose. To run Charon inside docker-compose, just execute docker-compose up.

Configuration

  • CHARON_URL - is URL under which is Charon visible from public internet, it is used to generate unique URLs for the webhook only bots

Docker Images

Charon has public docker image.

lukaswire/charon

Tag latest is current master branch - each commit is build and tagged as latest. Releases have then images with corresponding tag.

Development

Master branch is used as bleeding edge which is deployed as latest to staging environment. Stable releases are tagged and deployed to production. Significant or notable changes that would break current behavior are developed in separate branches and merged to master through the PR. Squashing is not necessary.

Charon uses pipenv for dependencies management. Currently build on top of:

  • Flask - development server and facade
  • gunicorn - production server
  • flask-restx - requests processing, swagger
  • requests - sending HTTP requests to Roman/Bot
  • emoji - emoji processing (from Slack to Wire)
  • redis - storage for information about bots and services
  • dacite - simple Dataclass parsing from JSON

Releases

See releases page for more info.

alt text

About

Proxy mapping requests from Slack bots to Roman and back

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages