こんにちは、Juntechです。
私は作業場にサーバを置いているのですが、
IP固定ができないため、うっかりルータを再起動するなどして、
グローバルIPがわからなくなってしまうことがよくあります。
そこで今回は、GoogleスプレッドシートとIFTTTを使って、
グローバルIPが変わった時に自動通知してもらおうと思います。
まずはスキーム
こんな感じでやります。
サーバーで定期的にIPを取得し、前回のIPと比較をします。
IPに変更があればWebhookを使ってIFTTTへPOSTし、
IFTTTからLINEへ通知します。
実装する
IFTTTの設定
まずはIFTTTの設定を済ませます。
https://ifttt.com/home
IFTTTとは、さまざまなサービスの間に入って、
データのやりとりを自動化できるサービスです。
最近だと、スマート家電が有名になったことで、
各種サービスとデバイスを連携する手段としてこのサービスを聞いたことのある人も多いかと思います。
今回はこのIFTTTで、サーバからPOSTした情報をLINEに連携します。
アカウント作成ができたら、右上メニューの「Create」を選択します。
するとこんな感じで、シンプルな設定画面が表示されます。
まずは「If This」を選択します。
検索バーに「Webhooks」と打ち込み、表示されたWebhooksのアイコンを選択します。
「Receive a web request」を選択します。
Event Nameを入力し、「Create trigger」を選択します。
なおここで設定した名前は後々のAPI利用時にURLに含める必要があるため、
半角小文字でシンプルな名前を設定しておくことを推奨します。
これでIfの設定ができました。
次に「Then That」を選択します。
今度は「LINE」と入力し、いつも使っているLINEのロゴを選択します。
LINEのログインウィンドウが開くので、
自分のアカウント情報を入力してログインします。
LINE通知の同意取得画面が開くので、「同意して連携する」を選択します。
IFTTTの画面に戻ると、連携内容の設定画面に進んでいます。
「Recipient」では通知を受け取るグループを設定できます。
今回は1人で使うので、「1:1でLINE Notifyから通知を受け取る」を選択します。
「Message」ではLINEに送信されるメッセージを設定します。
グレー背景で「 Value1 」となっている部分には、
API実行時にリクエストボディに詰められた値がセットされます。
今回は下記で設定しておきます。
サーバー「{{Value1}}」のグローバルIPが更新されました!<br>
IPアドレス:<br>
{{Value2}}
なお、変数名「Value1」「Value2」「Value3」は固定で、
違う名前に変更することはできないようです。
設定が終わったら、「Create action」を選択します。
Applet Titleをよしなに変えて、「Finish」を選択します。
これで設定が完了しました。
手動でPOSTしてみる
試しにPostmanでMessageをPOSTしてみましょう。
まずはWebhookのURLを取得します。
https://ifttt.com/maker_webhooks
上記ページにアクセスし「Documentation」を選択します。
「Your key is:」の次に表示された文字列が、自分専用のWebhookキーです。
これを使ってPOSTを行います。
PostmanでRequestを新規作成し、URLを下記にします。
https://maker.ifttt.com/trigger/:event/with/key/:key
こうすると「Params」タブに「event」と「key」のパスパラメータ設定行が表示されるため、
「event」には先ほどIFTTTでWebhooksに設定したEvent Nameを、
「key」にはWebhookキーを入力します。
Bodyタブに移動し、「raw」「JSON」を選んで、リクエストボディをセットします。
{
"value1": "LocalServer",
"value2": "XXX.XXX.XXX.XXX"
}
「Send」を選択するとAPIが実行され、Responseが返ってきます。
無事通りました。
先ほどIFTTTで設定したメッセージが、POSTした値を含めて送られています。
これでAPI経由でLINE通知をすることができました。
サーバ側の実装
最後に、サーバ側の実装を行います。
なおサーバは、CentOS 7.8を使っています。
今回はShellを使って、
IPアドレスを取得→前回のIPアドレスと比較→差分があればPOST
を行います。
#!/bin/bash
FILE_GLOBAL_IP="${WORKSPACE}/GLOBAL_IP"
FILE_GLOBAL_IP_OLD="${WORKSPACE}/GLOBAL_IP_OLD"
if [ -f "${FILE_GLOBAL_IP}" ]; then
mv "${FILE_GLOBAL_IP}" "${FILE_GLOBAL_IP_OLD}"
else
touch "${FILE_GLOBAL_IP_OLD}"
fi
RESPONSE_STATUS=$( curl -sS ifconfig.io -o "${FILE_GLOBAL_IP}" -w "%{http_code}" )
if [ "${RESPONSE_STATUS}" != 200 ]; then
echo "ERROR! Response Status Is ${RESPONSE_STATUS}."
exit 1
fi
GLOBAL_IP=$( cat "${FILE_GLOBAL_IP}" )
GLOBAL_IP_OLD=$( cat "${FILE_GLOBAL_IP_OLD}" )
if [ "${GLOBAL_IP}" != "${GLOBAL_IP_OLD}" ]; then
curl -sS --request POST "https://maker.ifttt.com/trigger/ip/with/key/${IFTTT_WEBHOOK_KEY}" \
--header "Content-Type: application/json" \
--data-raw "{ \
\"value1\": \"LocalServer\", \
\"value2\": \"${GLOBAL_IP}\" \
}"
else
echo "SUCCESS : IP Addres has not chenged."
fi
最初のIF分岐で、
前回のグローバルIPがあれば退避、なければ空ファイル作成
という処理を行っています。
その後グローバルIPを取得してファイルに書き込み、
同時にHTTPステータスコードを取得して変数に詰めています。
グローバルIPの取得は、curl ifconfig.io
で出来ます。
IF分岐でHTTPステータスコードを確認し、200以外であれば異常終了します。
最後に、今回グローバルIPを書き出したファイルと、
最初に退避した前回のグローバルIPファイルをそれぞれcat
し、
中身を比較します。
一致しなければ、IFTTTのWebHooksに対し、
今回取得したグローバルIPをPOSTします。
Webhookキーは環境変数にセットしています。
私の場合、このサーバにJenkinsを立てているので、
Jenkinsからこのスクリプトを定期実行することにしました。
Jenkinsがない場合には、crontab
でスケジュール実行するのがおすすめです。
今回はここまで。
同じスキームを使うことで、これ以外にも、
サーバで検知したものを通知したい系が簡単に実現できます。
ぜひ活用してみてください。