如何使用PHP通过Discord服务器ID生成Discord服务器邀请链接
实现步骤
1. 准备Discord开发者资源
- 注册Discord开发者账号,创建Bot并获取Bot Token
- 给Bot分配权限:需要
Create Invite(创建邀请)权限,将Bot加入目标服务器
2. 数据库设计
创建表存储用户与Discord服务器的关联信息,示例SQL:
CREATE TABLE user_discord_servers ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, -- 关联你的网站用户ID guild_id VARCHAR(255) NOT NULL, -- Discord服务器ID invite_code VARCHAR(255), -- 存储邀请码(非完整链接) last_checked DATETIME DEFAULT CURRENT_TIMESTAMP, expires_at DATETIME, -- 邀请过期时间(永久邀请设为null) UNIQUE KEY (user_id, guild_id) );
3. 用户保存服务器ID功能
处理用户提交的服务器ID,验证有效性后存入数据库:
<?php // 从表单获取用户提交的服务器ID $guildId = $_POST['discord_guild_id']; $userId = $_SESSION['user_id']; // 你的网站用户会话ID // 验证服务器ID有效性 $botToken = '你的Discord Bot Token'; $apiUrl = "https://discord.com/api/v10/guilds/{$guildId}"; $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bot {$botToken}", "Content-Type: application/json" ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $guildData = json_decode($response, true); if (isset($guildData['id'])) { // 服务器有效,写入数据库(已存在则更新) $pdo = new PDO('mysql:host=localhost;dbname=your_db', 'db_user', 'db_pass'); $stmt = $pdo->prepare("INSERT INTO user_discord_servers (user_id, guild_id) VALUES (?, ?) ON DUPLICATE KEY UPDATE guild_id=VALUES(guild_id)"); $stmt->execute([$userId, $guildId]); echo "服务器ID已保存"; } else { echo "无效的服务器ID,或Bot未加入该服务器"; } ?>
4. 获取并维护有效邀请链接
方法1:实时生成/验证(适合小流量场景)
在个人资料页面加载时,检查现有邀请有效性,无效则重新生成:
<?php function getValidDiscordInvite($guildId, $botToken) { $pdo = new PDO('mysql:host=localhost;dbname=your_db', 'db_user', 'db_pass'); // 查询现有邀请 $stmt = $pdo->prepare("SELECT invite_code, expires_at FROM user_discord_servers WHERE guild_id = ?"); $stmt->execute([$guildId]); $row = $stmt->fetch(PDO::FETCH_ASSOC); $now = new DateTime(); // 检查邀请是否存在且未过期 if ($row && $row['invite_code'] && ($row['expires_at'] === null || new DateTime($row['expires_at']) > $now)) { // 验证邀请有效性 $apiUrl = "https://discord.com/api/v10/invites/{$row['invite_code']}"; $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bot {$botToken}"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode === 200) { return "https://discord.gg/{$row['invite_code']}"; } } // 生成新的永久邀请 // 获取服务器文本频道ID $apiUrl = "https://discord.com/api/v10/guilds/{$guildId}/channels"; $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bot {$botToken}"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $channels = json_decode($response, true); $channelId = null; foreach ($channels as $channel) { if ($channel['type'] === 0) { // 文本频道 $channelId = $channel['id']; break; } } if ($channelId) { $apiUrl = "https://discord.com/api/v10/channels/{$channelId}/invites"; $postData = json_encode([ 'max_age' => 0, // 永久有效 'max_uses' => 0, // 不限次数 'temporary' => false, 'unique' => false ]); $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bot {$botToken}", "Content-Type: application/json" ]); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $inviteData = json_decode($response, true); if (isset($inviteData['code'])) { // 更新数据库 $stmt = $pdo->prepare("UPDATE user_discord_servers SET invite_code = ?, expires_at = ?, last_checked = NOW() WHERE guild_id = ?"); $stmt->execute([$inviteData['code'], null, $guildId]); return "https://discord.gg/{$inviteData['code']}"; } } return null; } // 在个人资料页面调用 $botToken = '你的Discord Bot Token'; $userId = $_SESSION['user_id']; $pdo = new PDO('mysql:host=localhost;dbname=your_db', 'db_user', 'db_pass'); $stmt = $pdo->prepare("SELECT guild_id FROM user_discord_servers WHERE user_id = ?"); $stmt->execute([$userId]); $guilds = $stmt->fetchAll(PDO::FETCH_COLUMN); foreach ($guilds as $guildId) { $inviteLink = getValidDiscordInvite($guildId, $botToken); if ($inviteLink) { echo "<a href='{$inviteLink}' target='_blank'>加入我的Discord服务器</a>"; } else { echo "无法获取有效邀请链接"; } } ?>
方法2:定时任务更新(适合大流量场景)
用Cron定时运行脚本批量更新邀请,避免页面加载时频繁调用API:
<?php // cron_invite_updater.php $botToken = '你的Discord Bot Token'; $pdo = new PDO('mysql:host=localhost;dbname=your_db', 'db_user', 'db_pass'); // 获取所有需要检查的服务器 $stmt = $pdo->query("SELECT id, guild_id, invite_code, expires_at FROM user_discord_servers"); $servers = $stmt->fetchAll(PDO::FETCH_ASSOC); $now = new DateTime(); foreach ($servers as $server) { $needsUpdate = false; $newInviteCode = $server['invite_code']; $newExpiresAt = $server['expires_at']; // 判断是否需要更新邀请 if (!$server['invite_code'] || ($server['expires_at'] && new DateTime($server['expires_at']) <= $now)) { $needsUpdate = true; } else { $apiUrl = "https://discord.com/api/v10/invites/{$server['invite_code']}"; $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bot {$botToken}"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200) { $needsUpdate = true; } } if ($needsUpdate) { // 生成新邀请,逻辑同实时方法 $apiUrl = "https://discord.com/api/v10/guilds/{$server['guild_id']}/channels"; $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bot {$botToken}"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $channels = json_decode($response, true); $channelId = null; foreach ($channels as $channel) { if ($channel['type'] === 0) { $channelId = $channel['id']; break; } } if ($channelId) { $apiUrl = "https://discord.com/api/v10/channels/{$channelId}/invites"; $postData = json_encode([ 'max_age' => 0, 'max_uses' => 0, 'temporary' => false, 'unique' => false ]); $ch = curl_init($apiUrl); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bot {$botToken}", "Content-Type: application/json" ]); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $inviteData = json_decode($response, true); if (isset($inviteData['code'])) { $newInviteCode = $inviteData['code']; $newExpiresAt = null; } } // 更新数据库 $stmt = $pdo->prepare("UPDATE user_discord_servers SET invite_code = ?, expires_at = ?, last_checked = NOW() WHERE id = ?"); $stmt->execute([$newInviteCode, $newExpiresAt, $server['id']]); } } ?>
设置Cron任务(每天凌晨运行一次):
0 0 * * * /usr/bin/php /path/to/cron_invite_updater.php
5. 注意事项
- 不要将Bot Token暴露在前端,建议存储在服务器环境变量中
- 处理Discord API限流:避免短时间内大量请求,可添加请求间隔控制
- 可选:通过Discord OAuth2验证用户对服务器的所有权,防止恶意提交
- 完善错误处理:捕获API调用失败、数据库操作异常等情况,给用户合理提示
内容的提问来源于stack exchange,提问作者Krzheski
相关产品推荐
相关产品推荐

