Integrating Discord API with Website (Notifications, Bots)
Discord is a popular platform for gaming and technical communities. Integration with a website enables: notifying the community about new content, verifying NFT or license ownership, creating exclusive channels for premium subscribers.
Discord Webhooks (Notifications)
class DiscordNotifier
{
public function send(string $webhookUrl, array $embeds): void
{
Http::post($webhookUrl, [
'embeds' => $embeds,
]);
}
public function announceNewArticle(Article $article): void
{
$this->send(config('services.discord.news_webhook'), [[
'title' => $article->title,
'description' => $article->excerpt,
'url' => route('articles.show', $article->slug),
'color' => 0x5865F2, // Discord Blurple
'image' => ['url' => $article->cover_url],
'timestamp' => $article->published_at->toIso8601String(),
'footer' => ['text' => 'example.com'],
]]);
}
}
OAuth2: Authorization via Discord
To access restricted sections of the site, authorize via Discord account:
Route::get('/auth/discord/redirect', function () {
return redirect(
'https://discord.com/api/oauth2/authorize?' .
http_build_query([
'client_id' => config('services.discord.client_id'),
'redirect_uri' => route('auth.discord.callback'),
'response_type' => 'code',
'scope' => 'identify guilds.members.read',
])
);
});
Route::get('/auth/discord/callback', function (Request $request) {
// Exchange code for token
$tokenResp = Http::post('https://discord.com/api/oauth2/token', [
'client_id' => config('services.discord.client_id'),
'client_secret' => config('services.discord.client_secret'),
'code' => $request->code,
'grant_type' => 'authorization_code',
'redirect_uri' => route('auth.discord.callback'),
])->json();
// Retrieve user data
$user = Http::withToken($tokenResp['access_token'])
->get('https://discord.com/api/users/@me')
->json();
// Check server membership
$member = Http::withToken($tokenResp['access_token'])
->get("https://discord.com/api/users/@me/guilds/{$guildId}/member")
->json();
return redirect('/dashboard');
});
Role Gating: Access by Discord Server Role
class DiscordRoleGate
{
public function hasAccess(string $userId, string $accessToken): bool
{
$member = Http::withToken($accessToken)
->get("https://discord.com/api/users/@me/guilds/{$this->guildId}/member")
->json();
$requiredRoles = config('services.discord.premium_role_ids');
return !empty(array_intersect($member['roles'] ?? [], $requiredRoles));
}
}
Timeline
Webhooks notifications: 1 day. OAuth2 + role-gating: 3–4 days.







