feat: Spotify integration (OAuth + voice tools)
Some checks failed
Deploy / deploy (push) Failing after 1m40s
Some checks failed
Deploy / deploy (push) Failing after 1m40s
This commit is contained in:
44
app/api/spotify/callback/route.ts
Normal file
44
app/api/spotify/callback/route.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
export const dynamic = 'force-dynamic'
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { writeFileSync } from 'fs'
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const code = req.nextUrl.searchParams.get('code')
|
||||
if (!code) return NextResponse.json({ error: 'no code' }, { status: 400 })
|
||||
|
||||
const clientId = process.env.SPOTIFY_CLIENT_ID!
|
||||
const clientSecret = process.env.SPOTIFY_CLIENT_SECRET!
|
||||
const redirectUri = `${process.env.NEXT_PUBLIC_APP_URL}/api/spotify/callback`
|
||||
|
||||
const res = await fetch('https://accounts.spotify.com/api/token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
Authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
grant_type: 'authorization_code',
|
||||
code,
|
||||
redirect_uri: redirectUri,
|
||||
}),
|
||||
})
|
||||
|
||||
const data = await res.json()
|
||||
if (!data.refresh_token) {
|
||||
return NextResponse.json({ error: 'no refresh_token', data }, { status: 400 })
|
||||
}
|
||||
|
||||
// Save to file for extraction
|
||||
try {
|
||||
writeFileSync('/tmp/spotify_refresh_token.txt', data.refresh_token)
|
||||
} catch {}
|
||||
|
||||
return new NextResponse(`
|
||||
<html><body style="font-family:monospace;padding:2rem;background:#111;color:#1DB954">
|
||||
<h2>✅ Spotify авторизован!</h2>
|
||||
<p>Refresh Token:</p>
|
||||
<pre style="background:#222;padding:1rem;word-break:break-all">${data.refresh_token}</pre>
|
||||
<p style="color:#888">Скопируй токен и передай Cosmo для сохранения в .env</p>
|
||||
</body></html>
|
||||
`, { headers: { 'Content-Type': 'text/html' } })
|
||||
}
|
||||
Reference in New Issue
Block a user