YT Music-koppling i settings: Googles device-flöde inbyggt
All checks were successful
build-and-push / build (push) Successful in 16s
All checks were successful
build-and-push / build (push) Successful in 16s
- POST /api/ytmusic/start + /poll: kör device-flödet mot Google och skriver ytmusicapi-kompatibel oauth.json till Youtubarrs datamapp (mounten byts till rw i stacken) - Settings-sektion: Client ID/secret, 'Spara & koppla' visar kod + länk och pollar tills godkänt; 'Testa kopplingen' verifierar med en token-förnyelse mot Google - 4 nya tester, totalt 21 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01824ZrvG2mDYYrmwqypLNup
This commit is contained in:
@@ -11,6 +11,7 @@ import { mbClient } from './musicbrainz.js'
|
||||
import { mapLidarrSearch } from './mapping.js'
|
||||
import { settingsStore } from './settings.js'
|
||||
import { makeTesters } from './testers.js'
|
||||
import { ytmusicFlow } from './ytmusic.js'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
@@ -28,6 +29,7 @@ export function buildApp(config, deps = {}) {
|
||||
const mb = deps.musicbrainz ?? mbClient()
|
||||
const store = deps.store ?? settingsStore(config.dataDir ?? '/data')
|
||||
const testers = deps.testers ?? makeTesters({ config, store })
|
||||
const ytmusic = deps.ytmusic ?? ytmusicFlow({ config, store })
|
||||
const app = Fastify({ logger: true, trustProxy: true })
|
||||
|
||||
app.register(fastifyCookie)
|
||||
@@ -157,6 +159,11 @@ export function buildApp(config, deps = {}) {
|
||||
userId: s.jellyfin?.userId ?? '',
|
||||
userName: s.jellyfin?.userName ?? '',
|
||||
},
|
||||
ytmusic: {
|
||||
clientIdSet: Boolean(s.ytmusic?.clientId),
|
||||
clientSecretSet: Boolean(s.ytmusic?.clientSecret),
|
||||
connected: existsSync(ytmusic.oauthPath),
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
@@ -171,10 +178,36 @@ export function buildApp(config, deps = {}) {
|
||||
userId: body.jellyfin?.userId,
|
||||
userName: body.jellyfin?.userName,
|
||||
},
|
||||
ytmusic: {
|
||||
clientId: body.ytmusic?.clientId,
|
||||
clientSecret: body.ytmusic?.clientSecret,
|
||||
},
|
||||
})
|
||||
return { ok: true }
|
||||
})
|
||||
|
||||
app.post('/api/ytmusic/start', async (req, reply) => {
|
||||
try {
|
||||
const out = await ytmusic.start()
|
||||
if (out.error) return reply.code(400).send(out)
|
||||
return out
|
||||
} catch (err) {
|
||||
req.log.error({ err }, 'device-flödet kunde inte startas')
|
||||
return reply.code(502).send({ error: 'kunde inte nå Google' })
|
||||
}
|
||||
})
|
||||
|
||||
app.post('/api/ytmusic/poll', async (req, reply) => {
|
||||
const deviceCode = req.body?.deviceCode
|
||||
if (!deviceCode) return reply.code(400).send({ error: 'deviceCode saknas' })
|
||||
try {
|
||||
return await ytmusic.poll(deviceCode)
|
||||
} catch (err) {
|
||||
req.log.error({ err }, 'device-poll misslyckades')
|
||||
return reply.code(502).send({ error: 'kunde inte nå Google' })
|
||||
}
|
||||
})
|
||||
|
||||
app.post('/api/settings/test', async (req, reply) => {
|
||||
const service = req.body?.service
|
||||
if (!testers[service]) return reply.code(400).send({ error: 'okänd tjänst' })
|
||||
|
||||
Reference in New Issue
Block a user