0
0

API GatewayとLambdaとS3でHTTPメソッドに応じて応答を変えた静的なWebサイトを作成し、EventBridgeとLambdaで定期的にリクエストを送信する

Posted at

この記事は以下のハッカソンに参加した際に作ったプロダクトの一部の作り方を示したものです。

作るもの

病院の診察予約を模擬した単純なWebサイトを作成します。実際にはCSRFトークンなど、もう少し複雑になることを考慮する必要があります。

  • GET: 現在の呼び出し番号を記載したページ
  • POST: 予約完了のページ
  • インターネットからHTTPSでアクセスでき、メソッドによって応答を変える

S3に設置するhtmlファイル

ChatGPTにイメージを伝えてhtmlファイルのコードを出力してもらい、項目や表示内容などを微調整しました。

呼び出し番号ページ

呼び出し番号を記載したページ。
スクリーンショット 2023-09-23 18.28.57.png

wait.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <title>診察の順番待ち</title>
  <style>
    body {
      font-family: 'Arial', sans-serif;
      background-color: #f4f4f4;
      margin: 0;
      padding: 0;
    }

    header {
      background-color: #50b3a2;
      color: white;
      text-align: center;
      padding: 1em 0;
    }

    ul {
      padding: 0;
      margin: 0;
      list-style: none;
    }

    ul li {
      background: #ffffff;
      margin-bottom: 1px;
      padding: 0.5em;
      text-align: center;
    }

    .calling {
      background-color: #ffcccb;
    }
  </style>
</head>

<body>
  <header>
    <h1>診察の順番</h1>
  </header>
  <main>
    <ul>
      <li class="calling">1番 - 現在呼び出し中</li>
      <li>2番</li>
      <li>3番</li>
      <li>4番</li>
      <li>5番</li>
    </ul>
  </main>
</body>

</html>

予約完了ページ

スクリーンショット 2023-09-24 13.53.24.png

yoyaku.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>予約完了</title>
<style>
  body {
    font-family: 'Arial', sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
  }
  .container {
    width: 50%;
    margin: auto;
  }
  header {
    background: #50b3a2;
    color: white;
    text-align: center;
    padding: 1em 0;
  }
  .notification {
    padding: 1em;
    background: #e3e3e3;
    margin: 1em 0;
  }
</style>
</head>
<body>
<div class="container">
  <header>
    <h1>予約完了</h1>
  </header>
  <div class="notification">
    <p>受付番号: <strong>5</strong></p>
    <p>予約番号: <strong>ABCDE</strong></p>
  </div>
</div>
</body>
</html>

S3に設置しLambda経由でAPI Gatewayから呼び出す

S3バケットにhtmlを設置

S3バケットを作成しファイルを設置します
スクリーンショット 2023-09-23 18.16.10.png
スクリーンショット 2023-09-23 18.26.10.png

表示するページごとにLambdaを作成

S3バケットからhtmlを取得しHTTPレスポンスを生成するLambdaを作成します。
スクリーンショット 2023-09-24 1.05.43.png

getWaitPage
import boto3
from botocore.exceptions import NoCredentialsError, PartialCredentialsError

s3_client = boto3.client('s3')
BUCKET_NAME = 'your backet name'

def lambda_handler(event, context):
    try:
        response = s3_client.get_object(Bucket=BUCKET_NAME, Key='wait.html')
        content = response['Body'].read().decode('utf-8')
        return {
            'statusCode': 200,
            'body': content,
            'headers': {
                'Content-Type': 'text/html'
            }
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': str(e)
        }

API GatewayでAPIを作成

APIを作成します。
スクリーンショット 2023-09-24 2.07.37.png
作成したAPIにルートからGETとPOSTを登録し、作成したLambdaをそれぞれ紐づけます。
スクリーンショット 2023-10-29 19.05.26.png
スクリーンショット 2023-10-29 19.07.23.png
API Gatewayのエンドポイントにブラウザからアクセスし、S3に設置したhtmlが表示されることを確認しましょう。

EventBridgeでLambdaを定期実行

定期実行するLambdaを作成

ここでは、POSTリクエストを送る例を記載しています。

eventbridge-yoyaku
import json
from urllib import request, parse

def lambda_handler(event, context):
    url = "your api url"
    
    # POSTリクエストに送信するデータ
    data = {}
    
    data = parse.urlencode(data).encode()
    req = request.Request(url, data=data, headers={'Content-Type': 'application/x-www-form-urlencoded'})
    
    try:
        with request.urlopen(req) as response:
            response_body = response.read().decode()
            status_code = response.getcode()
    except Exception as e:
        return {
            'statusCode': 500,
            'body': str(e)
        }
    
    return {
        'statusCode': status_code,
        'body': response_body
    }

テストを実行してWebページが取得できていることを確認します。
スクリーンショット 2023-10-29 19.22.56.png

EventBridgeのスケジュールを作成

スケジュールを作成します。
スクリーンショット 2023-09-24 14.01.26.png
トリガーを設定します。cron書式でかけます。例ではハッカソンのプレゼン期間中だけ5分ごとに動作するようにしています。
スクリーンショット 2023-09-24 14.12.41.png
作成したLambdaを実行するようにします。
スクリーンショット 2023-10-29 19.16.52.png

まとめ

予約サイトの模擬サイトをAWSで作り、LambdaをEventBridgeで定期実行させました。Lambdaの中でDynamoDBと連携させ、予約の実行タイミングを登録したり、予約後に予約番号を保存したりすると便利に使えるかと思います。

ただし実際にプログラムでWebサイトにスクレイピングや予約操作の自動実行を行うときは、Webサイトの利用規約や負荷などを考慮し、実施しても問題ないことを慎重に確かめてから実施してください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0