1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Discord HTTP APIをPHPで使ってみる

Last updated at Posted at 2025-12-21

本記事は、めんどい太郎の Advent Calendar 2025 n日目の記事です。

はじめに

今回はPHPでDiscord HTTP APIを使ってみます。

今回はDiscordでWebサイトにログインできるような機能を実装してみます。

また、指定のサーバに入っているかどうかもチェックしてみたいと思います。

環境準備

Discordアプリの作成・設定

まずは、Discordアプリの作成が必要です。

Discord Developer Portalにアクセスします。

「New Application」をクリックします。

image.png

アプリ名を入力し、利用規約に同意してCreateを押してアプリを作成します。

image.png

「OAuth2アプリケーションの制限達しました」とエラーが表示された場合は既存のアプリを減らしましょう。

image.png

たぶんロボット認証が入ると思いますので、サクッと人間であることを証明しましょう。

そうしたら、アプリが作成されたと思います。

左のメニューにある「OAuth2」を選択します。

image.png

「Redirects」項目の「Add Redirect」を押します。

ここには、ログイン後のリダイレクト先を指定します。

今回は、http://localhost/DiscordAuthTEST/login/callback.phpとします。

image.png

入力後、設定を保存します。

image.png

こんな感じの成功メッセージが表示されればOKです。

image.png

次は、「Client information」項目です。

ここにある「Client ID」をメモしておきます。

また、「Client Secret」の「Reset Secret」を押します。

そうすると、「Client Secret」が表示されると思います。これをメモしておきます。

「OAuth2 URL Generator」項目に移動します。

Scopesで次の項目を選びます。(画像とは少し違います。)

  • identify
  • guilds

Select redirect URLで先ほど追加したリダイレクト先を指定します。

URLが生成されるので、これをメモしておきます。

image.png

PHP環境の準備

PHPの環境は各自準備してください。

例えばRaspberry PiにPHPをインストールする方法は昨日の記事で紹介しています。

ただ、昨日の記事ではphp-curlをインストールしていないので追加でインストールしておいてください。

コード実装

さっそく実装していきます。

ログインページの作成

まずは、ログインページを作成します。

といっても、ただ先ほど生成したURLへアクセスを促すページです。

ここはHTMLで書いてしまいます。

login/index.html
<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>Discord Login Test</title>
</head>
<body>
    <h1>Discordログインテスト</h1><br>
    <a href="<URL>">Login</a>
</body>
</html>

<URL>の部分には、先ほど生成したURLを入れます。

コールバック処理の作成

次に、ログイン後のコールバック処理を作成します。

login/callback.php
<?php
  session_start();
  $url = "<Application_URL>";
  $VERSION = "1.0.0";
  // DiscordアプリのClient IDとClient Secret
  $API_ENDPOINT = 'https://discord.com/api/v10';
  $CLIENT_ID = "<CLIENT_ID>";
  $CLIENT_SECRET = "<CLIENT_SECRET>";
  $REDIRECT_URI = "<REDIRECT_URI>";
  $SERVER_ID = "<CHECK_SERVER_ID>";
  // 認可コードを取得
  if (!isset($_GET['code'])) {
      echo "エラー: 再度ログインしなおしてください。<br>";
      echo '<a href="./">ログインページへ</a>';
      exit();
  };
  $code = $_GET['code'];
  // トークンエンドポイントにPOSTリクエストを送信してアクセストークンを取得
  $Auth = base64_encode($CLIENT_ID.':'.$CLIENT_SECRET);
  $data = array(
    'grant_type' => 'authorization_code',
    'code' =>  $code,
    'redirect_uri' =>  $REDIRECT_URI
  );
  $headers = array(
    'Content-Type: application/x-www-form-urlencoded',
    'User-Agent: DiscordWebAuth ('.$url.', '.$VERSION.')',
    'Authorization: Basic '.$Auth
  );
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $API_ENDPOINT . '/oauth2/token');
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $response = curl_exec($ch);
  curl_close($ch);
  $responseJSON = json_decode($response);
  if (isset($responseJSON->error)) {
      echo "エラー: トークンの取得に失敗しました。<br>";
      echo '<a href="./">ログインページへ</a>';
      exit();
  };
  $access_token = $responseJSON->access_token;
  // アクセストークンを使ってユーザ情報を取得
  $headers = array(
    'Content-Type: application/json',
    'User-Agent: DiscordWebAuth ('.$url.', '.$VERSION.')',
    'Authorization:Bearer '.$access_token
  );
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $API_ENDPOINT . '/users/@me');
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $response = curl_exec($ch);
  curl_close($ch);
  $userInfo = json_decode($response);
  if (!isset($userInfo->id)) {
    echo "エラー: ユーザ情報の取得に失敗しました。<br>";
    echo '<a href="./">ログインページへ</a>';
    exit();
  };
  // ユーザが指定のサーバに入っているか確認
  $headers = array(
    'Content-Type: application/json',
    'User-Agent: DiscordWebAuth ('.$url.', '.$VERSION.')',
    'Authorization:Bearer '.$access_token
  );
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $API_ENDPOINT . '/users/@me/guilds');
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $response = curl_exec($ch);
  curl_close($ch);
  $userGuilds = json_decode($response);
  if (isset($responseJSON->error)) {
    echo "エラー: ユーザ情報の取得に失敗しました。<br>";
    echo '<a href="./">ログインページへ</a>';
    exit();
  };
  foreach ($userGuilds as $guild) {
    if ($guild->id === $SERVER_ID) {
      $isInGuild = true;
      break;
    }
  }
  if (!$isInGuild) {
    echo "エラー: 指定のサーバに参加していません。<br>";
    echo '<a href="./">ログインページへ</a>';
    exit();
  }

  echo "<h1>ログイン成功!</h1><br>";
  echo "ユーザID: " . $userInfo->id . "<br>";
  echo "ユーザ名: " . $userInfo->username . "<br>";
  echo '<br><a href="./">ログインページへ</a>';

  // トークン失効
  $data = array(
    'token' => $access_token,
    'token_type_hint' => 'access_token'
  );
  $headers = array(
    'Content-Type: application/x-www-form-urlencoded',
    'User-Agent: DiscordWebAuth ('.$url.', '.$VERSION.')',
    'Authorization: Basic '.$Auth
  );
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $API_ENDPOINT . '/oauth2/token/revoke');
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $response = curl_exec($ch);
  curl_close($ch);
?>

ここで注意するのは、一部のAPIはBASIC認証でCLIENT_IDCLIENT_SECRETを渡してあげる必要がある点でしょうか。

アクセスしてみる

では、実際にアクセスしてみましょう。

http://localhost/DiscordAuthTEST/login/index.htmlにアクセスします。

image.png

「Login」リンクをクリックします。

Discordのアプリ認可画面が表示されます。

image.png

認証を押してログインします。

image.png

ログイン成功画面が表示されました。

いい感じですね!

おわりに

ということで、今回はPHPを使ってDiscordログインを実装してみました。

結構雑な記事になっちゃった...

Discord HTTP APIは他にも色々な機能があるので、ぜひ試してみてください。

それでは!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?