[PYTHON] Création d'un LINE BOT pour notifier d'autres concours AtCoder à l'aide d'AWS

Avez-vous désactivé les notifications pour les applications autres que LINE? Je coupe. Je voulais que vous soyez averti sur LINE lorsque le calendrier du concours AtCoder a été ajouté, j'ai donc créé un LINE BOT avec Mr JJ.

Ce que j'ai créé

Nous rechercherons les concours programmés à 00h00 toutes les heures et BOT vous avertira lorsque de nouveaux concours seront ajoutés. image.png

Il existe également une fonction qui retourne lorsque vous envoyez un message. (prime) image.png

Vous pouvez ajouter des amis au LINE BOT créé à partir du bouton ci-dessous.

Ajouter un ami

Configuration du backend

LINE_BOT_structure.png Tout le traitement backend est effectué sur AWS (Amazon Web Services). L'opération sur AWS peut être divisée en deux.

Décrit les fonctionnalités implémentées pour chaque section.

Section de notification du concours

Flux de section de notification de concours

  1. Fonction Lambda: ** AtCoder_contest_Search ** gratte la page d'accueil d'AtCoder pour obtenir une liste des concours programmés.
  2. ** AtCoder_contest_Search ** obtient le fichier JSON de la liste des concours notifiés à partir de S3.
  3. Calculez le jeu de différences et extrayez les concours inopinés. Si le concours inopiné est vide, il se termine.
  4. Envoyez des données de concours inopinées à la fonction Lambda: ** LINE_contest_notify **.
  5. Notifiez les données envoyées par ** LINE_contest_notify ** au format de diffusion en utilisant line-bot-sdk.
  6. Téléchargez les données du concours obtenues dans [1] vers S3

Fonction de grattage

Python3


def get_contests():
    #Récupérer les données de l'URL
    url = "https://atcoder.jp/home?lang=ja"
    html_data = requests.get(url)

    #perspective html
    soup = BeautifulSoup(html_data.text, "html.parser")
    
    tags = ["upcoming", "recent"]
    ret_dic = {}
    for tag in tags:
        div = soup.find("div", id="contest-table-"+tag)
        table = div.find("table")
        times  = table.find_all("time")
        titles = table.find_all("a")

        ret_list = []
        for i in range(len(times)):
            dic = {}
            dic["start"] = times[i].text
            dic["title"] = titles[i*2+1].text
            dic["url"] = "https://atcoder.jp" + titles[i*2+1].get("href")
            ret_list.append(dic)
        ret_dic[tag] = ret_list
    return ret_dic
Contenu des données
argument null
Valeur de retour Données pour chaque concours(Heure de début / titre / URL)Liste des dictionnaires avec

Seul * ret_dic ["coming"] * est utilisé dans ce BOT.

Récupérer des fichiers depuis S3

Python3


def get_data_s3():
    #Fichier json du concours notifié sur S3"contests.json"Chargement
    
    client = boto3.client("s3")
    try:
        response = client.get_object(Bucket = "bucket_name", Key = "json_file_name")
    except Exception as e:
        print(e)
    return json.loads(response["Body"].read().decode())
Contenu des données
argument null
Valeur de retour Les données du dictionnaire lisent le fichier JSON sur S3

La valeur de retour de la méthode * get_object * est un dictionnaire et la clé "Body" contient le contenu du fichier.

Téléchargement de fichiers vers S3

Python3


def put_data_s3(save_dic):
    #Téléchargeur S3 pour les nouveaux fichiers json du concours notifié
    
    text = json.dumps(save_dic, ensure_ascii = False)
    s3 = boto3.resource("s3")
    s3.Object("bucket_name", "json_file_name").put(Body = text)
Contenu des données
argument Données du dictionnaire à enregistrer
Valeur de retour null

Lors de la conversion du dictionnaire en texte au format JSON, si la valeur de * ensure_ascii * est définie sur False, Le japonais dans le fichier JSON devient plus facile à lire et la taille du fichier peut être réduite.

Envoi d'un message diffusé

Python3


def DatetimeToString(date):
    if not isinstance(date, datetime.datetime):
        date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S%z")
    week_list = "Lundi, mardi, mercredi, jeudi, vendredi, samedi et dimanche"
    return f"{date.strftime('%m/%d')}({week_list[date.weekday()]}){date.strftime('%H:%M')}"

def MakeMessageText(event):
    text = DatetimeToString(event["start"]) + "\n" + event["title"] + "est retenu!\n" + event["url"]
    return text

def main(event, context):    
    line_bot_api = LineBotApi("channel_access_token")
    message = MakeMessageText(event)
    line_bot_api.broadcast(TextSendMessage(text=message))

    # ***Traitement pour terminer la fonction principale***

Créez un format de message pour l'heure de début du concours avec la fonction * DatetimeToString * Création d'un format pour les messages à notifier par la fonction * MakeMessageText *.

Vous pouvez notifier tous vos amis BOT en appelant simplement la méthode * LineBotApi * class * broadcast * de line-bot-sdk. ..

Section de réponse LINE

Schéma de configuration de ce système ![LINE_BOT_structure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308399/d98a570f-3c81-a5e4-b71e-8ac8182c1a31.png)

Flux de section de réponse LINE

  1. Lorsque LINE BOT reçoit un message LINE, il utilise un webhook pour POSTER le contenu du message sur API Gateway.
  2. POST to API Gateway déclenche la fonction Lambda: ** LINE_reply_message ** à exécuter.
  3. ** LINE_reply_message ** envoie un message de réponse LINE en utilisant line-bot-sdk.

Envoyer un message de réponse

Python3


def main(event, context):
    handler = WebhookHandler("channel_secret")
    line_bot_api = LineBotApi("channel_access_token")
    body = event["body"]

    #Ajout de la fonction de réponse au gestionnaire
    @handler.add(MessageEvent)
    def SendReply(line_event):
        message = MakeReplyMessage(line_event.message.text)
        line_bot_api.reply_message(line_event.reply_token, TextSendMessage(text=message))

    try:
        handler.handle(body, event["headers"]["X-Line-Signature"])
    except #La gestion des erreurs

    # ***Traitement pour terminer la fonction principale***

La fonction * MakeReplyMessage * renvoie un message de réponse sous forme de chaîne de caractères en fonction du contenu du message reçu par BOT. Nous vous recommandons tout particulièrement de lire la documentation line-bot-sdk pour cette partie.

À la fin

Nous avons présenté les principales fonctions que nous avons créées. Line-bot-sdk, qui facilite l'utilisation du BOT, est très pratique. J'ai peu de connaissances sur AWS et la conception est assez approximative, mais si j'en ai envie, j'ajouterai et améliorerai des fonctions à l'avenir. (peut être)

Recommended Posts

Création d'un LINE BOT pour notifier d'autres concours AtCoder à l'aide d'AWS
Création d'un bot Discord pour vous informer des mises à jour pour devenir romancier
Procédure de création d'un Line Bot sur AWS Lambda
Création d'un bot LINE ~ Création, déploiement et lancement ~
J'ai créé un programme pour vous avertir par LINE lorsque les commutateurs arrivent
Utilisez AWS lambda pour récupérer les actualités et notifier régulièrement LINE des mises à jour [python]
Histoire de faire une recherche de magasin BOT (AI LINE BOT) pour Go To EAT dans la préfecture de Chiba (2) [Présentation]
Envoyer un message à LINE avec Python (LINE Notify)
Utilisez AWS Lambda + LINE Notify pour avertir LINE de ne pas oublier votre parapluie lorsque vous rentrez chez vous
L'explication la plus simple au monde sur la création de LINE BOT (1) [Account preparation]
Créer un robot LINE de retour de perroquet avec AWS Cloud9
[Python] Utilisation de l'API Line [1ère création de Beauty Bot]
LINE Bot qui vous informe des stocks d'intérêt
Jouez pour informer Slack des données environnementales de SensorTag à l'aide d'AWS PaaS via Raspberry Pi3
Comment créer un LINE BOT 004 interactif (répondre à la date de clôture d'une société cotée)
[LINE Notify API, AWS] Envoyez régulièrement des tweets bourdonnants au groupe LINE
[Introduction à AWS] Mémorandum de création d'un serveur Web sur AWS
Je souhaite envoyer un message de Python à LINE Bot
Couches AWS Lambda Une explication rapide de la création à la liaison
L'histoire de la création d'une base de données à l'aide de l'API Google Analytics
Créons un bot LINE en utilisant divers services [ngrok edition]
[AWS] J'ai créé un BOT de rappel avec LINE WORKS (implémentation)
[Python] Laissez LINE vous informer quotidiennement du classement des résultats de recherche sur votre site.