{"id":32983895,"url":"https://github.com/arunthampi/relax","last_synced_at":"2026-01-14T15:53:08.938Z","repository":{"id":66375385,"uuid":"42845295","full_name":"arunthampi/relax","owner":"arunthampi","description":"Bots-as-a-Service for Slack","archived":false,"fork":false,"pushed_at":"2017-04-04T16:44:06.000Z","size":557,"stargazers_count":170,"open_issues_count":6,"forks_count":23,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-12-26T01:44:15.339Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arunthampi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2015-09-21T05:13:22.000Z","updated_at":"2024-11-28T15:33:44.000Z","dependencies_parsed_at":"2023-02-21T04:45:16.522Z","dependency_job_id":null,"html_url":"https://github.com/arunthampi/relax","commit_stats":null,"previous_names":["zerobotlabs/relax"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/arunthampi/relax","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arunthampi%2Frelax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arunthampi%2Frelax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arunthampi%2Frelax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arunthampi%2Frelax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arunthampi","download_url":"https://codeload.github.com/arunthampi/relax/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arunthampi%2Frelax/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28425512,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T15:24:48.085Z","status":"ssl_error","status_checked_at":"2026-01-14T15:23:41.940Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-11-13T07:00:40.532Z","updated_at":"2026-01-14T15:53:08.916Z","avatar_url":"https://github.com/arunthampi.png","language":"Go","funding_links":[],"categories":["Libraries"],"sub_categories":["Slack"],"readme":"## Relax\n\nRelax is a Message Broker for Slack Bots. What does that mean?\nIf you are running a \"bot-as-a-service\" for Slack, you have to maintain\nhundreds (if not thousands) of websocket connections and handle the\ndeluge of events from all these connections.\n\nRelax does all that heavy\nlifting for you and provides you with a single stream of events that\nyour web app can then take action on. The protocol is JSON based and so\nany web app can communicate with Relax.\n\n[![Travis Badge for Relax](https://travis-ci.org/zerobotlabs/relax.svg?branch=master)](https://travis-ci.org/zerobotlabs/relax)\n[![Gitter](https://badges.gitter.im/zerobotlabs/relax.svg)](https://gitter.im/zerobotlabs/relax?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n\nIf you are a Rails app however, there is a nifty [Ruby\nclient](https://github.com/zerobotlabs/relax-rb) for you to use.\n\nYou can also download pre-built binaries [here](#installation).\n\nIf you are a Heroku user, you can deploy Relax right away with one click.\n\n[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)\n\n\n**Known Issue:** When deploying using the \"Deploy with Heroku\" button,\nHeroku's Free Redis server takes a while to boot up, so your Relax\ndeployment will take a while to come up as well. You can see Relax\ntrying to connect to Heroku's Redis server by tailing logs `heroku logs\n--tail -a \u003cyour-heroku-app-name\u003e`. After a while, it should connect.\n\n## Coming Soon\n\n* Pluggable Messaging Backends\n\n## Installation\n\nAlthough Relax is written in Go, it does not require any knowledge\nof Go. You can download the latest stable version of relax\n[here](https://dl.equinox.io/zerobotlabs/relax/stable).\n\nBinaries are available for both OS X and Linux. Untar and gunzip the\ndownloaded file and move the `relax` binary to your `$PATH` to start\nusing.\n\n## Analytics for your Slackbot\n\nRelax now has optional [Botmetrics](https://getbotmetrics.com) analytics\nbuilt in. If you want analytics for your Slack bot, set the\n`BOTMETRICS_ENABLED` environment variable to 'true', get an API key and\na bot ID from botmetrics and set the `BOTMETRICS_API_KEY` and\n`BOTMETRICS_BOT_ID` environment variables set up and restart your Relax\ninstances.\n\n## In Production Use\n\nRelax is used in production to power [Nestor](https://www.asknestor.me).\n\n## Running Relax\n\nTo run it, basically run `relax` (assuming it is in your $PATH).\n\n`RELAX_BOTS_KEY=relax_bots_key RELAX_BOTS_PUBSUB=relax_bots_pubsub RELAX_EVENTS_QUEUE=relax_events_queue REDIS_HOST=localhost:6379 relax`\n\n## Setup\n\nThe Relax message broker requires a few environment variables to be set up (these same environment variables are also used to set up the Relax Ruby Client). These environment variables are basically Redis keys that can be configured based on your specific needs.\n\n`RELAX_BOTS_KEY`: This can be any string value and is used to store state about all Slack clients currently controlled by Relax in Redis.\n\n`RELAX_BOTS_PUBSUB`: This can be any string value and is used by Relax clients to notify Relax brokers that a new Slack bot has been started.\n\n`RELAX_EVENTS_QUEUE`: This can be any string value and is used by Relax brokers to send events to the client.\n\n`RELAX_MUTEX_KEY`: This can be any string value and is used by Relax brokers to decide whether to send events back to clients.\n\n## Protocol\n\nYou interact with Relax by sending messages to Relax via Redis, there\nare two primary ways of interacting with Relax:\n\n### Starting Bots\n\nTo start a bot, you need to `HSET` on `RELAX_BOTS_KEY` with a JSON blob\ncontaining `\"team_id\"` and `\"token\"` keys which represent the Team UID\nand Token for the bot you want to start. Along with this, you should\nalso `PUBLISH` on `RELAX_BOTS_PUBSUB` with a JSON blob containing the\nkeys `\"type\"` and `\"team_id\"` containing the values `\"team_added\"` and\nthe Team UID of the bot you want to start.\n\nFor e.g., for a bot who's Slack Team UID is \"TDEADBEEF\" and who's token\nis \"xoxo_slackbotoken\", you can issue the following commands using\n`redis-cli` to start a bot (assuming that `$RELAX_BOTS_KEY` is `relax_bots_key`):\n\n```bash\n$ redis-cli\n127.0.0.1:6379\u003e MULTI\nOK\n127.0.0.1:6379\u003e HSET relax_bots_key TDEADBEEF '{\"team_id\":\"TDEADBEEF\",\"token\":\"xoxo_slackbotoken\"}'\n(integer) 1\n127.0.0.1:6379\u003e HGETALL relax_bots_key\n1) \"TDEADBEEF\"\n2) \"{\\\"team_id\\\":\\\"TDEADBEEF\\\",\\\"token\\\":\\\"xoxo_slackbotoken\\\"}\"\n127.0.0.1:6379\u003e PUBLISH relax_bots_pubsub '{\"type\":\"team_added\",\"team_id\":\"TDEADBEEF\"}'\nQUEUED\n127.0.0.1:6379\u003e EXEC\n```\n\n### Listening for Events\n\nRelax also generates events (details of events are described in the [\"Events\" section of the README](https://github.com/zerobotlabs/relax#events))\n\nEvents are queued in the `$RELAX_EVENTS_QUEUE` key in Redis and so to consume events,\nyou need to `LPOP` or `BLPOP` the `$RELAX_EVENTS_QUEUE` to deal with events.\n\n## Events\n\nSlack Events are gathered from all teams that Slack is\nlistening to and are multiplexed onto a single Redis queue. The event\ndata structure consists of the following fields:\n\n### type\n\nThis is a string value contains the type of event can hold the following values:\n\nType               | What it does\n-------------------|---------------\n`disable_bot`      | This event is sent when authentication with a team fails (either due to a wrong token or an expired token).  `message_new`    | This is event is sent When a new message is received by Relax. *Note*: Only events for messages intended to Relax (so an @-mention to the bot or a direct message) are sent.\n`message_edited`   | This event is sent when a message has been edited.\n`message_deleted`  | This event is sent when a message has been deleted.\n`reaction_added`   | This event is sent when a reaction has been added to a message.\n`reaction_removed` | This event is sent when a reaction has been removed from a message.\n`team_joined`      | This event is sent when a new member has been added to the team. The best practice upon receiving this event is to refresh the team database and make sure that information on all members of the team is up to date.\n`im_created`       | This event is sent when a new direct message has been opened with the bot. This can be ignored in most cases as it is used by Relax to keep internal metadata in sync.\n\n### user_uid\n\nThis is a string value and is the UID (generated by Slack) of the user associated with the\nevent. So in the case of `message_new` it's the UID of the user who\ncreated the message, for `reaction_added`, it's the UID of the user who added a reaction to a message.\n\n### channel_uid\n\nThis is the UID (generated by Slack) of the channel associated with the event.\n\n### im\n\nThis is a boolean value to indicate whether the channel (with the UID\n`channel_uid`) is an IM or not.\n\n### text\n\nThis is a string value and contains the text associated with the\nevent. This can mean different things in different contexts:\n\nType               | What \"text\" field means\n-------------------|---------------\n`message_new`      | The message text\n`message_edited`   | The *new* text of the message\n`message_deleted`  | The original message text\n`reaction_added`   | Reaction added to a message. This contains the text representation of a reaction, for e.g. `:simple_smiley:`\n`reaction_removed` | Reaction removed from a message. This contain the text representation of a reaction, for e.g. `:simple_smiley:`\n`team_joined`      | Since there is no text metadata associated with this event, it is always blank.\n`im_created`       | Since there is no text metadata associated with this event, it is always blank.\n\n### relax_bot_uid\n\nThis is a string value and represent the UID of the bot that Relax\ncontrols. This is useful if you want to strip out the @-mention word in\na message @-mention'ed to the bot.\n\n### timestamp\n\nThis is a string value and represents the timestamp at which a\nparticular event occurred but can have different meanings in different\ncontexts:\n\nType               | What \"timestamp\" field means\n-------------------|---------------\n`disable_bot`      | Empty string\n`message_new`      | Timestamp at which the message was created. In this case, `timestamp` and `event_timestamp` will be the same\n`message_edited`   | Timestamp of the message that has been changed. Upon receiving a \"message_changed\" event, you can use \"channel_uid\" and \"timestamp\" to identify the message who's text has been changed and modify its text accordingly\n`message_deleted`  | Timestamp of the message that has been deleted. Upon receiving a \"message_changed\" event, you can use \"channel_uid\" and \"timestamp\" to identify the message that has been deleted and delete that message accordingly\n`reaction_added`   | Timestamp of the message for which a reaction has been added. Upon receiving a \"reaction_added\" event, you can use \"channel_uid\" and \"timestamp\" to identify the message for which a reaction has been added and change the metadata for that message accordingly\n`reaction_removed` | Timestamp of the message for which a reaction has been removed. Upon receiving a \"reaction_removed\" event, you can use \"channel_uid\" and \"timestamp\" to identify the message for which a reaction has been removed and change the metadata for that message accordingly\n`team_joined`      | Empty string\n`im_created`       | Empty string\n\n### provider\n\nThis is a string value and until Relax supports multiple providers,\nthis is always \"slack\".\n\n### event_timestamp\n\nThis is a string value and represents the time at which an event occurs.\nIn the case of `disable_bot`, `team_joined` and `im_created` events, it is\nan empty string.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farunthampi%2Frelax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farunthampi%2Frelax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farunthampi%2Frelax/lists"}