Telegram bot for scheduling meetings and events directly from Telegram.
Works best on smartphones.
Message @thetoodlebot to get started!
Follow these steps to deploy an instance of ToodleBot to a Uberspace.
- Go to uberspace.de and register for a new space.
username
is your Uberspace username,hostname
is the name of the server that the space runs on. - Add an SSH key under Logins in the dashboard.
- (Optional) Add a custom domain:
ssh <username>@<hostname> "uberspace web domain add isabell.example"
- (Optional) Update the DNS records with the IP adresses given from the previous command.
- Create a Telegram bot with BotFather and set its domain to the Uberspace domain or your custom domain.
- Configure the backend:
ssh <username>@<hostname> "uberspace web backend set <your-domain> --http --port 8088"
- Get the executable (or run
./gradlew build
to obtain the.jar
and copy that over to the server):ssh <username>@<hostname> "wget https://github.com/torond/toodlebot/releases/download/0.1.2/toodlebot-0.1.2.jar"
- Add config file:
ssh <username>@<hostname> "echo \"domain=https://<domain of server> port=8088 bot_username=<name of the Telegram bot without @> bot_token=<token of the Telegram bot>\" > environment.properties"
- Create data folder in home directory (todo: should be done by app itself):
ssh <username>@<hostname> "mkdir data"
- Add
supervisord
script and run the app.directory
change is needed so the app can accessenvironment.properties
.ssh <username>@<hostname> "echo \"[program:toodlebot] directory=/home/<username> command=java -jar toodlebot-0.1.2.jar startsecs=20 autostart=false\" > ~/etc/services.d/toodlebot.ini supervisorctl reread supervisorctl update supervisorctl start toodlebot"
The bot should now respond to /start
and you should be able to create Toodles.
Follow these steps if you want to set up an instance for yourself.
Create a file environment.properties
to the repository root with the following contents:
domain=<Local ip address of the machine the application is running on e.g. http://123.456.789.000>
port=<port the app should run on e.g. 8088>
bot_username=<Name of the Telegram bot (without @) e.g. thetoodlebot>
bot_token=<Token of the Telegram bot>
Use /setdomain
in BotFather to enable Login URL.
For development purposes, this should be the same as the ip in host
above (e.g. 123.456.789.000
).
For more information on the data flow between users, server and bot see the Data Flow section.
After V1.1 this project will probably go into maintenance-only mode.
If you want to contribute or have any questions, hit me up on Twitter :)
Some guidelines (subject to change):
- Follow the principle of least astonishment.
For
DataBaseService
: - Mention parameters (e.g.
byDoodleId
) in method names, but not in add methods - Mention IDs always with corresponding Table (
doodleId
instead ofuuid
) - No
EntityId<...>
or other IDs in Server.kt, except doodleId
A more detailed look at how this app works internally.
- A Doodle Creator acts as a Doodles admin. Note that a Doodles creator can also participate in it. There can only be one admin per Doodle.
- The Telegram Bot is the mediator between Client, Doodle Server and Group Chat. It does not contain any logic for the Doodle as this is the backends task.
- The Doodle Server contains business logic. It generates Doodle pages and manages user data.
- A Telegram Group is the place where a created Doodle is shared. Note that Doodles can be shared to more than one group.
- A Doodle Participant can answer given Doodles. Obviously there can be many participants.
- On all endpoints users are authenticated via their (hashed) Telegram data. Only the Doodle creator is authorized to edit and close the Doodle.
- Not shown in the diagram is that as long as the Doodle is open, "Create Doodle" and "Answer Doodle" can be accessed multiple times to change the proposed dates and answers.
Diagram code:
sequenceDiagram
autonumber
participant C as Doodle Creator<br><br>(Telegram Client)
participant B as Telegram Bot
participant W as Doodle Server
participant G as Telegram Group
participant P as Doodle Participant<br><br>(Telegram Client)
C ->> B: /start command (private chat)
B ->> C: Sends static link backend.com/setup<br>"Create Doodle" button
C ->> W: Clicks "Create Doodle"<br>(Telegram login data is sent and session is created)<br>[GET /setup]
W ->> C: Serves Setup-Doodle website
C ->> C: Picks initial dates
C ->> W: Confirms & sends picked dates<br>[POST /setup]
W ->> W: Persists Doodle and creates crypto links
W ->> B: Sends links t.me/<bot-username>?startgroup=<UUID><br> and backend.com/close/<UUID>
B ->> C: Sends links<br>"Share Doodle" and "Close Doodle" buttons
alt Sharing
C ->> G: Clicks "Share Doodle" and picks group chat
G ->> B: Sends /start <UUID> command
B ->> G: Sends link backend.com/answer/<UUID><br>'Answer Doodle' button
G ->> P: Forwards button to group members
loop For each participant
P ->> W: Clicks "Answer Doodle"<br>(Telegram login data is sent and session is created)<br>[GET /answer]
W ->> P: Servers Answer-Doodle
P ->> P: Picks dates
P ->> W: Confirms & sends picked dates<br>[POST /answer]
W ->> W: Persists answer
end
else Closing
C ->> W: Clicks "Close Doodle"<br>[GET /close/<UUID>]
W ->> C: Serves Closing-Doodle
C ->> C: Picks final dates
C ->> W: Confirms & sends final dates<br>[POST /close/<UUID>]
W ->> W: Marks Doodle as closed and sets auto-delete timer
W ->> B: Sends link backend.com/view/<UUID>
B ->> G: Sends link<br>"View Doodle" button
G ->> P: Forwards button to group members
P ->> W: Clicks "View Doodle"<br>[GET /view/<UUID>]
W ->> P: Serves View-Doodle
end