{"id":13842212,"url":"https://github.com/binwiederhier/replbot","last_synced_at":"2025-10-07T23:51:19.547Z","repository":{"id":46672122,"uuid":"388210775","full_name":"binwiederhier/replbot","owner":"binwiederhier","description":"Slack/Discord bot for running interactive REPLs and shells from a chat.","archived":false,"fork":false,"pushed_at":"2021-11-26T22:05:38.000Z","size":6808,"stargazers_count":203,"open_issues_count":5,"forks_count":8,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-12-10T00:42:07.305Z","etag":null,"topics":["discord","discord-bot","discordgo","docker","go","golang","repl","slack","slack-bot","slack-bot-go"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/binwiederhier.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}},"created_at":"2021-07-21T18:29:30.000Z","updated_at":"2024-11-25T13:05:14.000Z","dependencies_parsed_at":"2022-08-26T22:22:54.903Z","dependency_job_id":null,"html_url":"https://github.com/binwiederhier/replbot","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binwiederhier%2Freplbot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binwiederhier%2Freplbot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binwiederhier%2Freplbot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binwiederhier%2Freplbot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/binwiederhier","download_url":"https://codeload.github.com/binwiederhier/replbot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230408170,"owners_count":18220974,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["discord","discord-bot","discordgo","docker","go","golang","repl","slack","slack-bot","slack-bot-go"],"created_at":"2024-08-04T17:01:29.510Z","updated_at":"2025-10-07T23:51:14.516Z","avatar_url":"https://github.com/binwiederhier.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# 🤖 REPLbot\n[![Release](https://img.shields.io/github/release/binwiederhier/replbot.svg?color=success\u0026style=flat-square)](https://github.com/binwiederhier/replbot/releases/latest)\n[![Go Reference](https://pkg.go.dev/badge/heckel.io/replbot.svg)](https://pkg.go.dev/heckel.io/replbot)\n[![Tests](https://github.com/binwiederhier/replbot/workflows/test/badge.svg)](https://github.com/binwiederhier/replbot/actions)\n[![Go Report Card](https://goreportcard.com/badge/github.com/binwiederhier/replbot)](https://goreportcard.com/report/github.com/binwiederhier/replbot)\n[![codecov](https://codecov.io/gh/binwiederhier/replbot/branch/master/graph/badge.svg?token=bdrFZttMsk)](https://codecov.io/gh/binwiederhier/replbot)\n[![Slack channel](https://img.shields.io/badge/slack-@gophers/binwiederhier-success.svg?logo=slack)](https://gophers.slack.com/archives/C01JMTPGF2Q)\n\nREPLbot is a bot for Slack and Discord that allows you to control a [REPL](https://en.m.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) \nor shell from a chat. It comes with a few REPLs (Go 🥳, Java, NodeJS, PHP, Python, Ruby, Scala, Kotlin, C++, Ubuntu, Debian, Alpine, Arch Linux, Amazon Linux, CentOS \u0026 Fedora), \nbut you can [easily make or bring your own](config/script.d).\n\n![replbot demo](assets/slack-php-count.gif)\n\n## Why ...?\nI thought it might be a fun way to collaboratively dabble with a REPL in a team. Yes, I could have gone for a terminal \nin a browser, but there's nothing like having it right there in Slack. Mainly I did it because it was fun though. 😄\n\n## How it works\nI use `tmux` and the `tmux capture-pane` command to run most of the show. It's simple, but effective. In the first \niteration I tried using a pseudo terminal (pty) directly, but with all the escape sequences and commands, it was getting\nkinda tiresome, and I was spending time with stuff that I didn't want to spend time with (though I learned a lot!). \nAnd `tmux` does its job so well. \n\nThe actual REPLs are just simple scripts (see [script.d folder](config/script.d)), so they could be anything you like. \nI highly recommend using Docker to provide somewhat of an isolation, though you'll probably still need to trust the\npeople using the bot if you give them an entire REPL.\n\n## Screenshots \u0026 Videos\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src=\"assets/discord-scala-split.png\" width=\"300\"\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src=\"assets/discord-ubuntu-htop-split.png\" width=\"300\"\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cimg src=\"assets/discord-cpp-channel.png\" width=\"300\"\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eScala, split mode (Discord)\u003c/td\u003e\n    \u003ctd\u003eUbuntu running `htop` (Discord)\u003c/td\u003e\n    \u003ctd\u003eC++, channel mode (Discord)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cimg src=\"assets/slack-ubuntu-cursor-train.gif\" width=\"300\"\u003e\u003c/td\u003e    \n    \u003ctd\u003e\u003cimg src=\"assets/slack-ubuntu-custom-multiple.png\" width=\"300\"\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eBlinking cursors, choo choo 🚂 (Slack)\u003c/td\u003e        \n    \u003ctd\u003eCustom shells, multiple sessions (Slack)\u003c/td\u003e\n    \u003ctd\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## Usage\nAfter [installing REPLbot](#installation), you may use it by tagging `@replbot` in Slack/Discord. For the most part it \nshould be pretty self-explanatory:\n\n![replbot mention](assets/slack-mention-help.png)\n\nTo start a session with the default settings, simply say `@replbot java` to start a Java REPL. There are a few advanced arguments\nyou can use when starting a session.\n\n### REPL scripts\nREPLbot can run more or less arbitrary scripts and interact with them -- they don't really have to be REPLs. Any interactive\nscript is perfectly fine, whether it's a REPL or a Shell or even a game. By default, REPLbot ships with a [few REPLs](config/script.d). \nTo extend the REPLs you can run, simple add more scripts in the `script-dir` folder (see [config.yml](config/config.yml)).\n\nHere's a super simple example script:\n```bash\n#!/bin/sh\n# Scripts are executed as \"./script run \u003cid\u003e\" to start the REPL, and as \"./script kill \u003cid\u003e\"\n# to stop it. Not all scripts need the \"kill\" behavior, if they exit properly on SIGTERM.\ncase \"$1\" in\n  run)\n    while true; do\n      echo -n \"Enter name: \"\n      read name\n      echo \"Hello $name!\"\n    done \n    ;;\n  *) ;;\nesac\n```\n\nIn all likelihood, you'll want more isolation by running REPLs as Docker containers. Here's the [PHP REPL script](https://github.com/binwiederhier/replbot/blob/1460ddba1adbfd450465d5d37b0b9b340e8a4f79/config/script.d/php)\nthat REPLbot ships with (not shortened):\n\n```bash\n#!/bin/sh\n# REPLbot script to run a PHP REPL.\n#\n# Scripts are executed as \"./script run \u003cid\u003e\" to start the REPL,\n# and as \"./script kill \u003cid\u003e\" to stop it.\n\nDIR=\"$(cd -- \"$(dirname \"$0\")\" \u003e/dev/null 2\u003e\u00261 \u0026\u0026 pwd -P)\"\ncase \"$1\" in\n  run) docker run --rm --name \"$2\" -it php ;;\n  kill) \"$DIR\"/helpers/docker-kill \"$2\" ;;\n  *) echo \"Syntax: $0 (run|kill) ID\"; exit 1 ;;\nesac\n```\n\n### Session commands\nWhen a session is started, you can get a list of available commands by typing `!help` (or `!h`). To exit a session at any\npoint in time, type `!exit` (or `!q`).\n\n![replbot session help](assets/slack-session-help.png)\n\n### Recording sessions\nSessions can be recorded using `asciinema`, and can even be automatically uploaded to either [asciinema.org](https://asciinema.org/)\nor your private [asciinema-server](https://github.com/asciinema/asciinema-server) (see [install instructions](https://github.com/asciinema/asciinema-server/wiki/Installation-guide)).\n\nAfter a session exits, the recording is then attached to chat as a ZIP file and optionally as a link to the asciinema server.\nThis behavior can be controlled by the `default-record` and `upload-recording` option in the [config.yml](config/config.yml)\nfile, as well as the `record`/`norecord` option when starting a session. \n\nHere's [the asciinema.org link](https://asciinema.org/a/MGsOv6CCVXiRtR8ZEd7MtFOTe) of the example\nI recorded, as well as the [ZIP archive](assets/slack-recording.zip) with the recording.\n\n![replbot session recording](assets/slack-recording.png)\n\n### Web terminal\nEntering commands via Slack or Discord can be quite cumbersome, so REPLbot provides a web-based terminal (powered by\nthe amazingly awesome [ttyd](https://github.com/tsl0922/ttyd)). If enabled, a unique link is created for each session,\nwhich provides a read-only or writable web terminal.\n\n![replbot web terminal](assets/slack-web-terminal.png)\n\nThis behavior can be controlled by the `default-web` option in the [config.yml](config/config.yml) file, as well\nas the `web`/`noweb` option when starting a session. While a session is running, it can be toggled using the `!web`\ncommand.\n\n![replbot web terminal](assets/web-terminal.png)\n\n### Terminal sharing\nYou can share your local terminal window in Slack or Discord using the `share` feature. It's quite cool, although it's\nreally got nothing to do with REPLs 🤷. It also has to be specifically configured in the [config.yml](config/config.yml)\nfile using the `share-host` option, since it needs direct communication between the client and REPLbot.\n\n![replbot terminal sharing](assets/slack-terminal-sharing.gif)\n\n### Control mode\nYou can specify if you want the session to be started in the main channel (`channel`), in a thread (`thread`),\nor in split mode (`split`) using both channel and thread. Split mode is the default because it is the cleanest to use:\nit'll use a thread for command input and the main channel to display the terminal.\n\n![replbot split mode](assets/slack-split-mode.png)\n\n### Terminal size\nYou can set the terminal window size when you start a session by using the keywords `tiny` (60x15), `small` (80x24),\n`medium` (100x30), and `large` (120x38). The default is `small`. You may also resize the terminal while the session is\nrunning using the `!resize` command.\n\n![replbot window size](assets/discord-window-size.png)\n\n### Window mode\nWhen starting a session, you can choose whether to trim empty space from the terminal session (`trim`), or\nwhether to show the entire terminal window as it would appear in a terminal emulator (`full`). The default is `full`,\nas `trim` mode can get awkward when the terminal is expanded and the collapsed again.\n\n![replbot window mode](assets/discord-window-mode.png)\n\n## Installation\nPlease check out the [releases page](https://github.com/binwiederhier/replbot/releases) for binaries and \ndeb/rpm packages.\n\n**Requirements**:\n- A modern-ish Linux, preferably Ubuntu 18.04+, since that's what I develop on -- though it also runs on other\n  distros.\n- [tmux](https://github.com/tmux/tmux) \u003e= 2.6 is required, which is part of Ubuntu 18.04 (but surprisingly not part of Amazon Linux!)\n- [docker](https://docs.docker.com/get-docker/) for almost all scripts REPLbot ships with\n- [asciinema](https://asciinema.org/) if you'd like to [record sessions](#recording-sessions)\n- [ttyd](https://github.com/tsl0922/ttyd) if you'd like to use the [web terminal](#web-terminal) feature\n\n**Creating a REPLbot Slack app**:   \nREPLbot requires a Slack \"Classic App (bot)\", because of its use of the real time messaging (RTM)\nAPI. To create a classic app and acquire a Slack bot token, follow these steps:\n1. Create a [classic Slack app](https://api.slack.com/apps?new_classic_app=1)\n2. In the \"App Home\" section, add a \"Legacy bot user\"\n3. In the \"OAuth \u0026 Permissions\" section, click \"Install to Workspace\" (_this may require workspace admin approval_)\n4. Copy the \"Bot User OAuth Token\" starting with \"xoxb-...\"\n\n**Creating a REPLbot Discord app**:   \n1. Create a [Discord app](https://discord.com/developers/applications) \n2. In the \"Bot\" section, click \"Add Bot\" and disable \"Public Bot\"\n3. In the \"OAuth2\" section, click \"Add Redirect\" and type a URL (even https://google.com is fine),\n   select the scopes \"bot\" and \"messages.read\", and the permissions \"public threads\", \"private thread\",\n   \"send messages\", \"manage messages\", \"manage threads\". Click \"Save changes\".\n4. Copy the OAuth2 URL and navigate to it in the browser and authorize the app.\n5. In the \"Bot\" section, copy the token and paste it here\n\n**Installing `replbot`**:   \n1. Make sure `tmux` and probably also `docker` are installed. Then install REPLbot using any of the methods below. \n2. Then edit `/etc/replbot/config.yml` to add Slack or Discord bot token. REPLbot will figure out which one is which based on the format.\n3. Review the scripts in `/etc/replbot/script.d`, and make sure that you have Docker installed if you'd like to use them.\n4. If you're running REPLbot as non-root user (such as when you install the deb/rpm), be sure to add the `replbot` user to the `docker` group: `sudo usermod -G docker -a replbot`.\n5. Then just run it with `replbot` (or `systemctl start replbot` when using the deb/rpm).\n\n### Binaries and packages\n**Debian/Ubuntu** (*from a repository*)**:**\n```bash\ncurl -sSL https://archive.heckel.io/apt/pubkey.txt | sudo apt-key add -\nsudo apt install apt-transport-https\nsudo sh -c \"echo 'deb [arch=amd64] https://archive.heckel.io/apt debian main' \u003e /etc/apt/sources.list.d/archive.heckel.io.list\"  \nsudo apt update\nsudo apt install replbot asciinema\n```\n\n**Debian/Ubuntu** (*manual install*)**:**\n```bash\nsudo apt install tmux\nwget https://github.com/binwiederhier/replbot/releases/download/v0.6.4/replbot_0.6.4_amd64.deb\ndpkg -i replbot_0.6.4_amd64.deb\n```\n\n**Fedora/RHEL/CentOS:**\n```bash\n# Make sure that \"tmux\" is installed\nrpm -ivh https://github.com/binwiederhier/replbot/releases/download/v0.6.4/replbot_0.6.4_amd64.rpm\n```\n\n**Docker:**   \nYou can configure the Docker image by mounting a config directory (containing [config.yml](config/config.yml)) to \n`/etc/replbot`. To be able to use most of the pre-packaged [script.d](config/script.d) REPLs (to be mounted to `/etc/replbot/script.d`), \nyou'll need to give the REPLbot image access to the Docker socket file. This allows the container to spin up other containers \non the host. This is a security risk and considered bad practice, but it's the only way.\n\n```bash\n# Config and scripts live on the host\nwget https://github.com/binwiederhier/replbot/archive/refs/tags/v0.6.4.tar.gz\ntar zxvf v0.6.4.tar.gz\nsudo mkdir /etc/replbot\nsudo cp -a replbot-0.6.4/config/{script.d,config.yml} /etc/replbot\nvi /etc/replbot/config.yml\n  # Configure at least \"bot-token\"\n  # To support web terminal, set \"web-host\" (e.g. to localhost:31001)\n  # To support sharing, set \"share-host\" (e.g. to localhost:31002)\n  \n# Then you can start the REPLbot docker image (assuming web-host listening\n# at 31001 and share-host at 31002)\ndocker run --rm -it \\\n  -v /etc/replbot:/etc/replbot \\\n  -v ~/.asciinema:/root/.config/asciinema \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  -p 31001:31001 \\\n  -p 31002:31002 \\\n  binwiederhier/replbot\n```\n\nPlease note that if you'd like to associate the asciinema videos to an account, you need to set up and map the config directory\nproperly. For me, that worked by installing it on the host, running `asciinema rec` once and then associating the install-id \nlocated in `~/.asciinema/install-id`. Inside the docker image, asciinema expects the config directory to be in `~/.config/asciinema`.\n\n**Go:**\n```bash\n# Be sure \"tmux\" is installed\ngo get -u heckel.io/replbot\n```\n\n**Manual install** (*any x86_64-based Linux*)**:**\n```bash\n# Make sure that \"tmux\" is installed\nwget https://github.com/binwiederhier/replbot/releases/download/v0.6.4/replbot_0.6.4_linux_x86_64.tar.gz\nsudo tar -C /usr/bin -zxf replbot_0.6.4_linux_x86_64.tar.gz replbot\n```\n\n## Building\nBuilding replbot is simple. Here's how you do it:\n\n```\nmake build-simple\n# Builds to dist/replbot_linux_amd64/replbot\n``` \n\nTo build releases, I use [GoReleaser](https://goreleaser.com/). If you have that installed, you can run `make build` or\n`make build-snapshot`.\n\n## Contributing\nI welcome any and all contributions. Just create a PR or an issue, or talk to me [on Slack](https://gophers.slack.com/archives/C02ABHKDCN7).\n\n## License\nMade with ❤️ by [Philipp C. Heckel](https://heckel.io), distributed under the [Apache License 2.0](LICENSE).\n\nThird party tools/libraries:\n* [tmux](https://github.com/tmux/tmux) (ISC) is used to run most of the show\n* [docker](https://docs.docker.com/get-docker/) is used for almost all scripts REPLbot ships with\n* [asciinema](https://asciinema.org/) (GPLv3) is used to record sessions\n* [ttyd](https://github.com/tsl0922/ttyd) (MIT) is used to run the web terminal\n* [github.com/urfave/cli/v2](https://github.com/urfave/cli/v2) (MIT) is used to drive the CLI\n* [discord-go](https://github.com/bwmarrin/discordgo) (BSD-3) is used for the Discord communication, specifically these two\n  [these](https://github.com/bwmarrin/discordgo/pull/922) [two](https://github.com/bwmarrin/discordgo/pull/982) pull requests\n  for thread support\n* [slack-go](https://github.com/slack-go/slack) (BSD-2) is used for the Slack communication\n* [gliderlabs/ssh](https://github.com/gliderlabs/ssh) (BSD-3) is used for remote port forwarding for terminal sharing\n* [stretchr/testify](http://github.com/stretchr/testify) (MIT) is used in most of the tests \n\nCode and posts that helped:\n* [tmux sharing across hosts](https://gist.github.com/QuAzI/b6d29fd6239ed72c9c61870e7ee5ff90), thanks to [QuAzI](https://gist.github.com/QuAzI) \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinwiederhier%2Freplbot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbinwiederhier%2Freplbot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinwiederhier%2Freplbot/lists"}