Kinesis Advantage 360 の入荷Botを作る

# 経緯

このキーボードが欲しいがなかなか入荷しない上に入荷したとしてもすぐに売り切れる。 https://www.ergonomics.co.jp/smartphone/detail.html?id=000000000099

入荷をお知らせしてくれる公式LINEにも登録しているが、正直どれくらいリアルタイム性があるかわからない。

また、Lambdaを使った定期実行処理もなんだかんだ書いたことがなかったので書いてみたいと思った。

# 大まかな流れ

lambdaのランタイムはRuby前提。

  • samでlambdaを作る。
    • samを使わずに普通にmacのローカルで作ろうとするとnokogiriのネイティブビルド周りでlambdaが動かない
  • スクレイピングするコードを書く
  • Slack通知をするコードを書く(incomming webhook)
  • samコマンドでパッケージングとデプロイをする
  • lambdaのトリガーにEventBridgeを設定する
    • 「スケジュール方式」を選択して「rate(5 minutes)」と記載する

# 雑なコード

AWS SAM CLIが入ってない場合はインストールする。 https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-cli-install-mac.html

brew tap aws/tap
brew install aws-sam-cli

samを使って作る

$ sam init --runtime ruby2.7 --name foo_scraper
Which template source would you like to use?
	1 - AWS Quick Start Templates
	2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
	1 - Hello World Example
	2 - Multi-step workflow
Template: 1

Based on your selections, the only Package type available is Zip.
We will proceed to selecting the Package type as Zip.

Based on your selections, the only dependency manager available is bundler.
We will proceed copying the template using bundler.

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: 

Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

    -----------------------
    Generating application:
    -----------------------
    Name: foo_scraper
    Runtime: ruby2.7
    Architectures: x86_64
    Dependency Manager: bundler
    Application Template: hello-world
    Output Directory: .
    
    Next steps can be found in the README file at ./foo_scraper/README.md
        

    Commands you can use next
    =========================
    [*] Create pipeline: cd foo_scraper && sam pipeline init --bootstrap
    [*] Validate SAM template: cd foo_scraper && sam validate
    [*] Test Function in the Cloud: cd foo_scraper && sam sync --stack-name {stack-name} --watch

hello_world/Gemfileにnokogiriの記載を追加。

source "https://rubygems.org"

gem "httparty"
gem "nokogiri"

ruby '~> 2.7.0'

hello_world/app.rb を修正。ハリボテ感。

require 'json'
require 'net/http'
require 'uri'
require 'nokogiri'

def lambda_handler(event:, context:)
  scrape 
  {
    statusCode: 200,
    body: {
      message: "Hello World!",
      # location: response.body
    }.to_json
  }
end


def post_to_slack(message:)
  uri = URI.parse('https://hooks.slack.com/services/xxxxxxxxxxxxxxx')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  http.post(uri.path, { text: "<@UEAENGTNY> #{message}", "channel": "#sample" }.to_json)
end

def scrape
  url = 'https://www.ergonomics.co.jp/shopdetail/000000000099/'
  res = Net::HTTP.get(URI.parse(url))
  html = Nokogiri::HTML.parse(res)
  text = html.css('//*[@id="spcode"]')&.children&.last&.children&.text

  if text.nil?
    post_to_slack(message: 'HTML構造が変わってます。lambdaを修正してください。')
    return
  end

  if text != 'ワイヤレス (品切れ)'
    post_to_slack(message: '入荷したかも')
  else
    post_to_slack(message: '品切れです')
  end
end

この状態でローカルで動かしてみる。 まずはビルド。

$ sam build --use-container

イベントを発火させる。 events/event.jsonはデフォルトで生成されるもの。何もいじっていない。

$ sam local invoke -e events/event.json

するとSlackに通知が届く。 Image from Gyazo

あとはデプロイしてEventBridgeと繋ぐだけ。

S3経由でデプロイするみたいなのでまずはS3にバケットを作っておく。今回はkinesis-scraperというバケットを作っておいた。 そしてpackageコマンドとdeployコマンドを打てば新しくlambda関数が作られてマネコンから確認できる。

$ sam package --output-template-file output.yaml --s3-bucket kinesis-scraper
$ sam deploy --template-file output.yaml --stack-name kinesis-scraper --capabilities CAPABILITY_IAM

あとばEventBridgeをトリガーにするだけ。 こちらを参考。 【AWS】lambdaファンクションを定期的に実行する - Qiita

# まとめ

さくっとlambdaを作れるかと思ったらnokogiriのネイティブビルド問題によりsamを使う必要が生じで少し時間がかかってしまった。 lambdaとEventBridgeを繋ぐのは秒でできた。

# 参考にした記事

https://zenn.dev/shurijo_dot_com/articles/fb8a191baa9039 https://qiita.com/Y_uuu/items/85c86df8773f7c225521 https://qiita.com/Toshinori_Hayashi/items/5b0a72dc64ced91717c0