A repository containing the following bots developed in Scala.
Author: https://t.me/Benkio
Step-by-step guide: Adding a new bot (template, build registration, CI token secret, and README update).
Each bot contains a resources folder. You need to put in there
the .token file containing the telegram key specific to each
bot.
Each bot also uses a SQLite Database! So you need to provide
the path to the database into the application.conf or just set
up the specific environment variables. No need to put the files
in resources folder anymore (even if it’s still potentially
possible a little code change) since those will be fetched from
the web via URLs or by Telegram Ids.
To add data to the bots you need to:
- Add the file name, Telegram
file_idand/or downloadable link (usually Dropbox), to the json at the root of each bot folder. To get thefile_id_you can take advantage of @jsonbot by just sending the file and copy the id from the reply. - Modify the scala code to add the type that creates the mappings between the triggers and the files. See planty of examples of any kind throughout the code, especially under RichardPHJBensonBot’s data package.
To edit a bot’s *_replies.json via a GUI (and auto-regenerate *_triggers.txt on save), use the Replies Editor (GUI).
sbt repliesEditorServer/runThen open http://127.0.0.1:8088/.
The old video guide below refers to a time where also the
trigger.txt as to be updated manually. Now it’s automatic.
Check this video for a complete rundown on how to add files to a bot.
Each bot now has an additional main class that takes as input a space separated list of dropbox links and allows to:
- Automatically add data to the bot’s mentioned Json based on the filename extension or name.
- Prints incomplete scala code that can be arranged mantually to add the data.
In particular it relies on the naming convention:
<botId_><filename>(Gif)?.<extension>
eg. rphjb_ViviMorti.mp4
Based on that it groups data together in the outcome scala code To facilitate the creation of data you can use the following scala-cli script. It allows to extract data from youtube and generate: audio (mp3), video (mp4) and a gif (mp4 with Gif suffix)
Example commands:
$ sbt "abarAddData url1 url2"
$ sbt "xahAddData url1 url2"
$ sbt "mosAddData url1 url2"
$ sbt "ytaiAddData url1 url2"
$ sbt "rphjbAddData url1 url2"SELECT show_title FROM show WHERE show_origin_automatic_caption LIKE '%idiot%' AND show_upload_date > strftime("%F", "2025-08-08");There’s a module called botDB, if opportunely configured,
when launched, it applies the migrations and populates a bot
database.
Just set up:
- The
application.confcorrectly with the:- DB path, see the DB in the root of the project
- Location of the
jsons. There should be ajsonfile at the root of each bot module - shows youtube sources by bot containing the:
- list of playlist id or channel handle
- bot name
- relative output path, from BotDB folder, of the shows where to save the results.
- The Youtube Api file named
youTubeApiKey.tokenwith the API key from google console placed in/modules/botDB/src/main/resources/
Several command alias are defined in the project to group together useful sbt commands:
dbSetup- Run the botDB main that set up the DB anew. Running the migrations and updating the media tables based on the JSON in the bots folders.
fix- Run the
scalafmtandscalafixin the whole project. check- Check the project for formatting and dependencies using
sbtplugins such asscalafmt. validate- compile clean and test. It includes the
fixcommand and it is run in the CI. checkAllLinksTest- Run a parallel test and checks all the
media links in the DB and can be called manually by
sbt integration/runIntegrationScalaTests. Run it once in a while (especially after a series of new additions or changes in links) to be sure everything is still reachable and up. These tests excluded from the CI because they are quite slow.
Under Windows use the git bash terminal.
./lunch.sh # I know it's lunch not launch :)First be sure you have the .token files in place. Suppose you have them in the “~/Dropbox/” folder like so:
$ fd ".*\.token" ~/Dropbox/
/home/benkio/Dropbox/sBots/ABarberoBot/src/main/resources/abar_ABarberoBot.token
/home/benkio/Dropbox/sBots/CalandroBot/src/main/resources/cala_CalandroBot.token
/home/benkio/Dropbox/sBots/M0sconiBot/src/main/resources/mos_M0sconiBot.token
/home/benkio/Dropbox/sBots/RichardPHJBensonBot/src/main/resources/rphjb_RichardPHJBensonBot.token
/home/benkio/Dropbox/sBots/XahLeeBot/src/main/resources/xah_XahLeeBot.token
/home/benkio/Dropbox/sBots/YouTuboAncheI0Bot/src/main/resources/ytai_YouTuboAncheI0Bot.tokenCopy them in the project. Suppose you have the project in “~/workspace/sBots/”, you can do it with:
$ cd ~/Dropbox/sBots/
$ find ./ -type f -name "*.token" -exec cp --parents {} ~/workspace/sBots/modules/bots \;Reference: https://www.baeldung.com/linux/copy-files-retain-dir-structure
- Export the webhook host, locally using ngrok, expose or tunnelTo. example:
./expose share http://localhost:8080 - Change the entry
WEBHOOK_HOST_URLwith the name of the host from the previous step or change it in ~~sBots/main/src/main/resources/application.conf~ - run
sbt assembly - run
java -cp main/target/scala-3.3.7/main.jar com.benkio.main.MainWebhook
TODO: There’s already a main/Dockerfile with the command to run the webhook, but still it needs to be tested and visible from outside
Also check expose on docker. In order to may make it discoverable from telegram API.
When running the webhook main (MainWebhook), the application
periodically pings an external healthcheck endpoint so you can
monitor that the service is up (e.g. healthchecks.io).
- **Where**: The healthcheck runs in the main module; one background fiber pings the configured URL on a cron schedule.
- **Config**: In
modules/main/src/main/resources/application.confundermain.healthcheck-ping:endpoint- URL to GET (e.g.
https://hc-ping.com/<your-check-uuid>). cron- Cron4s expression for how often to ping (e.g.
* */10 * ? * *for every 10 minutes).
- **Overrides**: You can override with env vars if your config
supports it; otherwise edit
application.confbefore assembly. - **Note**: Only one healthcheck fiber is started per process. If you run multiple replicas, each will ping the same endpoint on each tick.
There should be a pipeline on main, running after the other
workflows, that should deploy build, deploy and run the bots
remotely on Oracle already. Every new main commit will result in a
deployment.
- Create a VM instance in the Oracle cloud
- Get the SSH Private and Public Keys to access it
- Login to ssh VM instance by ssh private key, user, and IP. get the last two on the site. Eg command:
ssh -i <<private key of the vm>> <<user of the vm>>@<<public IP of the vm>>(ssh -i ssh-key-2022-04-26.key opc@140.238.155.16)
- Login to ssh VM instance by ssh private key, user, and IP. get the last two on the site. Eg command:
- Install the jdk 16. Follow this tutorial
If something doesn’t work, please follow this guide and update the documentation accondingly Follow these steps to set up the server property:
- Server Prerequisites
- Check this page for the prerequisites required by telegram to work with webhook. In our case, we choose port 8443 for SSL connection.
- Open Port on OCI Subnet
- The instance where the bots are running needs to have an attached VNICs(Virtual Network Interface Card) with a subnet. The subnet will have a default security list containing the rules for the ports available from outside. Add a new rule for the port required and save it. The parameters to use are:
- Stateless: No
- Source: 0.0.0.0
- IP Protocol: TCP
- Source Port Range: All
- Destination Port Range: 8443
This should allow telegram to reach your server through that port.
- Test the port is open
- by spawning a server with the command
python3 -m http.server 8443and try to open a browser tab to the server. eg http://129.152.27.196:8443/ - Generate a keystore JKS
- On the server, using the commands on this page, follow the instruction for the java keystore, pasting each command one by one. For the correct keystore password to use, check the `application.conf`. Example
$ keytool -genkey -alias sbots -keyalg RSA -keystore sbotsKeystore.jks -keysize 2048 -validity 360 Enter keystore password: Re-enter new password: Enter the distinguished name. Provide a single dot (.) to leave a sub-component empty or press ENTER to use the default value in braces. What is your first and last name? [Unknown]: 129.152.27.196 What is the name of your organizational unit? [Unknown]: What is the name of your organization? [Unknown]: What is the name of your City or Locality? [Unknown]: What is the name of your State or Province? [Unknown]: What is the two-letter country code for this unit? [Unknown]: Is CN=129.152.27.196, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct? [no]: yes Generating 2,048 bit RSA key pair and self-signed certificate (SHA384withRSA) with a validity of 360 days for: CN=129.152.27.196, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
- Convert the keystore to PEM
- following the commands in the link above. eg:
$ keytool -importkeystore -srckeystore sbotsKeystore.jks -destkeystore sbots.p12 -srcstoretype jks -deststoretype pkcs12 Importing keystore sbotsKeystore.jks to sbots.p12... Enter destination keystore password: Re-enter new password: Enter source keystore password: Entry for alias sbots successfully imported. Import command completed: 1 entries successfully imported, 0 entries failed or cancelled $ openssl pkcs12 -in sbots.p12 -out sbotsCertificatePub.pem -nokeys
- Set the
main/src/resources/application.confaccordingly:webhook-base-urlashttps://<serverip>:<outsideport>, eghttps://129.152.27.196:8443host-urlas0.0.0.0portas<internalPort>in our case8443webhook-certificatewith the path of the public certificate, egsbotsCertificatePub.pemkeystore-pathadd the path to the keystore, egsbotsKeystore.jkskeystore-passwordadd the password of the keystore, egsbotsKeystorePassword
- Run
sbt "clean; main/assembly"to create the fat jar - Move the fat jar to the VM by
rsyncandssh. Eg.rsync -P -e "ssh -i <<private key of the vm>>" <<path to the fat jar -> sBots/main/target/scala-3.3.7/main.jar>> <<user of the vm>>@<<public IP of the vm>>:/home/<<user of the vm>>/main.jar(rsync -P -e "ssh -i ubuntu_rsa.pem" /home/benkio/workspace/sBots/main/target/scala-3.3.7/main.jar ubuntu@129.152.27.196:/home/ubuntu/bots/main.jar) - Move the
botDB.sqliteif not present in the same way before. If an update to themedianeeds to be done, better to dump the current database in order not to lose thetimeout,subscription, or other changes in the process. No easy way to migrate the database as of now. - Login to the VM
- OPTIONAL: be sure to have the right environment variables. IT’S RECOMMENDED TO
CHANGE the
application.conf(point 1) before running theassembly. The environment variables could lose their value somehow. - Run the bots.
- Polling:
java -Xmx512m -Xms512m -cp main.jar com.benkio.main.MainPolling - Webhook:
java -Xmx512m -Xms512m -cp main.jar com.benkio.main.MainWebhook
- Polling:
- press
Ctrl+Z, runbganddisownin order to let previous command run in background - close your terminal and enjoy
