Un bot es un programa que se comunica con humanos vía una aplicación de chat.
SITP bot es un bot que ayuda a conocer más información acerca de los buses SITP.
Bus SITP es un bus del Sistema Integrado de Transporte Público, que circula por las calles de Bogotá.
Haciendo "scraping" de la página de SITP.
El web scraping es una técnica para extraer información de sitios web.
Para realizar scraping en Python se usa una librería llamada Scrapy.
Polling: un script de Python cada cierto tiempo se conecta a servidores de Telegram y pregunta si hay mensajes nuevos.
Webhook: una URL específica en nuestro servidor a la cual Telegram envía nuevos mensajes.
1. Obtener token de Telegram:
2. Decir a Telegram el URL dónde estará el webhook:
curl -F "url=https://sitp.vero4ka.info/bot/<token>/"
https://api.telegram.org/bot<token>/setWebhook
3. Escribir un endpoint para el webhook:
class TelegramCommandReceiveView(View):
def post(self, request, bot_token):
if bot_token != settings.TELEGRAM_TOKEN:
return HttpResponseForbidden('Invalid token')
try:
raw = request.body.decode('utf-8')
payload = json.loads(raw)
except ValueError:
return HttpResponseBadRequest('Invalid request body')
# Haz algo con payload
return JsonResponse({}, status=200)
{
"update_id": 302347250,
"message": {
"message_id": 60,
"from": {
"id": 237007449,
"first_name": "Pepito",
"username": "pepito123"
},
"chat": {
"id": 237007449,
"first_name": "Pepito",
"username": "pepito123",
"type": "private"
},
"date": 1483840800,
"text": "Hola",
"entities":[
{
"type":"bot_command",
"offset":0,
"length":4
}
]
}
}
$ pip install telepot
TelegramBot =
telepot.Bot(settings.TELEGRAM_TOKEN)
chat_id = payload['message']['chat']['id']
# Enviar un mensaje simple
bot.sendMessage(chat_id, 'Hola')
# Enviar un texto enriquecido
bot.sendMessage(
chat_id,
'*Hola*, ¿cómo vas?',
parse_mode='Markdown'
)
$ pip install emoji
import emoji
# Enviar un mensaje con emoji
bot.sendMessage(
chat_id,
emoji.emojize(
'Hola :wink:',
use_aliases=True,
),
parse_mode='Markdown'
)
# Enviar foto
bot.sendPhoto(chat_id, photo)
# Enviar audio
bot.sendAudio(chat_id, audio)
# Enviar ubicación
bot.sendLocation(chat_id, latitude, longitude)
# Pedir al usuario a enviar su ubicación
keyboard = ReplyKeyboardMarkup(keyboard=[
[KeyboardButton(
text='Enviar mi ubicación',
request_location=True,
)],
])
bot.sendMessage(
chat_id,
'Enviar mi ubicación',
reply_markup=ReplyKeyboardMarkup(
keyboard=[
[KeyboardButton(text="Enviar mi ubicación", request_location=True)]
],
),
)
1. Crear una aplicación en Facebook y agregar "Messenger":
2. Configurar un webhook:
3. Para poder verificar que nuestro bot esté bien configurado, Facebook nos mandará una petición GET a nuestro servidor:
GET https://mipagina.com/bot/fb-webhook/
?hub.mode=subscribe
&hub.challenge=1122334455
&hub.verify_token=una-frase-secreta
y esperará que le respondemos con el código 200 y el contenido del paramentro hub.challenge cuando verify_token coincide con la frase secreta que especificamos, o con el código HTTP 403 en el caso opuesto.
class FacebookCommandReceiveView(View):
def get(self, request):
if (
request.GET.get('hub.mode') == 'subscribe' and
request.GET.get('hub.verify_token')
== settings.FACEBOOK_VERIFY_TOKEN
):
return HttpResponse(request.GET.get('hub.challenge'))
else:
return HttpResponseForbidden()
4. Escribir una vista que se encargará de recibir la petición:
5. Oprimir el botón "Verify and Save". Después de eso Facebook nos dará un token de la aplicación y permitirá configurar el webhook:
6. Suscribirse a los eventos en Messenger:
7. Damos click en "Edit notes" y entramos a el formulario
de configuración:
8. Después de que Facebook verifique el comportamiento de nuestro bot, recibimos el mensaje de aprobación:
9. Cuando nuestro bot esté listo, lo podemos activar para todos los usuarios:
{
"object": "page",
"entry": [{
"messaging": [
{
"timestamp": 148596022321686,
"message": {
"seq": 110377,
"mid": "mid.1424360289686:0b78d5e099",
"text": "Hola"
}, "recipient": {
"id": "2445077123307282"
}, "sender": {
"id": "1341234970435656"
}
}
],
"id": "51247423670015",
"time": 1485960807075
}]
}
class FacebookCommandReceiveView(View):
def post(self, request, bot_keyword):
if bot_keyword != settings.FACEBOOK_VERIFY_TOKEN:
return HttpResponseForbidden('Invalid token')
data = json.loads(request.body.decode('utf-8'))
# Make sure this is a page subscription
if data['object'] == 'page':
# Iterate over each entry - there may be multiple if batched
for entry in data['entry']:
# Iterate over each messaging event
for event in entry['messaging']:
if event.get('message'):
# Recibimos un mensaje
elif event.get('delivery'):
# Mensaje recibido
elif event.get('read'):
# Mensaje leído
elif event.get('postback'):
# Postback, por ejemplo, de un botón
# ...
return HttpResponse()
recipient_id = event['sender']['id']
message = event['message']
message_text = message.get('text', '')
if 'hola' in message_text:
payload = {
'message': {
'text': 'Hola :)',
},
'recipient': {
'id': recipient_id,
}
}
base_url = 'https://graph.facebook.com/v2.6/me/messages'
response = requests.post(
'{}?access_token={}'.format(base_url, ACCESS_TOKEN),
json=payload,
)
if response.status_code == 200:
response_body = response.json()
else:
logger.error('Unable to send message')
# Enviar un adjunto:
# imagen, audio, video, archivo
payload = {
'message': {
'attachment': {
'type': 'image',
'payload': {
'url': image_url,
}
}
},
'recipient': {
'id': recipient_id,
}
}
payload = {
'message': {
'text': message,
'quick_replies': [{
'content_type': 'location',
}]
},
'recipient': {
'id': recipient_id,
}
}
Se puede pedir a usuario a enviar información específica por medio de "Quick Replies":
No se puede :(
Pero es posible generar una imagen del mapa, usando, por ejemplo, los mapas estáticos de Google o Mapbox:
https://api.mapbox.com/v4/mapbox.streets/
pin-s+f44({long},{lat})/
{long},{lat},15/300x200.png?
access_token={access_token}
@vero4ka_ru
https://telegram.me/sitp_bot
https://www.facebook.com/SITPbot