Giter VIP home page Giter VIP logo

replbot's Introduction

๐Ÿค– REPLbot

Release Go Reference Tests Go Report Card codecov Slack channel

REPLbot is a bot for Slack and Discord that allows you to control a REPL or 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 & Fedora), but you can easily make or bring your own.

replbot demo

Why ...?

I thought it might be a fun way to collaboratively dabble with a REPL in a team. Yes, I could have gone for a terminal in a browser, but there's nothing like having it right there in Slack. Mainly I did it because it was fun though. ๐Ÿ˜„

How it works

I use tmux and the tmux capture-pane command to run most of the show. It's simple, but effective. In the first iteration I tried using a pseudo terminal (pty) directly, but with all the escape sequences and commands, it was getting kinda tiresome, and I was spending time with stuff that I didn't want to spend time with (though I learned a lot!). And tmux does its job so well.

The actual REPLs are just simple scripts (see script.d folder), so they could be anything you like. I highly recommend using Docker to provide somewhat of an isolation, though you'll probably still need to trust the people using the bot if you give them an entire REPL.

Screenshots & Videos

Scala, split mode (Discord) Ubuntu running `htop` (Discord) C++, channel mode (Discord)
Blinking cursors, choo choo ๐Ÿš‚ (Slack) Custom shells, multiple sessions (Slack)

Usage

After installing REPLbot, you may use it by tagging @replbot in Slack/Discord. For the most part it should be pretty self-explanatory:

replbot mention

To start a session with the default settings, simply say @replbot java to start a Java REPL. There are a few advanced arguments you can use when starting a session.

REPL scripts

REPLbot can run more or less arbitrary scripts and interact with them -- they don't really have to be REPLs. Any interactive script is perfectly fine, whether it's a REPL or a Shell or even a game. By default, REPLbot ships with a few REPLs. To extend the REPLs you can run, simple add more scripts in the script-dir folder (see config.yml).

Here's a super simple example script:

#!/bin/sh
# Scripts are executed as "./script run <id>" to start the REPL, and as "./script kill <id>"
# to stop it. Not all scripts need the "kill" behavior, if they exit properly on SIGTERM.
case "$1" in
  run)
    while true; do
      echo -n "Enter name: "
      read name
      echo "Hello $name!"
    done 
    ;;
  *) ;;
esac

In all likelihood, you'll want more isolation by running REPLs as Docker containers. Here's the PHP REPL script that REPLbot ships with (not shortened):

#!/bin/sh
# REPLbot script to run a PHP REPL.
#
# Scripts are executed as "./script run <id>" to start the REPL,
# and as "./script kill <id>" to stop it.

DIR="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 && pwd -P)"
case "$1" in
  run) docker run --rm --name "$2" -it php ;;
  kill) "$DIR"/helpers/docker-kill "$2" ;;
  *) echo "Syntax: $0 (run|kill) ID"; exit 1 ;;
esac

Session commands

When a session is started, you can get a list of available commands by typing !help (or !h). To exit a session at any point in time, type !exit (or !q).

replbot session help

Recording sessions

Sessions can be recorded using asciinema, and can even be automatically uploaded to either asciinema.org or your private asciinema-server (see install instructions).

After a session exits, the recording is then attached to chat as a ZIP file and optionally as a link to the asciinema server. This behavior can be controlled by the default-record and upload-recording option in the config.yml file, as well as the record/norecord option when starting a session.

Here's the asciinema.org link of the example I recorded, as well as the ZIP archive with the recording.

replbot session recording

Web terminal

Entering commands via Slack or Discord can be quite cumbersome, so REPLbot provides a web-based terminal (powered by the amazingly awesome ttyd). If enabled, a unique link is created for each session, which provides a read-only or writable web terminal.

replbot web terminal

This behavior can be controlled by the default-web option in the config.yml file, as well as the web/noweb option when starting a session. While a session is running, it can be toggled using the !web command.

replbot web terminal

Terminal sharing

You can share your local terminal window in Slack or Discord using the share feature. It's quite cool, although it's really got nothing to do with REPLs ๐Ÿคท. It also has to be specifically configured in the config.yml file using the share-host option, since it needs direct communication between the client and REPLbot.

replbot terminal sharing

Control mode

You can specify if you want the session to be started in the main channel (channel), in a thread (thread), or in split mode (split) using both channel and thread. Split mode is the default because it is the cleanest to use: it'll use a thread for command input and the main channel to display the terminal.

replbot split mode

Terminal size

You can set the terminal window size when you start a session by using the keywords tiny (60x15), small (80x24), medium (100x30), and large (120x38). The default is small. You may also resize the terminal while the session is running using the !resize command.

replbot window size

Window mode

When starting a session, you can choose whether to trim empty space from the terminal session (trim), or whether to show the entire terminal window as it would appear in a terminal emulator (full). The default is full, as trim mode can get awkward when the terminal is expanded and the collapsed again.

replbot window mode

Installation

Please check out the releases page for binaries and deb/rpm packages.

Requirements:

  • A modern-ish Linux, preferably Ubuntu 18.04+, since that's what I develop on -- though it also runs on other distros.
  • tmux >= 2.6 is required, which is part of Ubuntu 18.04 (but surprisingly not part of Amazon Linux!)
  • docker for almost all scripts REPLbot ships with
  • asciinema if you'd like to record sessions
  • ttyd if you'd like to use the web terminal feature

Creating a REPLbot Slack app:
REPLbot requires a Slack "Classic App (bot)", because of its use of the real time messaging (RTM) API. To create a classic app and acquire a Slack bot token, follow these steps:

  1. Create a classic Slack app
  2. In the "App Home" section, add a "Legacy bot user"
  3. In the "OAuth & Permissions" section, click "Install to Workspace" (this may require workspace admin approval)
  4. Copy the "Bot User OAuth Token" starting with "xoxb-..."

Creating a REPLbot Discord app:

  1. Create a Discord app
  2. In the "Bot" section, click "Add Bot" and disable "Public Bot"
  3. In the "OAuth2" section, click "Add Redirect" and type a URL (even https://google.com is fine), select the scopes "bot" and "messages.read", and the permissions "public threads", "private thread", "send messages", "manage messages", "manage threads". Click "Save changes".
  4. Copy the OAuth2 URL and navigate to it in the browser and authorize the app.
  5. In the "Bot" section, copy the token and paste it here

Installing replbot:

  1. Make sure tmux and probably also docker are installed. Then install REPLbot using any of the methods below.
  2. 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.
  3. Review the scripts in /etc/replbot/script.d, and make sure that you have Docker installed if you'd like to use them.
  4. 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.
  5. Then just run it with replbot (or systemctl start replbot when using the deb/rpm).

Binaries and packages

Debian/Ubuntu (from a repository):

curl -sSL https://archive.heckel.io/apt/pubkey.txt | sudo apt-key add -
sudo apt install apt-transport-https
sudo sh -c "echo 'deb [arch=amd64] https://archive.heckel.io/apt debian main' > /etc/apt/sources.list.d/archive.heckel.io.list"  
sudo apt update
sudo apt install replbot asciinema

Debian/Ubuntu (manual install):

sudo apt install tmux
wget https://github.com/binwiederhier/replbot/releases/download/v0.6.4/replbot_0.6.4_amd64.deb
dpkg -i replbot_0.6.4_amd64.deb

Fedora/RHEL/CentOS:

# Make sure that "tmux" is installed
rpm -ivh https://github.com/binwiederhier/replbot/releases/download/v0.6.4/replbot_0.6.4_amd64.rpm

Docker:
You can configure the Docker image by mounting a config directory (containing config.yml) to /etc/replbot. To be able to use most of the pre-packaged script.d REPLs (to be mounted to /etc/replbot/script.d), you'll need to give the REPLbot image access to the Docker socket file. This allows the container to spin up other containers on the host. This is a security risk and considered bad practice, but it's the only way.

# Config and scripts live on the host
wget https://github.com/binwiederhier/replbot/archive/refs/tags/v0.6.4.tar.gz
tar zxvf v0.6.4.tar.gz
sudo mkdir /etc/replbot
sudo cp -a replbot-0.6.4/config/{script.d,config.yml} /etc/replbot
vi /etc/replbot/config.yml
  # Configure at least "bot-token"
  # To support web terminal, set "web-host" (e.g. to localhost:31001)
  # To support sharing, set "share-host" (e.g. to localhost:31002)
  
# Then you can start the REPLbot docker image (assuming web-host listening
# at 31001 and share-host at 31002)
docker run --rm -it \
  -v /etc/replbot:/etc/replbot \
  -v ~/.asciinema:/root/.config/asciinema \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -p 31001:31001 \
  -p 31002:31002 \
  binwiederhier/replbot

Please note that if you'd like to associate the asciinema videos to an account, you need to set up and map the config directory properly. For me, that worked by installing it on the host, running asciinema rec once and then associating the install-id located in ~/.asciinema/install-id. Inside the docker image, asciinema expects the config directory to be in ~/.config/asciinema.

Go:

# Be sure "tmux" is installed
go get -u heckel.io/replbot

Manual install (any x86_64-based Linux):

# Make sure that "tmux" is installed
wget https://github.com/binwiederhier/replbot/releases/download/v0.6.4/replbot_0.6.4_linux_x86_64.tar.gz
sudo tar -C /usr/bin -zxf replbot_0.6.4_linux_x86_64.tar.gz replbot

Building

Building replbot is simple. Here's how you do it:

make build-simple
# Builds to dist/replbot_linux_amd64/replbot

To build releases, I use GoReleaser. If you have that installed, you can run make build or make build-snapshot.

Contributing

I welcome any and all contributions. Just create a PR or an issue, or talk to me on Slack.

License

Made with โค๏ธ by Philipp C. Heckel, distributed under the Apache License 2.0.

Third party tools/libraries:

  • tmux (ISC) is used to run most of the show
  • docker is used for almost all scripts REPLbot ships with
  • asciinema (GPLv3) is used to record sessions
  • ttyd (MIT) is used to run the web terminal
  • github.com/urfave/cli/v2 (MIT) is used to drive the CLI
  • discord-go (BSD-3) is used for the Discord communication, specifically these two these two pull requests for thread support
  • slack-go (BSD-2) is used for the Slack communication
  • gliderlabs/ssh (BSD-3) is used for remote port forwarding for terminal sharing
  • stretchr/testify (MIT) is used in most of the tests

Code and posts that helped:

replbot's People

Contributors

binwiederhier avatar mamercad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

replbot's Issues

Share your own terminal

This works, but is cumbersome for the user:

ssh -N -R 10000:localhost:22 [email protected]
ssh -t pheckel@localhost -p 10000 tmux a
  • Could add SSH server to replbot
  • Can we redirect traffic directly to tmux server instead of going through ssh server on the local side?

REPLbot no longer works on Discord

Tried to spin up REPLbot for another Discord server today and can't seem to get it to work. I've tried with both normal permissions + administrator permissions on the bot as well as the role in the server. In servers, it doesn't seem to send any messages at all when mentioned. It does reply in DMs, but is unable to recognize any commands. Screenshot attached.
Screenshot 2022-08-29 004706

Failed to start tmux

Ran into another tmux issue with the latest Docker image for REPLbot, however I don't think this one is related to the scripts being in DOS format ๐Ÿ˜„

This is a brand new VM running Ubuntu 20.04.3 LTS, latest version of tmux and Docker.

root@replbot01:~# docker run --rm -it \
>   -v /etc/replbot:/etc/replbot \
>   -v /var/run/docker.sock:/var/run/docker.sock \
>   binwiederhier/replbot
Unable to find image 'binwiederhier/replbot:latest' locally
latest: Pulling from binwiederhier/replbot
ba3557a56b15: Pull complete
94caa5d1da70: Pull complete
a10a29983da5: Pull complete
3d6ccddb7fa4: Pull complete
ed1bef566495: Pull complete
201a9d1142eb: Pull complete
0806b78d1f4d: Pull complete
2987e14e0ec7: Pull complete
b6e074b08920: Pull complete
Digest: sha256:5766d1634030f8bda85441f471a0a5f566bf24acba515c9373ba50d3ae04cccd
Status: Downloaded newer image for binwiederhier/replbot:latest
2021/10/02 21:32:03 Discord connected as user REPLbot/880575037789323355
2021/10/02 22:03:43 [773039894888579092_893981604693831710] Starting session, requested by 451095196118024202
2021/10/02 22:03:43 [773039894888579092_893981604693831710] Started REPL session
2021/10/02 22:03:43 [773039894888579092_893981604693831710] Failed to start tmux: command failed: fork/exec /tmp/replbot_773039894888579092_893981604693831710.tmux.script: no such file or directory
command: /tmp/replbot_773039894888579092_893981604693831710.tmux.script
command output:
2021/10/02 22:03:43 [773039894888579092_893981604693831710] Closed REPL session
2021/10/02 22:03:43 [773039894888579092_893981604693831710] Session exited with error: command failed: fork/exec /tmp/replbot_773039894888579092_893981604693831710.tmux.script: no such file or directory

Let me know if you need any other info! I'll try to dig into this more later when I have some time.

Web terminal not working

โฏ sudo grep ^web-add /etc/replbot/config.yml
web-address: [redacted]:[redacted]

โฏ ttyd -h 2>&1 | head -1
ttyd is a tool for sharing terminal over the web

โฏ which ttyd
/usr/local/bin/ttyd

image

Also, it looks like it's completely missing from the Slack message http:///uQURnJBV2C.

(Discord) Delete thread on exit

It creates a fair bit of noise when it doesn't delete the threads when the session is over.

An option in config.yaml to enable/disable deletion would be a nice companion.

Failed to start tmux, installed via rpm

I tried to start up a repl but it immediately failed with the following log output:

Started replbot server.
Slack connected as user replbot/U02F6EQ62VD
[session C5UPSCFP1_1632527569_060800] Starting session
[session C5UPSCFP1_1632527569_060800] Started REPL session
[session C5UPSCFP1_1632527569_060800] Failed to start tmux: exit status 1
[session C5UPSCFP1_1632527569_060800] Closed REPL session
[session C5UPSCFP1_1632527569_060800] Session exited with error: exit status 1

But when I switch user to the replbot user I'm able to start a tmux session without issue. I don't think this is related to #35, as I'm using the default set of scripts that came installed with the RPM package. I also double-checked the python repl that I used to try it out and it had regular unix line endings.

Thanks so much for the project! I'm looking forward to playing with it. Right now I'm using it to learn about AWS CDK. I'm hoping to make a reusable stack that anyone can use to stand up a replbot server on an ec2 machine.

Failed to start tmux using Docker

Using the latest Docker image, replbot seems to be unable to start tmux. Also using the latest config and script.d files. I haven't had much time to look into this yet and have not tested using replbot straight from Go or with a direct install, but figured I'd at least document it here. I am using the latest version of Docker and the host is Ubuntu 20.04.3. Let me know if I can provide any more info!

root@localhost:~# docker run --rm -it \
>   -v /etc/replbot:/etc/replbot \
>   -v /var/run/docker.sock:/var/run/docker.sock \
>   binwiederhier/replbot
Unable to find image 'binwiederhier/replbot:latest' locally
latest: Pulling from binwiederhier/replbot
ba3557a56b15: Pull complete 
94caa5d1da70: Pull complete 
a10a29983da5: Pull complete 
3d6ccddb7fa4: Pull complete 
ed1bef566495: Pull complete 
201a9d1142eb: Pull complete 
0806b78d1f4d: Pull complete 
2987e14e0ec7: Pull complete 
cf93861db271: Pull complete 
Digest: sha256:cc83a8a0613674a70b25d7bf7a23a536b2183a0eed47845f54456696f88f388e
Status: Downloaded newer image for binwiederhier/replbot:latest
2021/09/22 17:52:10 Discord connected as user REPLbot
2021/09/22 17:52:14 [773039894888579092_890294434044993566] Starting session, requested by axite
2021/09/22 17:52:14 [773039894888579092_890294434044993566] Started REPL session
2021/09/22 17:52:14 [773039894888579092_890294434044993566] Failed to start tmux: exit status 1
2021/09/22 17:52:14 [773039894888579092_890294434044993566] Closed REPL session
2021/09/22 17:52:14 [773039894888579092_890294434044993566] Session exited with error: exit status 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.