見出し画像

AWS LambdaとLINE Notifyを使用したグラフの自動送信

この記事は、AWS LambdaとLINE Notifyを使用してグラフの自動送信を実装する際の参考として役立つことを目指しています。同じような課題に直面している人が、この記事を読むことで時間を節約できることを願っています。

背景



サーバレスアーキテクチャの利点を活かして、AWS Lambdaを使用して定期的な通知やレポートを自動化したいと考えていました。特に、LINE Notifyを使って、生成したグラフをLINE上で直接確認するという方法を探求していました。


課題

初期の実装では、メッセージの送信は成功していたものの、画像の送信に問題が生じていました。具体的には、LINE Notify APIから Bad Request エラーが返される問題に直面しました。

目的

このブログ記事の目的は、AWS LambdaとLINE Notifyを使用してグラフを自動的に送信する際の正確な手順と、遭遇したトラブルの解決方法を共有することです。

方法

  1. LINE NotifyのAPIトークンの取得:

  • LINE Notifyの公式サイトにアクセスし、APIトークンを取得します。

  • このトークンは、後でPythonコード内の config.ini に保存します。

[LINE]
token = YOUR_LINE_NOTIFY_TOKEN
  1. Pythonコードの実装:

以下のPythonコードは、matplotlib を使用してグラフを生成し、requests ライブラリを使用してLINE Notify APIにメッセージと画像を送信するものです。

import configparser
import requests
import matplotlib.pyplot as plt
import numpy as np
import io

def send_to_line_notify(message, image_buffer=None):
    config = configparser.ConfigParser()
    config.read('config.ini')
    token = config['LINE']['token']
    
    url = "https://notify-api.line.me/api/notify"
    headers = {
        "Authorization": f"Bearer {token}"
    }
    
    data = {
        "message": message
    }
    
    files = {}
    if image_buffer:
        files = {"imageFile": ("image.png", image_buffer, "image/png")}
    
    response = requests.post(url, headers=headers, data=data, files=files)
    return response.json()

def create_plot():
    x = np.linspace(0, 10, 100)
    y = np.sin(x)
    plt.plot(x, y)
    plt.title("Sample Plot")
    plt.xlabel("X Axis")
    plt.ylabel("Y Axis")
    buffer = io.BytesIO()
    plt.savefig(buffer, format="png")
    buffer.seek(0)
    return buffer

def lambda_handler(event, context):
    buffer = create_plot()
    response = send_to_line_notify("Here's your plot from AWS Lambda:", buffer)
    return response

  1. AWS Lambdaの設定:

  • 必要なライブラリを含むzipファイルを作成し、AWS Lambdaにアップロードします。以下のコマンドでzipファイルを作成することができます。

requirements.txtの作成

pipreqs --encoding UTF8

layerの作成 (power shell)

docker run -v "${PWD}:/var/task" "public.ecr.aws/sam/build-python3.9" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.9/site-packages/; exit"

pythonフォルダができるので、それをzip圧縮してLambdaのレイヤー作成でアップロードする。

  • Lambda関数のタイムアウトやメモリの設定を調整します。

トラブルシューティング

問題の発生

初期の実装では、メッセージは正常に送信されましたが、画像の送信時にLINE Notify APIから Bad Request エラーが返されました。

原因

  • 画像データの送信方法が不適切であったため、LINE Notify APIはリクエストを正常に処理できませんでした。

解決方法

  1. 画像のバイナリデータの取り扱い:

    • io.BytesIO() を使用して、メモリ上に一時的に画像データをバイナリ形式で保存しました。

    • このバイナリデータを直接 requests ライブラリに渡して、画像として送信することができました。

  2. requests.post の files パラメータの利用:

    • 画像データを送信する際には、requests.post メソッドの files パラメータを使用して、画像データを添付する必要があります。

    • files パラメータには、ファイル名、バイナリデータ、およびMIMEタイプを指定するタプルを渡しました。

結論

AWS LambdaとLINE Notifyを組み合わせることで、定期的なレポートや通知を効率的に自動化することができます。ただし、特に画像の送信に関しては注意が必要です。このブログ記事を参考にして、同じ問題に遭遇した場合のトラブルシューティングに役立ててください。

この記事が気に入ったらサポートをしてみませんか?