読者です 読者をやめる 読者になる 読者になる

[Mac]自宅のIPアドレスの変更を検出してLINEに通知するコピペスクリプト

その他 その他-Mac
更新履歴


MacグローバルIPアドレスの変更を自動で検出し、LINE Notifyで通知を出すシェルスクリプトと設置方法を紹介します。

f:id:four_or_three:20161102205712p:plain:w250

Workflowは記事の最後のほうに申し訳程度に出てきます。

作業の手順
  1. LINE Notifyのパーソナルアクセストークンを取得
  2. グローバルIPアドレスをチェックして変更があればLINEに通知を出すシェルスクリプト」をコピペで作る
  3. 2のスクリプトを定期的に実行するためのplistファイルをコピペで作る
  4. ワークフローの設定
  5. 3のplistファイルをロードしてIPアドレスの監視を開始

それではいきます。

1.パーソナルアクセストークンを取得

やり方はQiitaのこの記事で詳しく説明されています。
qiita.com
いきなり丸投げで恐縮ですが、これよりわかりやすく書く自信はありません。
下のほうのコードが書いている手前あたりまで読めば大丈夫です。

補足事項。

トークンは何度でも取得しなおすことができます。
通知名が気に入らなかったり、トークンを控えたメモがどこかにいってしまったりした場合は、削除して新たに発行します。

2.シェルスクリプト作成

2.0 このスクリプトがやること
  • MacグローバルIPアドレスをチェックし、変更があればLINEに通知を出す
  • 何らかの理由でアドレスの取得に5回続けて失敗した場合も通知を出す
    (アドレスの取得に利用しているWebサイトは、バックアップを含めて3つ)
  • 何らかの理由でLINEへの通知に失敗した場合はMacのローカル通知を出す

シェルはbashです。AppleScriptが混じっていますのでMac専用ですが、手直しすれば他の環境でも使えると思います。(って当たり前か)

2.1 ファイル一式を保存するフォルダを作る

スクリプトファイルを作成する前に、スクリプトファイル本体、IPアドレスの比較のためのテキストファイル、実行ログを保存するためのフォルダを作っておきます。

特にこだわりがなければ、/Users/ユーザ名/Documents/IPアドレス監視にしておくと、この後の作業が楽になります。
ここから先は、このフォルダを作成したものとして説明を進めます。

2.2 スクリプトファイルの作成

下のコードをコピーし、テキストエディタに貼り付けます。

(2017年2月19日修正)

#!/bin/bash

# IPアドレスを保存するテキストファイルのフルパス
readonly FILE_PATH="${HOME}/Documents/IPアドレス監視/LastAddress.txt"
# LINE Notifyのパーソナルアクセストークン
readonly TOKEN="your token"
# LINEへの通知に追記するURL 不要なら空にしておく
readonly NOTIFICATION_URL="workflow://run-workflow?name=LINE%20to%20URL&input="

readonly URL_ARR=("ifconfig.io" "inet-ip.info" "ipcheck.ieserver.net")

function get_address() {
    curl -Ss -f "$1"
}

function post_to_line() {
    for line in "$@"
    do
        local joined_str+="\n$line"
    done
    local body=$(echo -e "$joined_str")
    curl -f -X POST \
        -H "Authorization: Bearer $TOKEN" \
        -F "message=$body" \
        https://notify-api.line.me/api/notify
}

function notify_mac() {
    osascript -e '
      on run argv
          set the_message to (item 1 of argv) & return & (item 2 of argv)
          display notification the_message with title "IPアドレス監視スクリプトより通知" sound name "Basso"
      end run
  ' "$1" "$2"
}

function save_txt() {
    : > "$FILE_PATH"
    for line in "$@"
    do
        echo "$line" >> "$FILE_PATH" 
    done
}

if [ ! -e "$FILE_PATH" ]; then
    save_txt "0.0.0.0" "0"
fi

readonly LAST_ADDRESS=$(sed -n 1p "$FILE_PATH")
error_times=$(sed -n 2p "$FILE_PATH")

for url in "${URL_ARR[@]}"
do
    current_address=$(get_address "$url")
    if [ $? != 0 ] || [ -z "$current_address" ]; then
        current_address="fail"
    else
        break
    fi
done

if [ $LAST_ADDRESS = "0.0.0.0" ]; then
    if [ "$current_address" = "fail" ]; then
        message="IPアドレスの取得に失敗しました。"
        post_to_line "$message"
        if [ $? != 0 ]; then
            message1="IPアドレスの取得に失敗しました。"
            message2="LINEへの通知に失敗しました。"
            notify_mac "$message1" "$message2"
        fi
    else
        message="IPアドレスの監視を開始しました。"
        post_to_line "$message"
        if [ $? != 0 ]; then
            message1="IPアドレスの監視を開始しました。"
            message2="LINEへの通知に失敗しました。"
            notify_mac "$message1" "$message2"
        fi
        save_txt "$current_address" "0"
    fi
elif [ "$current_address" = "fail" ]; then
    ((error_times++))
    if [ "$error_times" -ge 5 ]; then
        message="IPアドレスの取得に${error_times}回続けて失敗しました。"
        post_to_line "$message"
        if [ $? != 0 ]; then
            message1="IPアドレスの取得に${error_times}回続けて失敗しました。"
            message2="LINEへの通知に失敗しました。"
            notify_mac "$message1" "$message2"
        fi
        save_txt "$LAST_ADDRESS" "0"
    else
        save_txt "$LAST_ADDRESS" "$error_times"
    fi
elif [ "$current_address" != "$LAST_ADDRESS" ]; then
    if [ -z "$NOTIFICATION_URL" ]; then
        url=""
    elif [ $(echo "$NOTIFICATION_URL" | grep -E '^workflow') ]; then
        url="$NOTIFICATION_URL$current_address"
    else
        url="$NOTIFICATION_URL"
    fi
    message_arr=("IPアドレスが変更されています。" "前のアドレス" \
        "$LAST_ADDRESS" "現在のアドレス" "$current_address" "$url")
    post_to_line "${message_arr[@]}"
    if [ $? != 0 ]; then
        message1="IPアドレスが変更されています。LINEへの通知に失敗しました。"
        message2="[新しいアドレス]$current_address"
        notify_mac "$message1" "$message2"
    fi
    save_txt "$current_address" "0"
else
    save_txt "$current_address" "0"
fi
  • テキストの文字コードUTF-8、改行コードはLFに設定
    これを間違うと動きません。

  • 4行目に、IPアドレス比較のためのテキストファイルをフルパスで記入
    2.1でフォルダを違うものにしていなければ、初期設定値のままでOKです。

  • 6行目に、1で取得したパーソナルアクセストークンを記入

  • 8行目に、LINEへの通知に追記するURLを設定
    初期設定値は、記事の最後のほうで紹介するワークフローの起動URLになっています。

記入を終えたら、2.1で作成したフォルダに「CheckAddress.sh」というファイル名で保存します。
スクリプトファイルの作成が完了しました。

3.plistファイルの作成

下のコードをコピーし、テキストエディタに貼り付けます。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>monitor.ip.address</string>

  <key>ProgramArguments</key>
  <array>
    <string>bash</string>
    <string>/Users/ユーザ名/Documents/IPアドレス監視/CheckAddress.sh</string>
  </array>

  <key>RunAtLoad</key>
  <true/>

  <key>StartInterval</key>
  <integer>600</integer>

  <key>StandardOutPath</key>
  <string>/Users/ユーザ名/Documents/IPアドレス監視/stdout.log</string>
  <key>StandardErrorPath</key>
  <string>/Users/ユーザ名/Documents/IPアドレス監視/stderror.log</string>
</dict>
</plist>
  • テキストの文字コードUTF-8

  • 11行目に、2で作成したスクリプトファイルのフルパスを記入
    ユーザ名の部分にユーザ名を書き入れます。

  • 18行目の数字で、何秒ごとにIPアドレスをチェックするか設定

  • 21行目、24行目にログファイルのフルパスを記入
    ユーザ名の部分にユーザ名を書き入れます。

記入を終えたら、/Users/ユーザ名/Library/LaunchAgentsに「monitor.ip.address.plist」という名前で保存します。
plistファイルの作成が完了しました。

plistファイルをいろいろ編集したい場合の参考ページ

qiita.com

4.ワークフローの設定

LINEに通知されたリンクから起動し、新しいIPアドレスクリップボードにコピーしてURLを開くワークフローです。

f:id:four_or_three:20161102210446p:plain:w250

URLに、Googleアナリティクスのフィルター編集のページや、VPNの設定を開くURLなどを設定しておくといいかと思います。
ワークフロー名を変更する場合は、シェルスクリプト8行目のNOTIFICATION_URLも修正する必要がありますのでご注意。

このワークフローの使用は必須ではありません。不要の場合は、シェルスクリプト8行目のNOTIFICATION_URLを別のURLに書き換えたり空にしたりしてください。

インポート

https://workflow.is/workflows/094e68fe97eb485da7de59ea1efa4405

5.plistファイルのロード

ターミナル.appを開き、

launchctl load ~/Library/LaunchAgents/monitor.ip.address.plist


を実行します。

LINE Notifyから開始の通知が来れば、監視スクリプトの設置は完了です。
お疲れ様でした。


監視を止める場合は、ターミナルで

launchctl unload ~/Library/LaunchAgents/monitor.ip.address.plist


を実行します。
monitor.ip.address.plistを編集した後も、いったんunloadして再びloadする必要があります。

広告を非表示にする