Skip to content

Commit

Permalink
Telegram bot initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
npanuhin committed Dec 9, 2024
1 parent 366737f commit 708c92c
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,6 @@ __pycache__/
/build/
cmake-build-debug/
/Testing/

# Telegram bot token
/scripts/token.txt
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ cmake -DCMAKE_BUILD_TYPE=Release -S . -B build
cmake --build build --parallel
```

## Running
## Running (CLI)

Running the project consists of three steps:

Expand Down Expand Up @@ -73,6 +73,16 @@ Running the project consists of three steps:
Fri Mar 20 03:11:00 2020 - Fri Mar 20 04:09:00 2020
```

## Telegram bot

To run the Telegram bot, you need to create a `.token` file in the `telegram` folder and put your Telegram bot token there.

After that, you can run the bot:
```bash
python3 telegram/bot.py
```


## Testing

Tests are [automatically run by GitHub Actions](../../actions). To run them locally:
Expand Down
2 changes: 1 addition & 1 deletion models/src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ QTextStream& operator<<(QTextStream& os, const Journey &journey) {
os << "\n";
os << routeTypeNames[ride.route->type] << " " << ride.route->name << "\n";
os << (*ride.firstStop)->name << " -> " << (*ride.lastStop)->name << "\n";
os << ride.startTime() << " - " << ride.endTime() << "\n";
os << ride.startTime() << " " << ride.endTime() << "\n";
} else {
auto &transfer = std::get<Transfer>(journeyElement);
os << "\n";
Expand Down
124 changes: 124 additions & 0 deletions scripts/bot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import subprocess
import telebot
import os

from src.utils import mkpath_root


EXEC = mkpath_root('build/sdt-navigator')


with open(mkpath_root('scripts/token.txt')) as file:
tg_token = file.read().strip()

bot = telebot.TeleBot(tg_token)

SELECTED_DATASET = {} # {user_id: dataset_name}


def run_command(dataset: str, command: str) -> str:
print(f'Running command: {command}')
result = ""

try:
executable = [EXEC, dataset]
# print(f'Running executable: {executable}')
process = subprocess.Popen(
executable,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)

# print('Waiting for response')
stdout, stderr = process.communicate(command, timeout=10)
# print('Response received')

if process.returncode == 0:
result = stdout.split('[sdt-navigator]$')[1].strip()
else:
result = f'Error occurred: {stderr}'

process.kill()

except Exception as e:
result = f'Error occurred: {e}'

return result


@bot.message_handler(commands=['start'])
def start_message(message):
bot.send_message(
message.chat.id,
'Please select a dataset using /select command (e.g., `/select gtfs_hamburg`)',
parse_mode='Markdown'
)


@bot.message_handler(commands=['select'])
def select_dataset(message):
user_input = message.text.strip().removeprefix('/select').strip()

if not user_input:
return start_message(message)

if not os.path.isdir(mkpath_root(f'data/{user_input}')):
bot.send_message(
message.chat.id,
'Dataset was not found. Please try again',
)
return start_message(message)

SELECTED_DATASET[message.chat.id] = user_input
bot.send_message(
message.chat.id,
f'Dataset \"{user_input}\" selected! You can now use /route or /search like this:'
)
bot.send_message(
message.chat.id,
f'```\n'
f'/route --start \"Bremen Hbf\" --end \"Hamburg Airport (Flughafen)\" --date 2020-03-20 --time 06:00\n'
f'/search Bremen\n'
f'```',
parse_mode='Markdown'
)


@bot.message_handler(commands=['route'])
def route_command(message):
if message.chat.id not in SELECTED_DATASET:
return start_message(message)

user_input = message.text.strip().removeprefix('/')

bot.send_message(
message.chat.id,
run_command(SELECTED_DATASET[message.chat.id], user_input)
)


@bot.message_handler(commands=['search'])
def search_command(message):
if message.chat.id not in SELECTED_DATASET:
return start_message(message)

user_input = message.text.strip().removeprefix('/')

bot.send_message(
message.chat.id,
run_command(SELECTED_DATASET[message.chat.id], user_input)
)


@bot.message_handler(func=lambda message: True)
def handle_input(message):
bot.send_message(
message.chat.id,
'Please use commands: /select, /route, /search'
)


print('Starting Telegram Bot...')
bot.polling()
2 changes: 1 addition & 1 deletion scripts/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

assert sys.version_info >= (3, 11), f'Python 3.11 or later required, got {".".join(map(str, sys.version_info))}'

from src.utils import mkpath_root
from src.convert_transfers import convert_transfers
from src.convert_stations import convert_stations
from src.convert_trips import convert_trips
from txt_to_csv import txt_to_csv
from src.utils import mkpath_root


# ====================================================== Settings ======================================================
Expand Down
1 change: 1 addition & 0 deletions scripts/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
orjson~=3.10.12
pandas~=2.2.3
pysimdjson~=6.0.2
pyTelegramBotAPI~=4.25.0
6 changes: 6 additions & 0 deletions scripts/src/bot_commands.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/select - Select a dataset
/route - Input a route query to find the best route between two stations
/search - Search a station by it's approximate name


route --start "Bremen Hbf" --end "Hamburg Airport (Flughafen)" --date 2020-03-20 --time 06:00

0 comments on commit 708c92c

Please sign in to comment.