-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 15db1b5
Showing
21 changed files
with
1,942 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.venv | ||
.vscode | ||
**/__pycache__ | ||
manage.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# vscode settings | ||
.vscode | ||
|
||
# python venv and pycache | ||
.venv | ||
__pycache__ | ||
|
||
# media (for saving repo space) | ||
src/data/media/pics/* | ||
src/data/media/videos/* | ||
|
||
# sensitive data | ||
src/data/bot.session |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
repos: | ||
- repo: https://github.com/pre-commit/pre-commit-hooks | ||
rev: v4.6.0 | ||
hooks: | ||
- id: check-added-large-files | ||
args: | ||
- --maxkb=500 | ||
- id: check-case-conflict | ||
- id: check-docstring-first | ||
- id: check-json | ||
- id: check-toml | ||
- id: check-yaml | ||
- id: end-of-file-fixer | ||
- id: mixed-line-ending | ||
args: | ||
- --fix=lf | ||
- id: trailing-whitespace | ||
|
||
- repo: https://github.com/pycqa/isort | ||
rev: 5.13.2 | ||
hooks: | ||
- id: isort | ||
files: ".*" | ||
args: | ||
- --profile=black | ||
- --project=telegram-auto-texter | ||
|
||
- repo: https://github.com/pre-commit/mirrors-mypy | ||
rev: v1.11.2 | ||
hooks: | ||
- id: mypy | ||
files: ".*" | ||
additional_dependencies: | ||
- types-pyyaml | ||
|
||
- repo: https://github.com/pycqa/pydocstyle | ||
rev: 6.3.0 | ||
hooks: | ||
- id: pydocstyle | ||
args: | ||
- --convention=google | ||
exclude: "docs|tests" | ||
|
||
- repo: https://github.com/asottile/pyupgrade | ||
rev: v3.17.0 | ||
hooks: | ||
- id: pyupgrade | ||
args: | ||
- --py310-plus | ||
|
||
- repo: https://github.com/astral-sh/ruff-pre-commit | ||
rev: v0.6.8 | ||
hooks: | ||
- id: ruff | ||
args: | ||
- --fix | ||
- --exit-non-zero-on-fix | ||
- --show-fixes | ||
- --line-length=100 | ||
- id: ruff-format | ||
args: | ||
- --line-length=100 | ||
|
||
- repo: https://github.com/adrienverge/yamllint.git | ||
rev: v1.35.1 | ||
hooks: | ||
- id: yamllint | ||
exclude: "tests" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[Telegram] | ||
api_id = API_ID | ||
api_hash = API_HASH |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
FROM ubuntu:22.04 | ||
|
||
ENV DEBIAN_FRONTEND=noninteractive \ | ||
TZ="Europe/Stockholm" | ||
|
||
RUN apt-get update && \ | ||
apt-get install -y --no-install-recommends \ | ||
python3 \ | ||
python3-pip \ | ||
tzdata && \ | ||
apt-get clean && \ | ||
rm -rf /var/lib/apt/lists/* | ||
|
||
WORKDIR /telegram-auto-texter | ||
ADD . . | ||
RUN pip install -r requirements.txt | ||
CMD ["python3", "-u", "main.py"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2024 Jose A. Romero | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
"""This module serves as the main entry point for the Telegram bot application. | ||
It handles the initialization of the bot, sets up scheduled tasks for sending messages and media, | ||
and manages user interactions. The module integrates with the worker functions to perform various | ||
tasks such as sending greetings, media items, and reminders, while utilizing the APScheduler for | ||
task scheduling. | ||
""" | ||
|
||
import asyncio | ||
from configparser import ConfigParser, ExtendedInterpolation | ||
|
||
from apscheduler.schedulers.asyncio import AsyncIOScheduler | ||
from telethon import TelegramClient, events | ||
from telethon.tl.custom.message import Message | ||
|
||
from src import worker | ||
|
||
config = ConfigParser(interpolation=ExtendedInterpolation()) | ||
config.read("config.ini") | ||
|
||
client = TelegramClient( | ||
"src/data/bot", config.get("Telegram", "api_id"), config.get("Telegram", "api_hash") | ||
).start() | ||
print("Telegram user bot is now running...") | ||
|
||
|
||
@client.on(events.NewMessage("me", pattern="/health")) | ||
async def handle_health(event: Message | events.NewMessage): | ||
"""Handles the /health command and responds with the application's health status. | ||
This asynchronous function listens for messages containing the /health command and replies with | ||
the current health status of the application. It provides a simple way for users to check if the | ||
bot is operational. | ||
Args: | ||
event (Message | events.NewMessage): The event object representing the incoming message. | ||
Raises: | ||
Exception: If there is an error while sending the reply. | ||
""" | ||
await event.reply(worker.health()) | ||
|
||
|
||
@client.on(events.NewMessage("me", pattern="/greeting_info")) | ||
async def handle_greeting_info(event: Message | events.NewMessage): | ||
"""Handles the /greeting_info command and responds with the next greeting time. | ||
This asynchronous function listens for messages containing the /greeting_info command and | ||
replies with the scheduled time for the next greeting. It provides users with information about | ||
when they can expect the next greeting message. | ||
Args: | ||
event (Message | events.NewMessage): The event object representing the incoming message. | ||
Raises: | ||
Exception: If there is an error while sending the reply. | ||
""" | ||
await event.reply(f"Next greeting at {worker.next_greeting_time}") | ||
|
||
|
||
@client.on(events.NewMessage("me", pattern="/send_greeting")) | ||
async def handle_send_greeting(event: Message | events.NewMessage): | ||
"""Handles the /send_greeting command to send a morning greeting. | ||
This asynchronous function listens for messages containing the /send_greeting command and | ||
triggers the sending of a morning greeting via the Telegram client. It then replies to the user | ||
to confirm that the action has been completed. | ||
Args: | ||
event (Message | events.NewMessage): The event object representing the incoming message. | ||
Raises: | ||
Exception: If there is an error while sending the greeting or the reply. | ||
""" | ||
await worker.send_morning_greeting(client) | ||
await event.reply("Done!") | ||
|
||
|
||
@client.on(events.NewMessage("me", pattern="/test_greeting")) | ||
async def handle_test_greeting(event: Message | events.NewMessage): | ||
"""Handles the /test_greeting command to send a test morning greeting. | ||
This asynchronous function listens for messages containing the /test_greeting command and | ||
triggers the sending of a morning greeting via the Telegram client without marking it as used. | ||
It then replies to the user to confirm that the action has been completed. | ||
Args: | ||
event (Message | events.NewMessage): The event object representing the incoming message. | ||
Raises: | ||
Exception: If there is an error while sending the greeting or the reply. | ||
""" | ||
await worker.send_morning_greeting(client, user_id="me", set_as_used=False) | ||
await event.reply("Done!") | ||
|
||
|
||
@client.on(events.NewMessage("me", pattern="/afternoon_media_info")) | ||
async def handle_afternoon_media(event: Message | events.NewMessage): | ||
"""Handles the /afternoon_media_info command and responds with the next media time. | ||
This asynchronous function listens for messages containing the /afternoon_media_info command | ||
and replies with the scheduled time for the next afternoon media. It provides users with | ||
information about when they can expect the next media item. | ||
Args: | ||
event (Message | events.NewMessage): The event object representing the incoming message. | ||
Raises: | ||
Exception: If there is an error while sending the reply. | ||
""" | ||
await event.reply(f"Next greeting at {worker.next_afternoon_media_time}") | ||
|
||
|
||
@client.on(events.NewMessage("me", pattern="/send_afternoon_media")) | ||
async def handle_send_afternoon_media(event: Message | events.NewMessage): | ||
"""Handles the /send_afternoon_media command to send an afternoon media item. | ||
This asynchronous function listens for messages containing the /send_afternoon_media command | ||
and triggers the sending of an afternoon media item via the Telegram client. It then replies to | ||
the user to confirm that the action has been completed. | ||
Args: | ||
event (Message | events.NewMessage): The event object representing the incoming message. | ||
Raises: | ||
Exception: If there is an error while sending the media or the reply. | ||
""" | ||
await worker.send_afternoon_media(client) | ||
await event.reply("Done!") | ||
|
||
|
||
@client.on(events.NewMessage("me", pattern="/test_afternoon_media")) | ||
async def handle_test_afternoon_media(event: Message | events.NewMessage): | ||
"""Handles the /test_afternoon_media command to send a test afternoon media item. | ||
This asynchronous function listens for messages containing the /test_afternoon_media command | ||
and triggers the sending of an afternoon media item via the Telegram client without marking it | ||
as used. It then replies to the user to confirm that the action has been completed. | ||
Args: | ||
event (Message | events.NewMessage): The event object representing the incoming message. | ||
Raises: | ||
Exception: If there is an error while sending the media or the reply. | ||
""" | ||
await worker.send_afternoon_media(client, user_id="me", set_as_used=False) | ||
await event.reply("Done!") | ||
|
||
|
||
@client.on(events.NewMessage("me", pattern="/stats")) | ||
async def handle_stats(event: Message | events.NewMessage): | ||
"""Handles the /stats command to send statistics to the user. | ||
This asynchronous function listens for messages containing the /stats command and triggers the | ||
sending of statistics related to the application via the Telegram client. It provides users with | ||
insights into the current state of the application. | ||
Args: | ||
event (Message | events.NewMessage): The event object representing the incoming message. | ||
Raises: | ||
Exception: If there is an error while sending the statistics. | ||
""" | ||
await worker.send_stats(client, user_id="me") | ||
|
||
|
||
async def main(): | ||
"""Main entry point for starting the Telegram bot and scheduling tasks. | ||
This asynchronous function initializes the scheduler and starts the various tasks for sending | ||
morning greetings, afternoon media, and pill reminders. It then enters an infinite loop to keep | ||
the application running and responsive. | ||
""" | ||
scheduler = AsyncIOScheduler() | ||
worker.start_sending_morning_greeting(scheduler, client, try_today=True) | ||
worker.start_sending_afternoon_media(scheduler, client, try_today=True) | ||
worker.start_sending_pills_reminder(scheduler, client) | ||
scheduler.start() | ||
while True: | ||
await asyncio.sleep(1) | ||
|
||
|
||
client.loop.run_until_complete(main()) |
Oops, something went wrong.