Skip to content

OleksiyRudenko/jsconsole-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JS Console Telegram Bot

JS Console Bot can be connected to a chat. It listens to messages, executes the code, and responds with the latest statement result.

Examples:

Request:

/js 6+1

Response:

> 6+1
7

Request:

/js const a = [1,2,3];
a.map(item => item * 2)

Response:

> const a = [1,2,3];
> a.map(item => item * 2);
[2, 4, 6]

jsconsole-bot screenshot

The code is considered to be an untrusted user input and executed in a jail. The app is stateless, which means each code snippet is executed in isolation from past sessions.

Original bot is named jsconsole and available as @okjs_bot. You may also add it to any group chat.

Table of Contents

Requirements Addressed

As a user I want to

  • submit a code snippet so I can get the result output immediately
  • have result output neatly formatted

As a service owner I want to

  • restrict the resource used to run user code snippets so everyone can benefit from free hosting tier.
  • safely process untrusted user input
  • benefit from NodeJS hosting free tier
  • benefit from simple app deployment

Restrictions

The following restrictions are applied:

  • source code length
  • execution time
  • restricted native API:
    • setTimeout, require, setInterval, setTimeout, setImmediate are unavailable

See config.js and vm2/VM docs for details.

Setup

This app is developed to run on vercel platform.

Installation workflow:

  1. Install tools and dependencies
  2. Register the bot and store Telegram API access token
  3. Deploy bot as a lambda on vercel
  4. Register bot webhook with Telegram

The below instructions are valid as of February 23, 2021

Install tools and dependencies

You are expected to have the following installed:

  • NodeJS and npm. NodeJS v12.13.0 is recommended (vercel hosting uses NodeJS v10.x, v12.x, v14.x)
  • yarn package manager
Note on NodeJS

It is recommended to use nvm or nvm for Windows to manage NodeJS versions.

Under Windows open cmd.exe or PowerShell as administrator to use nvm.

Set up account on vercel. Integration with GitHub is optional.

./setup.sh install will install dependencies and vercel CLI

You may need sudo installation.

Once vercel CLI is installed it is recommended to login from your current device (normally it is done once for all projects supported with vercel).

./setup.sh login <your_email_associated_with_vercel_account>

Register your bot

Register your bot with BotFather and take a note of API access token.

Store your token with vercel secrets storage.

.setup.sh save_token <telegram_api_token>

Now your token is securely stored and will be

  • available at every device you have logged into vercel from
  • supplied by vercel to the app at app execution as an env variable

You may list stored secrets with vercel secrets ls. You will not be able to retrieve the raw content of your secrets. However, you always can consult BotFather to retrieve the token.

It is recommended that you store all secrets like credentials, access tokens etc with the secrets storage, not as some plain text in your code base.

First deployment

./setup.sh deploy

Take a note of the complete url of your end-point alias. Example: https://jsconsole-bot-your-vercel-username.vercel.app

Register the bot web hook with Telegram

Telegram needs to know where to send messages addressed to your bot.

This end-point is called a web hook.

./setup.sh set_webhook <your_project_url.vercel.app> <telegram_api_token>

You're done!

You may want change something in your bot code. Once you're ready to deploy just run vercel.

Your projects are accessible via dashboard. Each project lists all deployments. You may want to delete obsolete deployments. You will also find logs useful.

Developer's notes

Project structure

-\
 |-- api                   ## app code base
 |   |-- config.js         ## app config
 |   |-- jsconsole-bot.js  ## entry point / lambda function
 |   \-- sandbox.js        ## sandbox
 |
 |-- assets
 |   |-- jsconsole-bot.jpg    ## illustration
 |   \-- logo-JS-console.png  ## image used as bot's avatar in Telegram
 |
 |-- www                     ## web presentation
 |   |-- default-beauty.css  ## basic styling
 |   \-- index.html          ## default index.html
 |
 |-- .gitignore
 |-- .vercelignore    ## files to be ignore by vercel
 |-- LICENSE.md
 |-- vercel.json      ## deployment setup
 |-- package.json  ## project properties
 |-- README.md
 |-- setup.sh      ## setup script
 \-- yarn.lock

App code base

jsconsole-bot.js

vercel requires app entry points to export functions that are ready to serve network requests. Since Telegram API sends messages via POST and POST request body is not available synchronously the function exported is async and micro is employed to process the request properly.

vercel examples demonstrate GET requests processing, which are synchronous.

  • jsConsoleBot (exported) - an async function to serve requests
  • emulateConsoleInput - a method to echo user input emulating console input; in bigger chats it may happen that some users may post before bot responds so echoing is helpful
  • sendMessage - a method to send response using Telegram API

sandbox.js

  • executeInASandbox (exported) - executes validated source code in a jail; uses vm2
  • validate - validates source code against custom restrictions
  • stringify - produces neatly formatted result output; uses stringify-object by yeoman

The project uses is tested under NodeJS v12.13.0 that is one of NodeJS versions used by vercel as of writing this docs.

NodeJS versions between 8.x and 12.x may cause issues with output.

config.js

  • telegramApiUrl - Telegram API v5.0 url to send responses back to client; used in jsconsole-bot.js
  • sandBoxRestrictions - custom user code restrictions; used in sandbox.js
  • sandBoxConfig - sandbox config; used in sandbox.js

Web presentation

These files are served whenever a user access the app via browser at app domain root.

App deployment setup

.vercelignore

Files that shouldn't be uploaded to vercel. Normally those are files that aren't required to build a project and aren't used in production. Syntax is similar to that of .gitignore.

vercel.json

vercel deployment configuration.

NB! Current config uses legacy configuration approaches. Should be upgraded to match the approach as documented under the link above.

  • version - platform version (legacy)
  • name - project name (legacy)
  • builds - project build settings, defining e.g. which files are static and should be served as is, and which should be processed by NodeJS before deployment (legacy)
  • routes - routing rules, defining e.g. what file to serve when a web user accesses project root and how a web hook (access point url) maps to a lambda (legacy)
  • env - env variables, accessible via process.env object; when value starts with @ the real value is taken from vercel secrets storage (legacy)

package.json

Note how main property points at your primary lambda function. It might be also an index.js that sets up a local server for local tests.

setup.sh

A script used to set the project up.

Credits

Telegram botification is inspired by How to build a telegram bot using Node.js and Now [2018-10-19] and How to make a responsive telegram bot [2016-09-21].