🤖

保育園の体温入力を自動化する

2023/02/26に公開

きっかけ

  • 今までは毎日紙に書いて提出していたものがWebで入力する方式に変更になった
  • Webでの入力はログインや画面遷移など今までよりも時間がかかる
  • 「Hey Siri」で入力ができれば手間がないのでは?

システム構成

システム構成は以下のとおりです。

体温の入力を簡単にする

  1. iPhoneもしくはApple Watchから「ショートカット」で体温を入力
    • ショートカットは音声入力の内容を取り出してWebhookをキックする事ができる
    • 体温の情報を埋め込んだコードをWebhookでSlackに投稿する
  2. サーバ上のSlackボットが上記のコードに反応して体温情報を抜き取り、スクリプトを起動
    • ショートカットをトリガーにRaspberryPiを動作させたかったのでSlackとHubotを利用
  3. スクリプトでWebサイトを操作して体温を自動入力する

「ショートカット」を使うと任意のサービスのWebhookをキックする事ができます。IFTTTなどのサービスとの連携など色々幅が広がります。

必要な知識, ハード, 事前準備

  • Raspberry Piなどのサーバ
  • Linuxの知識 (cron, aptなどでの必要なソフトの導入)
  • 基本的なプログラミング知識(RubyとかPythonとか)
  • Slackアカウントの作成と、Slackボットの作成(Hubot)
  • Webサイトのログイン情報
  • HTML, JavaScriptなどに対する基本的な知識
  • iPhoneで任意のショートカットを作成する(音声で数値を入力してWebhookを実行します)

この記事では、主にWebサイトの操作(プログラム)についてフォーカスしています。
cronの設定方法やSlackの設定などは他の人の記事などを参考にしてください。
ある程度のことは、ご自分で調べて解決できる人を対象にしています。

ブラウザの操作を自動化する

ポイント

  • Seleniumなどのヘッドレスブラウザが必要
    • 対象のサイトがAjaxを使っているので、ヘッドレスのブラウザがないと上手く操作できない
    • 今回はPhantomJSを利用
    • PhantomJSは開発が停止している
    • これからやる人はSeleniumを使った方が良い
    • 導入方法は他の人の記事を参考にしてください
  • Rubyで実装(Pythonとかの方が情報が多いけど、Rubyが好きだから)
  • Capybaraを利用(Webのテストとかで使われる)
    • ボタンを押したりとか、画面遷移の記述が楽になる
  • 色々試したけど、体温入力画面にURLを指定して直接遷移させることにした
    • ログイン画面からボタンを押して遷移していく場合、Ajaxのロードとか待ったりとかでうまくいかなかった
    • この辺りは、対象のシステム毎に調整が必要

プログラム

実際に作成したプログラムはこちらです。
(サイトのURLなどは別の物に変えてあります)
実行引数に体温が渡される仕様にしています。

#!/usr/bin/ruby

require 'capybara'
require 'capybara/dsl'
require 'capybara/poltergeist'
require 'nokogiri'
require 'open-uri'

Capybara.configure do |config|
    config.run_server = false
    config.default_driver = :poltergeist
    config.javascript_driver = :poltergeist
    config.app_host = "https://example.com" # 対象のサイトのURL
    config.default_max_wait_time = 60
    config.ignore_hidden_elements = false
end

Capybara.register_driver :poltergeist do |app|
    Capybara::Poltergeist::Driver.new(app, {
      :timeout=>120,
      js_errors: false,
      phantomjs_options: [
        '--load-images=no',
        '--ignore-ssl-errors=yes',
        '--ssl-protocol=any'
      ]
      })
end

module Crawler
    class Bluemix
        
        include Capybara::DSL

        def login(username, password)
            page.driver.headers = { "User-Agent" => "Mac Safari" }

            visit('/parent/secure/ログインページのパス')
            fill_in 'txtID', with: username
            fill_in 'txtPASS', with:  password
            click_on 'ログイン'

            #doc = Nokogiri::HTML.parse(page.html)
            #pp doc
        end

        def inputTemp(value)
            # ご家庭よりに遷移 (直接URLで遷移する)
            visit('/parent/secure/体温入力先のパス.aspx')

            s = value.split(".")
            select s[0], :from => 'ddlTEMPERATURE1'
            select s[1], :from => 'ddlTEMPERATURE2'
            select '特に無し', :from => 'grdFREE_ctl02_ddlNAIYO'
            select '無', :from => 'grdFREE_ctl03_ddlNAIYO'
            click_on '登録'
            page.accept_confirm

        end

    end
end

# 数値かどうか判定します
def is_numeric?(text)
    true if Float(text) rescue false
end

# __main__

if ARGV.size < 1
    exit 1
end

temp = ARGV[0]
exit 2 if !is_numeric?(temp)

crawler = Crawler::Bluemix.new
crawler.login("ユーザID", "パスワード")
crawler.inputTemp(temp)

Discussion