Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Messaggi di benvenuto più articolati #42

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
if [ -f requirements_dev.txt ]; then pip install -r requirements_dev.txt; fi
- name: Test with pytest
run: |
pytest --cov src tests/ --cov-fail-under=100 --cov-report xml
pytest --cov . tests/
- name: Upload to CodeCoverage
uses: codecov/codecov-action@v2
with:
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ A simple Telegram bot built with [python-telegram-bot](https://python-telegram-b
It simply sends a randomized welcome message from a pre-defined message list each time a new user joins a specific group.

## How to use?
Just set a `QDBotToken` env variable, this is your bot token obtained from [BotFather](https://t.me/botfather)
Just set a `TOKEN` env variable, this is your bot token obtained from [BotFather](https://t.me/botfather)

### Example in bash
```bash
export QDBotToken="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" # Your bot token
export TOKEN="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" # Your bot token
```

## Write Unit Tests
Expand All @@ -33,4 +33,4 @@ To add a new unit test without mocking, there are some examples at the beginning
If is necessary one or more mock(s), it's possible to append three more keys to the unit test. The test should have the same keys with three more keys:
- `mock_obj`: it's a list of the objects in which there are the functions to mock. In our examples they often refer to the main object (the one imported from src.main)
- `mock_func`: an array of strings, it indicates the functions to mock
- `mock_ret`: a list of the returned values
- `mock_ret`: a list of the returned values
11 changes: 11 additions & 0 deletions data/welcome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"it": ["Benvenuto USER nel nostro gruppo ^-^","Ciao USER!","Salve USER!"],
"en": ["Welcome USER to our group ^-^","Hello USER!","Howdy USER!"],
"readme": "https://t.me/c/1095167198/67194",
"utils": [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Al fine di mantenere il supporto alla doppia lingua (e ulteriori future) penso possa essere utile trasformare le liste contenute in it ed en in dizionari e incorporare all'interno di questi nuovi dizionari utils in entrambe le lingue

"Se hai idee o suggerimenti, condividili con noi. Siamo aperti a nuove prospettive!",
"Non esitare a fare domande se hai bisogno di aiuto.",
"Speriamo che ti possa sentire come a casa tua.",
"Ricorda di rispettare le opinioni degli altri membri, anche se non sempre concordi. La diversità ci arricchisce."
]
}
16 changes: 16 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from os import getenv
from telegram.ext import MessageHandler, Updater, Filters
from module.commands.welcome import send_welcome

def main() -> None:
TOKEN = getenv("TOKEN")
updater = Updater(TOKEN, use_context=True)
dp = updater.dispatcher

dp.add_handler(MessageHandler(Filters.status_update.new_chat_members, send_welcome))

updater.start_polling()
updater.idle()

if __name__ == '__main__':
main()
36 changes: 36 additions & 0 deletions module/commands/welcome.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from telegram import Update, User
from telegram.ext import CallbackContext
from module.shared import welcome
from random import randrange


def get_new_user_name(user: User) -> str:
return f"@{user['username']}" if user['username'] is not None else user['first_name']


def generate_welcome(new_member: User) -> str:
new_member_username = get_new_user_name(new_member)

match new_member["language_code"]:
case "en":
lan_code = "en"
case "it" | _ :
lan_code = "it"

wlc_mess_list = welcome[lan_code]

return wlc_mess_list[randrange(0, len(wlc_mess_list))].replace("USER", new_member_username)


def send_welcome(update: Update, _: CallbackContext) -> None:
if update.message.new_chat_members:
for new_member in update.message.new_chat_members:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Il controllo dell'esistenza di elementi diventa ridondante, infatti un foreach eventuale su una lista vuota non avrebbe tempo di calcolo aggiuntivo

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scusami ma non ho capito benissimo. La miglior scelta è non eseguire il for?

Copy link
Member

@domenicoblanco domenicoblanco Oct 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In questo caso conviene eseguirlo a prescindere, infatti il costo del for su una lista vuota è praticamente identico al controllare se esiste effettivamente qualcosa su cui iterare ed eventualmente iterare.
In breve, invece di controllare due volte l'esistenza degli elementi, conviene lasciarlo controllare dal for stesso

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ceeerto, ha perfettamente senso. Sono d'accordo

if not new_member.is_bot:
handle_welcome(update, new_member)


def handle_welcome(update: Update, new_member: User) -> None:
welcome_msg = f'{generate_welcome(new_member)}\n' + \
f"- Dai un'occhiata al [README]({welcome['readme']})\n" + \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L'uso di ' e " non è consistente con il resto del programma, inoltre la concatenazione attraverso l'operatore + rende inutile l'uso delle f-string.
Una sintassi valida potrebbe essere simile a:

welcome_msg = (
    f'{generate_welcome(new_member)}\n' 
    f'- Dai un'occhiata al [README]({welcome["readme"]})\n'
    f'- {welcome["utils"][randrange(0, len(welcome["utils"]))]}'
)

f"- {welcome['utils'][randrange(0, len(welcome['utils']))]}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Facendo riferimento al commento su utils, andrebbero localizzate le stringhe, eventualmente memorizzando il valore per l'uso successivo

Copy link
Member Author

@Picred Picred Oct 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E come potrebbe diventare "randomico" il messaggio se appena ne leggo uno casuale dal file (la prima volta), esso viene localizzato e ripreso in una futura chiamata della funzione?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Errore mio, intendevo memorizzare la lingua di riferimento in modo da essere passata all'interno di generate_welcome, senza dover quindi ottenere di nuovo il valore da User

Copy link
Member Author

@Picred Picred Oct 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quindi l'idea sarebbe creare una sorta di:

{
     "it" : {
       "benvenuti" : ["...", "..." ],
       "utils" : ["...", "...", "..." ]
      }
      "readme" : "https://..."
}

Ho capito bene?

Ed eventualmente il lan_code conservato in una variabile per accedere direttamente al json[lan_code]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Esattamente c:

update.message.reply_markdown(welcome_msg, disable_web_page_preview=True)
4 changes: 4 additions & 0 deletions module/shared.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from json import load

with open("data/welcome.json", "r") as f:
welcome = load(f)
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
python-telegram-bot == 20.0a0
python-telegram-bot==13.8.1
Empty file removed src/__init__.py
Empty file.
46 changes: 0 additions & 46 deletions src/main.py

This file was deleted.

4 changes: 0 additions & 4 deletions src/welcome.json

This file was deleted.

2 changes: 1 addition & 1 deletion tests/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from telegram import Message, Chat
from telegram.ext import Application
from datetime import datetime
import src.main as main
import main as main


def get_wel(lan_code: str) -> str:
Expand Down
Loading