{"id":17540444,"url":"https://github.com/cellane/deep_thought","last_synced_at":"2026-02-24T00:06:13.025Z","repository":{"id":50117887,"uuid":"372673412","full_name":"Cellane/deep_thought","owner":"Cellane","description":"Slack translation bot (using DeepL service) written in Elixir/Phoenix","archived":false,"fork":false,"pushed_at":"2025-01-16T04:29:43.000Z","size":217,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-29T06:04:32.329Z","etag":null,"topics":["deepl","elixir","elixir-phoenix","phoenix","slack","slack-bot","translation"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Cellane.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-01T01:55:11.000Z","updated_at":"2025-01-16T04:29:45.000Z","dependencies_parsed_at":"2025-03-29T04:40:56.999Z","dependency_job_id":"441b7713-1172-4faf-ba2c-ee68cfd7fd62","html_url":"https://github.com/Cellane/deep_thought","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Cellane/deep_thought","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cellane%2Fdeep_thought","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cellane%2Fdeep_thought/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cellane%2Fdeep_thought/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cellane%2Fdeep_thought/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Cellane","download_url":"https://codeload.github.com/Cellane/deep_thought/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cellane%2Fdeep_thought/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29761997,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T21:02:23.375Z","status":"ssl_error","status_checked_at":"2026-02-23T20:58:31.539Z","response_time":90,"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":["deepl","elixir","elixir-phoenix","phoenix","slack","slack-bot","translation"],"created_at":"2024-10-20T22:23:55.222Z","updated_at":"2026-02-24T00:06:13.008Z","avatar_url":"https://github.com/Cellane.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🤔 Deep Thought – DeepL translation bot for Slack\n\n_Deep Thought_ is a Slack bot that provides a simple way to get translations for messages sent in your workspace. Simply invite _Deep Thought_ into channels (or group conversations!) that you wish to receive translations in, react to a message you wish to see translated with a flag emoji that indicates the desired language (for example, use Japanese flag 🇯🇵 to get translation in Japanese), and let the magic happen! ✨\n\n## Usage\n\nThere are two main ways of interacting with the bot and receiving translations:\n\n1. Most users choose to request and receive translations by reacting to a message they wish to see translated with an flag emoji, as described above;\n2. For sending a quick translation into public channel or private channel the bot was previously invited to, you can also utilize the recently added `/translate [language shorthand/flag emoji] [text]` Slack command.\n\n## Prerequisites\n\nTo run the bot, you must fullfil the following requirements:\n\n- Have a DeepL API key (provided with a [DeepL API Free](https://www.deepl.com/pro#developer) or [DeepL API Pro plans](https://www.deepl.com/pro#developer));\n- Have a Slack workspace to which you are permitted to install apps;\n- Have a Heroku-compatible application hosting with a PostgreSQL database;\n  - While [Heroku](https://www.heroku.com) is technically supported, the bot has only been tested in a [Dokku](https://dokku.com/) environment with the official [Dokku Postgres Plugin](https://github.com/dokku/dokku-postgres).\n\n## Deployment\n\nTo deploy _Deep Thought_, you first need to create a Slack application, then configure your server to receive callback anytime the bot should perform any action.\n\n### Slack configuration\n\n1. Navigate to the [Your Apps](https://api.slack.com/apps) page and press the **Create New App** button\n2. Choose _From an app manifest_, select your workspace and paste the following manifest, adjusting the `YOUR.DOMAIN.HERE` strings in three different places:\n\n   ```yaml\n   _metadata:\n     major_version: 1\n     minor_version: 1\n   display_information:\n     name: Deep Thought\n     description: For the deepest of translations\n     background_color: \"#2c2d30\"\n   features:\n     app_home:\n       home_tab_enabled: false\n       messages_tab_enabled: true\n       messages_tab_read_only_enabled: true\n     bot_user:\n       display_name: Deep Thought\n       always_online: true\n     slash_commands:\n       - command: /translate\n         url: https://YOUR.DOMAIN.HERE/slack/commands/translate\n         description:\n           Translate your message, sending both the translation and original\n           text to the channel\n         usage_hint: \"[language shorthand/flag emoji] [text]\"\n         should_escape: false\n   oauth_config:\n     scopes:\n       bot:\n         - channels:history\n         - chat:write\n         - commands\n         - groups:history\n         - mpim:history\n         - mpim:write\n         - reactions:read\n         - users.profile:read\n         - chat:write.public\n   settings:\n     event_subscriptions:\n       request_url: https://YOUR.DOMAIN.HERE/slack/events\n       bot_events:\n         - reaction_added\n     interactivity:\n       is_enabled: true\n       request_url: https://YOUR.DOMAIN.HERE/slack/actions\n     org_deploy_enabled: false\n     socket_mode_enabled: false\n     is_hosted: false\n   ```\n\n3. Confirm by pressing the **Create** button\n4. Install the application to your workspace by pressing the **Install to Workspace** button and confirming the permission scope\n5. Reveal your _Signing Secret_ by pressing the **Show** button – this will be the value of your `SLACK_SIGNING_SECRET` environmental variable\n6. Navigate to the _OAuth \u0026 Permissions_ section and note your _Bot User OAuth Token_ – this will be the value of your `SLACK_BOT_TOKEN` environmental variable\n\n### Dokku configuration (server side)\n\n1. Install the official Dokku Postgres Plugin if you haven’t done so before\n\n   ```shell\n   sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres\n   ```\n\n2. Create a new Dokku app to host the bot:\n\n   ```shell\n   dokku apps:create bot\n   ```\n\n3. Create and link a database:\n\n   ```shell\n   dokku postgres:create bot-db\n   dokku postgres:link bot-db bot\n   ```\n\n4. Configure the required environmental variables:\n\n   ```shell\n   dokku config:set bot DEEPL_AUTH_KEY=DEEPL_AUTH_KEY_HERE\n   dokku config:set bot HOSTNAME=HOSTNAME_HERE\n   dokku config:set bot SECRET_KEY_BASE=SECRET_KEY_BASE\n   dokku config:set bot SLACK_BOT_TOKEN=SLACK_BOT_TOKEN_HERE\n   dokku config:set bot SLACK_SIGNING_SECRET=SLACK_SIGNING_SECRET_HERE\n   ```\n\n   Most of these are self-describing, but two variables are of note:\n\n   - `HOSTNAME` should correspond to the hostname your bot will be accessible on, without the protocol prefix\n   - `SECRET_KEY_BASE` can be any sufficiently random string, but preferably use a key generated with the `mix phx.gen.secret` command\n\n5. Configure the domain mapping for the app:\n\n   ```shell\n   dokku domains:set bot YOUR.DOMAIN.HERE\n   ```\n\n6. Configure TLS so that the bot is accessible via HTTPS in a way that is acceptable to you, perhaps with Dokku’s [Let’s Encrypt plugin](https://github.com/dokku/dokku-letsencrypt)\n\n### Dokku configuration (local side)\n\n1. From the directory into which you have checked this repository out, configure the remote repository pointing at your Dokku instance:\n\n   ```shell\n   git remote add dokku dokku@YOUR.SERVER.HERE:bot\n   ```\n\n2. Finally, deploy the bot:\n\n   ```shell\n   git push dokku master\n   ```\n\n## Local development\n\nTo start your bot:\n\n- Install dependencies with `mix deps.get`\n- Create and migrate your database with `mix ecto.setup`\n- Install Node.js dependencies with `npm install` inside the `assets` directory\n- Start Phoenix endpoint with `mix phx.server`\n\n## Privacy\n\nWhile the bot has to store some information in its database in order to function properly, it does not store either the original nor the translated message. Currently, these are the only pieces of information that _Deep Thought_ stores:\n\n- For each translated message:\n  - `channel_id`, an unique identifier of the channel in which the message was posted\n  - `message_ts`, an unique timestamp of the message that was translated\n  - `target_language`, indicating the language into which the message was translated\n- For each user mentioned in any translated message:\n  - `user_id`, an unique identifier of the user\n  - `real_name`, the value of the _Full Name_ field in user’s Slack profile\n\nIn order for _Deep Thought_ to operate correctly, the following Slack OAuth permission scopes are required:\n\n- `commands`\n  - Required in order to provide the `/translate` slash command\n- `groups:history`\n  - Required in order to read the content of a single message in private channels that _Deep Thought_ was manually invited to, once a flag emoji has been added to that message\n- `channels:history`\n  - Required in order to read the content of a single message in public channels that _Deep Thought_ was manually invited to, once a flag emoji has been added to that message\n- `chat:write`\n  - Required in order to send message to private channels _Deep Thought_ was manually invited to\n- `chat:write.public`\n  - Required in order to send messages to any public channel\n- `mpim:history`\n  - Required in order to read the content of a single message in group direct messages that _Deep Thought_ was manually invited to, once a flag emoji has been added to that message\n- `mpim:write`\n  - Required in order to send messages to group direct messages\n- `reactions:read`\n  - Required in order to be notified when emoji reaction has been added to a message\n- `users.profile:read`\n  - Required in order to translate machine-readable user ID’s into user’s real name\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcellane%2Fdeep_thought","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcellane%2Fdeep_thought","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcellane%2Fdeep_thought/lists"}