Zenn
💬

MinecraftサーバーログのDiscord通知スクリプト

に公開

概要

Minecraft Java Edition サーバーの稼働状況(プレイヤーのログイン・ログアウト、チャット内容)およびサーバーログ全体を、指定したDiscordチャンネルにリアルタイムで通知するBashスクリプトを作成する。これにより、ゲームクライアントを起動せずにサーバーの状態を確認することが可能になる。

既存のプラグインやスクリプトも存在するが、本稿では必要最低限の機能(ログのDiscordへの転送)を自作スクリプトで実装する方法を解説する。

動作環境

OS: Ubuntu 20.04.6 LTS (Focal Fossa)
他のLinuxディストリビューションでも同様の原理で動作する可能性がある。
実装する機能
サーバーへのプレイヤーログイン・ログアウト、およびゲーム内チャットをDiscordの特定チャンネルへ通知する。
サーバーログ(latest.log)の全内容を、上記とは別のDiscordチャンネルへ転送する。
上記2種類の通知は、それぞれ異なるDiscordチャンネルに送信されるようにする。
実装方法
DiscordのWebhook機能を利用して、スクリプトから指定チャンネルへメッセージを送信する。Minecraftサーバーは、サーバーログをlogs/latest.logファイルに追記していくため、このファイルを監視し、追記された内容をWebhook経由でDiscordへ送信することで機能を実現する。

設定手順

  1. Discordの設定
    通知を受け取りたいDiscordサーバー内に、通知用チャンネルを2つ作成する(例: minecraft-status, minecraft-log)。
    各チャンネルの「チャンネル設定」を開き、「連携サービス」(または「アプリ」>「ウェブフック」)を選択する。
    「新しいウェブフックを作成」ボタンをクリックし、ウェブフックを生成する。
    生成された「ウェブフックURL」をコピーし、後で使用するためにそれぞれ記録しておく。このURLは外部に漏洩しないよう注意すること。
  2. Bashスクリプトの作成
    以下の内容でBashスクリプトファイル(例: mc_discord_logger.sh)を作成する。
#!/bin/bash

# --- 設定項目 ---
# Discord Webhook URL (ログ全体用)
LOGGER_URL="手順1で取得したログ全体用Webhook URL"
# Discord Webhook URL (ログイン/チャット用)
CHAT_URL="手順1で取得したログイン/チャット用Webhook URL"
# 監視対象のログファイルパス (引数で受け取る)
LOG_PATH="$1"

# --- メイン処理 ---
# 指定されたログファイルの追記を監視
tail -F "$LOG_PATH" | while read -r line; do
  # 追記された行をログ全体用チャンネルに送信
  curl -H "Content-Type: application/json" \
          -X POST \
          -d "{\"content\": \"$line\"}" \
          $LOGGER_URL

  # 行の内容がチャットまたはログイン/ログアウト情報か判定
  if [[ "$line" == *"<"* ]] || [[ "$line" == *"the game"* ]]; then
    # 条件に一致する場合、ログイン/チャット用チャンネルにも送信
    curl -H "Content-Type: application/json" \
            -X POST \
            -d "{\"content\": \"$line\"}" \
            $CHAT_URL
  fi
done
スクリプト解説:

LOGGER_URL, CHAT_URL: 手順1で取得したDiscord Webhook URLをそれぞれ設定する。
LOG_PATH="$1": スクリプト実行時の第一引数で渡されるログファイルのパスを変数に格納する。
tail -F "$LOG_PATH": 指定されたファイル($LOG_PATH)の末尾を監視し、追記があった場合に出力する。-Fオプションは、ログローテーションなどでファイル名が変更されても追跡を続けるために使用する。

参考: tailコマンドの-fと-Fの違いについて
https://qiita.com/sakito/items/7f65e16f10b3d754f307

while read -r line; do ... done: tailコマンドの出力を1行ずつline変数に読み込み、ループ処理を行う。
curl ... $LOGGER_URL: line変数の内容をJSON形式のペイロードとして、LOGGER_URLにPOSTリクエストで送信する。これによりDiscordにメッセージが投稿される。
if [[ "$line" == *"<"* ]] || [[ "$line" == *"the game"* ]]; then ... fi: line変数に特定の文字列が含まれるか条件分岐を行う。
"<": Minecraftのチャットログに含まれる形式(例: <PlayerName> message)を検出する。
"the game": プレイヤーのログイン/ログアウトメッセージ(例: PlayerName joined the game, PlayerName left the game)を検出する。
条件に一致した場合のみ、CHAT_URLへも同じ内容を送信する。

  1. スクリプトの実行
    作成したスクリプトファイルをサーバー上に配置し、以下のコマンドで実行する。
bash /path/to/mc_discord_logger.sh /path/to/minecraft/server/logs/latest.log

/path/to/mc_discord_logger.sh: 作成したスクリプトファイルの絶対パスまたは相対パスを指定する。
/path/to/minecraft/server/logs/latest.log: 監視対象となるMinecraftサーバーのlatest.logファイルの絶対パスを指定する。
スクリプトが正常に起動すれば、ログファイルの監視が開始され、Discordへの通知が行われる。

永続的な実行:

このスクリプトはフォアグラウンドで実行されるため、実行中のターミナルセッションが終了するとスクリプトも停止する。サーバー稼働中、常にスクリプトを実行状態にしておくためには、screenやtmuxといったターミナルマルチプレクサを使用するか、systemd等でサービスとしてバックグラウンド実行させる必要がある。

まとめ

本稿では、BashスクリプトとDiscord Webhookを用いて、Minecraftサーバーのログを指定されたDiscordチャンネルに転送する方法を解説した。
tailコマンドによるファイル監視とcurlコマンドによるWebhook送信、そして簡単な文字列判定を組み合わせることで、目的の機能を実現できることを学んだ。さらに必要に応じて、スクリプトを改変し、通知内容のフィルタリングやフォーマット変更などを加えることも可能であると推測できる。

まとめ2

ここまで、原文は自分で書きましたが、Gemini2.5を使用して推敲を行ってもらいました。
一応前回自分で書いた記事のリンクも載せておきます。(ダイレクトアクセス稼ぎ)

https://zenn.dev/enumh/articles/832b6c5ff8307b

やっぱり自分で文章を書くよりもAIに頼った方が分かりやすい文章が書けるものなんですかね~
それでは、(o-o-)ノシ

Discussion

ログインするとコメントできます