cronジョブの結果をAndroidに通知する

夜間レポートやバックアップなど、定期ジョブの終了コードを通知します。

QuickStart

必要な環境: Linuxのユーザーcron + Bash + curl

  1. AndroidにQueueRingをインストールし、端末登録と通知の許可を済ませて、現在のQueue IDをコピーします。端末をオンラインにしてください。
  2. ID保存 → 2ファイル作成 → 本体準備 → 定期実行
  3. 端末で結果を確認する

Queue IDは送信権限を与える秘密です。公開せず、漏えい時はアプリで再発行して設定を更新してください。秘密管理の詳細。

202は受理のみで、端末表示・履歴保存・IDの有効性は保証されません。再送により重複する場合があります。再試行は通知だけにし、ジョブやagentをやり直さないでください。HTTPエラーと再試行の対処。

1. Queue IDを一度だけ保存する

Bashに貼り付け — Queue IDを秘密ファイルに保存
install -d -m 700 "$HOME/.config/queuering"
(
  set +x
  umask 077
  read -r -s -p 'Paste the Queue ID from your Android app: ' QUEUE_ID
  printf '\n'
  [[ "$QUEUE_ID" =~ ^qr1\.[A-Za-z0-9_-]{1,16}\.[A-Za-z0-9_-]{59}$ ]] || exit 1
  printf '%s\n' "$QUEUE_ID" > "$HOME/.config/queuering/queue-id"
  chmod 600 "$HOME/.config/queuering/queue-id"
)

ボタンはコードだけをコピーします。使えない場合はコードを選択して手動でコピーしてください。コード内の表示メッセージは英語版と共通です。

送信元の端末でBashに貼り付け、非表示のプロンプトへIDを入力してください。リポジトリの外に、権限を制限して保存します。

2. 送信スクリプトとラッパーを作成する

$HOME/.local/binにnotify-android.shとnightly-with-alert.shを作成します。実行前に、exit 0だけの無害な確認用ジョブを$HOME/.local/bin/nightly-job.shへ保存してください。既存の実ジョブがある場合は先に内容を確認し、通知テストのために上書きしたりバックアップをやり直したりしないでください。同じcronユーザーで手動確認してから定期実行します。

Bashに貼り付けると、両方の保存先が未使用の場合だけ2ファイルを作成します。開始時の確認でどちらかが存在すれば、書き込み前に停止します。既存スクリプトがこのレシピと一致するか確認してから使うか、未使用の名前を選び、埋め込まれたラッパーを含むセットアップと実行コマンドの対応する全パスを変更してください。再試行のためにカスタムスクリプトを削除しないでください。HTTP送信と本体の終了コード維持を分けるための2ファイルです。ID設定が欠落・読取不能でも、スキップするのは通知だけです。

Bashに貼り付け — 2つのスクリプトを作成
(
  set -eu
  umask 077
  for file in "$HOME/.local/bin/notify-android.sh" "$HOME/.local/bin/nightly-with-alert.sh"; do
    if [[ -e "$file" || -L "$file" ]]; then
      printf 'Setup stopped: %s already exists. Existing files were kept. Review them before continuing.\n' "$file" >&2
      exit 1
    fi
  done
  install -d -m 700 "$HOME/.local/bin"
  set -C
  cat > "$HOME/.local/bin/notify-android.sh" <<'QUEUERING_SENDER'
#!/usr/bin/env bash
set +x
set -eu
set +x
: "${QUEUE_ID:?Load your Queue ID before sending}"
[[ "$QUEUE_ID" =~ ^qr1\.[A-Za-z0-9_-]{1,16}\.[A-Za-z0-9_-]{59}$ ]] || {
  printf 'Invalid Queue ID format; copy it from the app.\n' >&2
  exit 1
}
: "${1:?Pass a short notification message}"
message=$1
status=$(curl --silent --connect-timeout 10 --max-time 30 \
  --output /dev/null --dump-header /dev/stderr --write-out '%{http_code}' \
  --request POST "https://api.queuering.org/q/$QUEUE_ID" \
  --header 'Content-Type: text/plain; charset=utf-8' \
  --data-binary "$message") || {
  printf 'Notification transport failed; check connectivity.\n' >&2
  exit 1
}
printf 'Notification HTTP %s\n' "$status" >&2
[[ "$status" == 202 ]]
QUEUERING_SENDER
  cat > "$HOME/.local/bin/nightly-with-alert.sh" <<'QUEUERING_WRAPPER'
#!/usr/bin/env bash
set +x
set -eu
PATH=/usr/local/bin:/usr/bin:/bin
export PATH
result=0
bash "$HOME/.local/bin/nightly-job.sh" || result=$?
if ! IFS= read -r QUEUE_ID < "$HOME/.config/queuering/queue-id"; then
  printf 'Notification skipped: cannot read Queue ID configuration.\n' >&2
elif ! QUEUE_ID="$QUEUE_ID" bash "$HOME/.local/bin/notify-android.sh" "Nightly job finished (exit $result)"; then
  printf 'Notification failed; the cron job exit code is preserved.\n' >&2
fi
exit "$result"
QUEUERING_WRAPPER
)

3. テストを実行する

セットアップが成功したか、既存スクリプトがこのレシピと一致することを確認してから進んでください。

Bashに貼り付け — ラッパーを実行
bash "$HOME/.local/bin/nightly-with-alert.sh"
echo $?

端末で結果を確認する

確認用のnightly-job.shをexit 0、次にexit 7という無害な内容にし、bash "$HOME/.local/bin/nightly-with-alert.sh"を実行します。端末の通知とecho $?(0または7)を確認してください。一時的に直近の時刻で実行する設定にし、cronユーザーのHOME・PATH・権限・時計とタイムゾーン・ログ出力先を確認してから、夜間のスケジュールを使います。

HTTP 202が返っても端末に通知が出ない場合は、現在のQueue ID・Androidの通知権限・端末の接続状態を先に確認してください。アプリの最近の履歴は追加の確認材料であり、配信を証明する受領記録ではありません。

次にcronへ登録する(手動確認が成功したら)

cronへの登録手順と連携の制限

連携の手順と制限

Bashとcurlがあり、ユーザーのcronサービスが稼働しているLinuxホストが必要です。cronユーザーがQueue IDの秘密ファイルとスクリプトを所有してください。

ラッパーを定期実行する

同じユーザーでcrontab -eを使います。例はcronデーモンに設定されたタイムゾーンの02:00に実行します。ログにはジョブ出力とHTTPヘッダーが含まれるので、非公開にし、本体ジョブから認証情報を出力しないでください。

Bashに貼り付け — 非公開ログを準備
install -d -m 700 "$HOME/.local/state/queuering"
(umask 077; touch "$HOME/.local/state/queuering/cron.log")
chmod 600 "$HOME/.local/state/queuering/cron.log"

crontab -e に保存 — 02:00に実行
0 2 * * * /bin/bash "$HOME/.local/bin/nightly-with-alert.sh" >> "$HOME/.local/state/queuering/cron.log" 2>&1

実際に実行され、終了して戻ったジョブの結果を通知する例です。未実行のジョブ、cronの無効化、コマンドのハング、ホスト停止、ネットワーク断は検知できません。未実行やホスト停止の検知には、独立した外部監視やheartbeatの期限判定が必要です。ジョブの重複実行は避けてください。この例ではロック・実行期限・未実行検知サービスを追加していません。

Queue IDの秘密管理の詳細

Queue IDを秘密として管理する

Queue IDを知る人は端末に通知を送れます。送信権限を与える認証情報として扱い、実IDを公開リポジトリ・Issue・ログ・スクリーンショット・プロンプト・サンプルの固定値に載せないでください。シェルトレース(set -x)、curlのverbose/trace出力、共有するターミナル録画は使わないでください。URLやプロセスの引数にIDが含まれるため、信頼できる端末でだけ実行し、プロキシやアクセスログへの記録も制限してください。

漏えいした場合は、アプリでQueue IDを再発行し、古いIDを使うすべてのローカル設定やActions secretsを更新してください。古い値を編集せず、アプリから新しい値をコピーします。202応答では古いIDがまだ有効かどうかを確認できません。

API契約・HTTPエラー・再試行

応答の意味と安全な再試行

通知とメッセージ履歴はベストエフォートです。HTTP 202はリクエストの受理を示し、Androidでの表示や履歴への保存を保証しません。無効・非アクティブ・古いQueue IDにも意図的に同じ202を返すため、IDの有効性も判断できません。履歴には端末で取得できたメッセージを最大100件保存します。履歴にないことだけでは、HTTP処理の失敗とは判断できません。

送信先はPOST https://api.queuering.org/q/{queueId}です。UTF-8のtext/plain; charset=utf-8、またはapplication/jsonを使います。JSONでは空でないbody文字列が必須で、titleは任意ですが、指定する場合は空白だけにしないでください。JSON構文も含めたリクエスト本文全体の上限は4096 bytesです。

HTTP応答と次に行うこと
結果対処
202Androidの通知権限・接続状態と、アプリの現在のQueue IDを確認します。通知が表示されないという理由だけで再送しないでください。
400リクエスト、Content-Type、JSON構文、必須フィールドを修正してから再送します。
413UTF-8本文を4096 bytes以下に短くします。JSONのエスケープも容量に含まれます。
429Retry-Afterがあれば、指定された秒数以上待ちます。なければ待ち時間を増やしながら、回数を制限して再試行します。短い間隔で繰り返さないでください。
503一時的に利用できません。障害を確認し、待ち時間を増やしながら、回数を制限して後で再試行します。
通信失敗・タイムアウト結果が不明な場合があります。接続状態を確認してから再送するか判断してください。

サンプルは接続タイムアウト10秒・全体タイムアウト30秒で1回だけ送信します。HTTPステータスとRetry-Afterを含む応答ヘッダーを出力し、自動では再試行しません。再送すると通知が重複する可能性があります。この例には冪等性キーはありません。再試行するのは通知だけにし、状態を知らせるためにバックアップ・デプロイ・agentの本体処理をやり直さないでください。通常のジョブログや監視を判断の根拠にしてください。

ほかのレシピを試す

すべてのレシピ · QueueRingのホーム