# El meu primer TelegramBot ## Índex sessió: 1. Objectiu taller. 2. Configurar entorn 3. Explicació de què és un Bot. Tipus de bots. 4. API TelegramBotApi 5. Programar primer Bot: bot conversa 1 a 1 5.1. Creació bot a @BotFather i configuració essencial. 5.2. Bot per jugar al cara i creu. 6. Programar segon Bot: inline. Generar acudits o excuses. 7. Referències ## 2. Configurar entorn Per poder programar correctament un Bot s'ha de: Tenir coneixement bàsics de Python (perquè és el llenguatge en què s'escull l'API) Tenir usuari del Telegram. Recomanable: activar la versió web del Telegram. Obriu al navegador la web: [http://web.telegram.org](http://web.telegram.org) . Us envia un codi d'activació. ![](https://i.imgur.com/2KWqkKp.png) Instal·lar l'API al vostre ordinador: des de la finestra shell del Repl.it ```bash= sudo pip install pyTelegramBotAPI ``` ![](https://i.imgur.com/OMkm65x.png) ## 3 Tipus de bot Farem tres tipus de Bot: ### 3.1 Bots de conversa un a un: - Aquells on l'usuari obrirà una conversa privada amb el Bot. - Poden ser jocs, enviar-nos informació... Exemple @triviaBot. ### 3.2. Bots inline: S'usen des de la línia d'escriptura de missatge. Aquells que ens ajuden quan estem conversant amb algú, ens ajuden a crear missatges o enviar imatges. Exemple @Gif @Youtube. ![](https://i.imgur.com/KJb212I.png) ### 3.3. Bots en un grup: S'afegeixen com un membre més d'un grup i responen quan se'ls passa una comanda (inicia per /) Poden ser per fer enquestes en un grup, presa de decisions, jocs...etc. Exemple @vot ## 4. API L'API ens dóna una sèrie de funcions que ens permet interactuar amb la plataforma de Telegram. Telegram és codi obert i permet accedir als seus continguts i funcionalitats via crides HTTP. La API fet amb Python ens facilita l'accés i ens encapsula les crides HTTP i els tractaments dels seus resultats que estan codificats en JSON. L'API escollida és pyTelegramBotApi que és codi obert. Per lligar el codi del nostre Bot amb el Telegram l'API usa un TOKEN (identificador) que dóna Telegram per a cada Bot creat. ## 5. Primer BOT: Conversa un a un ### 5.1. BotFather Creació del bot a Telegram per això s'usa un Bot !!! Ole ole! El Bot és el @BotFather. ![](https://i.imgur.com/0nSuOn0.png) Obriu conversa amb el BotFather. Té una sèrie de comandes. Useu la comanda /newbot. Poseu en el següent missatge el nom del Bot: CaraCreu$VOSTRENOM$ Després poseu el nom del Bot (serà el @), poseu al mateix però al final Bot. CaraCreu$VOSTRENOM$Bot. Podem posar més característiques del Bot . Interessa /setcommands per posar les comandes. **Però som programadors i ho farem per CODI!** ### 5.2. Joc de cara i creu Primer lligar el programa Python amb l'API de telegram. ```python3= import random import telebot from telebot import types TOKEN = 'TOKEN DONAT PER @BOTFATHER' #L'objecte bot interactuarà amb l'API bot = telebot.TeleBot(TOKEN) ranking={} ``` ![Captura de pantalla 2024-06-09 a les 8.13.04](https://hackmd.io/_uploads/SJA-_Tzr0.png) Heu de copiar el text que us ha sortit de color taronja al codi, on posa 'TOKEN DONAT PER @BOTFATHER' I ara el que hem de fer es respondre al start. Per tant hem de definir que li direm a l'usuari quan obri conversa amb el nostre bot. Abans de la funció que tractarà la comanda es posa: @bot.message_handler(commands=['start']) def start_command(missatge): Al definir la funció hem de tenir en compte que reben un objecte missatge del que ens interessa: **missatge.chat.id** Identificador únic del xat **missatge.from_user** Objecte del usuari. **missatge.from_user.username** L'objecte bot té diverses funcions una és: **bot.send_message(chat_id, text)** Quan acabem perquè el bot es quedi pendent a l'espera de missatges s'executa la funció **bot.polling()**. Veieu aquí el primer codi: ```python3= import telebot import random from telebot import types TOKEN = '' bot = telebot.TeleBot(TOKEN) ranking={} @bot.message_handler(commands=['start']) def start_command(missatge): bot.send_message( missatge.chat.id, 'Amb /tirar poden jugar i /rank veure el ranking' ) ranking[missatge.from_user.username]=[0,0] bot.polling() ``` Executeu-lo. Obriu conversa amb el bot, hem tingut èxit? Ara anem a fer l'acció de jugar d'apostar. Com ho feu? Afegiu aquest codi abans de la linia bot.polling() ```python3= @bot.message_handler(commands=['tirar']) def tirar_command(missatge): markup = types.ReplyKeyboardMarkup(row_width=2, one_time_keyboard=True) markup.add(types.KeyboardButton("Cara"),types.KeyboardButton("Creu")) resposta=bot.send_message(missatge.chat.id,"Hola que vols apostar cara o creu?",reply_markup=markup) bot.register_next_step_handler(resposta,decisio) ``` La funció que decideix (funció normal de Python) ha de: - Llençar una moneda. Com ho feu? Random? - Si l'usuari guanya enviar un missatge dient guanyat i sinó derrota. - Si la moneda és 0 i el resposta.text és Cara guanya. - Si la moneda és 1 i el resposta.text és Creu guanya. - Sinó perd. Copieu aquesta funció justa abans de la funció anterior: ```python3= def decisio(missatge): #moneda és el resultat del random moneda=random.randrange(2) if ((moneda==0 and missatge.text=="Cara") or (moneda==1 and missatge.text=="Creu")): bot.send_message(missatge.chat.id,"Has guanyat") else: bot.send_message(missatge.chat.id,"Has perdut") ``` Millores: - podeu enviar una imatge de la moneda cara o creu. - si s'encerta es pot enviar un àudio amb uns aplaudiments. Agafeu els recursos de https://github.com/sergiperez/tallerTelegramBot/tree/master/imatges Per enviar una imatge es fa amb (just es mostra imatge després de generar per random la moneda): ```python3= photo = open(str(moneda)+'.png', 'rb') bot.send_photo(missatge.chat.id, photo) ``` Per enviar l'àudio (just després que es digui has guanyat): ```python3= audio = open('aplaudiments.mp3', 'rb') bot.send_audio(missatge.chat.id, audio) ``` **Executeu, funciona?** Ara afegim aquest codi just abans del bot.polling() per: - mostrar el ranking de victòries dels jugadors. - permetre que es respongui per text (Cara o Creu) ```python3= # filter on a specific message @bot.message_handler(func=lambda message: message.text == "Cara") def command_cara(m): jugar(m) # default handler for every other text @bot.message_handler(func=lambda message: message.text == "Creu") def command_creu(m): jugar(m) @bot.message_handler(commands=['rank']) def rank(missatge): for user in ranking: victories=float(ranking[user][0]) derrotes=float(ranking[user][1]) if ((victories+derrotes)==0): bot.send_message(missatge.chat.id,str(user)+" encara no has jugat cap partida") else: bot.send_message(missatge.chat.id,str(user)+" ha guanyat "+str(victories/float(victories+derrotes)*100)+"%") ``` ## 6. Segon BOT: Inline (generador d'acudits o excuses) Creeu un bot igual que abans però li direm Excuses$VOSTRENOM$ Però ara s'ha d'executar dues comandes més: /setinline i us demanar frase a indicar que ha d'escriure usuari /setinlinefeedback i seleccioneu enable. ![Captura de pantalla 2024-06-09 a les 8.36.11](https://hackmd.io/_uploads/HJIuTpGBA.png) Un cop el feu, el lligueu igual que abans. ```python3= import telebot import os from telebot import types #/setinline frase #/setinlinefeedback enable TOKEN = 'El valor que us dona el @BotFather' #Bot Father us ha donat aquest valor bot = telebot.TeleBot(TOKEN) ``` Ara però com respon des de la línia d'escriptura de missatges heu d'implementar els següents mètodes (ja que no tenen comandes) **@bot.inline_handler(lambda query: len(query.query) is 0)** **@bot.inline_handler(func=lambda query: True)** El primer és perquè no s'executi si usuari no escriu cap paraula i no fem res. ```python3= @bot.inline_handler(lambda query: len(query.query) is 0) def default_query(inline_query): bot.answer_inline_query( inline_query.id, results=[] ) ``` Ara la funció que és posaria sota el segon ens hauria de retornar l'excusa que contingui paraula que escriu usuari. ```python3= @bot.inline_handler(func=lambda query: True) def query_text(inline_query): bot.answer_inline_query( inline_query.id, results=cercar(inline_query.query) ) def cercar(consulta): resultats=[] i=0 for acudit in acudits: if (consulta in acudit): i+=1 resultats.append( types.InlineQueryResultArticle( i, acudit, types.InputTextMessageContent(acudit) ) ) return resultats bot.polling() ``` Si feu excuses heu de canviar en el codi acudits per excuses. Per retornar s'ha de fer una llista d'objectes **types.InlineQueryResultArticle** amb tres camps un identificador (seqüència), el text i el text de nou com a **types.InputTextMessageContent(text)**. Aquí teniu una possible llista d'acudits: ```python3= acudits=[ "Crec que estas obsessionat amb el futbol i em fas falta. Falta! Si no t'he tocat.", "Cuantas anclas tiene un barco? 11 Por que? Porque siempre dicen 'eleven anclas'.", "Per que als elefants no els agrada la informatica? Tenen por als ratolins.", "Que desayuna Thor? Thor-tilla.", "Que son 8 bocabits? Un bocabyte.", "Que es un terapeuta? Mil gigapeutas.", "A l'escola els companys em diuen Facebook? I tu que els dius? M'agrada.", "Tens Wi-fi? Si I quina es la clau? Tenir diners i pagar-lo.", "Com li diuen al cosi vegetaria de Bruce Lee? Broco Lee", "Cual es el alimento mas filosofico? El pienso", "Siempre que cuento este chiste los perros dicen: GUAU!", "Donde pondrias un musico a jugar en un partido de futbol? En cualquiera de las bandas.", "En una convencion de circos un hombre pregunta: Disculpe, donde estan las hermanas siamesas? En la Sala de Juntas.", "Que li diu el Firefox al Chrome? Que te den Mozilla" ] ``` I d'excuses: ```python3= excuses = [ "El tren va en retras","No he canviat l'hora","El mobil no m'ha despertat","No sabia que la classe començava a les 8","Windows no funciona","El gos s'ha menjat l'arxiu","Ah! He oblidat annexar l'arxiu","No tens el document compartit?","Tinc la feina feta, però està a casa.","He fet tard perquè en ma casa fa molt de fred i el cola cao no es dissolia amb la llet.", "No he pogut lliurar el treball perquè han entrat a robar a ma casa i s'han emportat el meu ordinador","No estava copiant, estava mirant si el meu company ho ha fet bé.","No és que no estigui fent res, s'està descarregant un programa.","No faig la feina perquè a mi m'agrada fer els deures a casa.","He faltat a classe per temes personals, a partir de demà ja no arribaré tard i vindré tots els dies."] ``` El feu? ### 7.Referències - https://python-telegram-bot.org/ - http://piensa3d.com/tutorial-como-crear-programar-bot-telegram-python/ - http://untitled.es/bot-telegram-python-parte-2/ - https://geekytheory.com/telegram-programando-un-bot-en-python/ - https://github.com/HackLab-Almeria/clubpythonalm-taller-bots-telegram -http://hacklabalmeria.net/actividades/2016/04/28/taller-telegram.html - https://www.codementor.io/garethdwyer/building-a-telegram-bot-using-python-part-1-goi5fncay - https://core.telegram.org/bots - https://khashtamov.com/en/how-to-create-a-telegram-bot-using-python/ - https://www.atareao.es/tutorial/crea-tu-propio-bot-para-telegram/ - https://github.com/eternnoir/pyTelegramBotAPI/blob/master/telebot/types.py