Skip to content

About

Tool used to create playlist in the Spotify from text list.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

Spotify Playlist Creator

Um MVP local que transforma uma lista de músicas em texto simples (uma música por linha, por exemplo Artista - Título) em uma playlist no Spotify. Ele procura no catálogo do Spotify, pontua cada resultado em relação ao que você digitou e, então, seleciona automaticamente a melhor correspondência ou a marca para revisão.

Pré-requisitos

  • Node.js >= 20
  • Para o Spotify (padrão): uma conta do Spotify e um Client ID de aplicativo do Spotify do Spotify Developer Dashboard. Nenhum client secret é necessário — a autenticação usa o fluxo de Código de Autorização com PKCE.
  • Para o YouTube (opcional): um projeto no Google Cloud Console com a YouTube Data API v3 habilitada e um OAuth 2.0 Client ID do tipo confidential. O suporte ao YouTube só é ativado quando GOOGLE_CLIENT_ID e GOOGLE_CLIENT_SECRET estão definidos; caso contrário, o app roda apenas com Spotify.

Configuração

  1. Instale as dependências:

    npm install
  2. Copie o arquivo de exemplo de configuração e preencha seu Client ID:

    cp .env.example .env

    A URI de redirecionamento deve corresponder exatamente à que você cadastrou no Dashboard:

    http://127.0.0.1:3000/auth/callback
    
  3. Inicie o servidor de API e a interface web:

    npm run dev

    A API ouve em http://127.0.0.1:3000 e a interface web em http://127.0.0.1:5173. Abra a interface, clique em Login, conclua a tela de consentimento do Spotify e volte ao app.

Habilitando o YouTube (opcional)

O YouTube/Google é um segundo provedor, à frente de um dropdown de Platform na interface. É ativado somente quando as credenciais do Google estão presentes:

  1. No Google Cloud Console, crie (ou selecione) um projeto.

  2. Em APIs & Services → Library, ative a YouTube Data API v3 (necessária para a busca/criação de playlist).

  3. Em APIs & Services → OAuth consent screen, configure o app: escolha External (ou Internal para conta de trabalho/educação), preencha os dados e, enquanto estiver em Testing, adicione seu e-mail como tester — senão a autorização do Google é recusada.

  4. Em APIs & Services → Credentials → Create credentials → OAuth client ID, crie uma credencial do tipo Web application e registre:

    • Authorized JavaScript origins — a origem da interface web:

      • desenvolvimento: http://127.0.0.1:5173
      • produção: a origem onde a SPA é servida (ex.: http://127.0.0.1:3000)
    • Authorized redirect URIs — a URI que o servidor usa:

      http://127.0.0.1:3000/api/auth/youtube/callback
      

    A redirect URI cadastrada deve casar exatamente com a que o servidor envia. Se você sobrescrever GOOGLE_REDIRECT_URI (ou rodar em outra porta/host), cadastre essa mesma URI aqui, ou o Google recusa o callback.

  5. No arquivo baixado, copie client_id e client_secret para o .env (o project_id/client_email não são usados):

    GOOGLE_CLIENT_ID=
    GOOGLE_CLIENT_SECRET=
  6. Reinicie o app. A aba YouTube passa a mostrar o botão Connect YouTube; conclua o consentimento do Google e volte.

Quando GOOGLE_CLIENT_ID e GOOGLE_CLIENT_SECRET não estão definidos, o card do YouTube exibe "Not configured on this server" e o app continua funcionando com Spotify. Quando apenas GOOGLE_CLIENT_ID está presente (sem o secret), o servidor emite um aviso e o suporte ao YouTube fica indisponível.

Problemas comuns

Erro "Este aplicativo não foi publicado" / não consegue autorizar. Isso é esperado enquanto a OAuth consent screen está no estado Testing. Duas formas de resolver:

  • Ficar no estado Testing (recomendado para uso local). Em APIs & Services → OAuth consent screen → Audience, clique em Add test users e adicione exatamente o e-mail da conta com a qual você faz login no Google, aguarde ~1-2 min para propagar e tente de novo. Em Testing o app expira em 30 dias e a data é renovada a cada edição da tela.
  • Publicar o app. Clique em Publish app no canto superior direito da mesma tela. Para a YouTube Data API v3 o Google também pode exigir verificação do app (um formulário que pode levar dias); caso isso bloqueie, prefira ficar no estado Testing com test users.

A Authorized JavaScript origin cadastrada deve casar exatamente com a origem de onde a página faz o login: http://127.0.0.1:5173 no desenvolvimento (Vite) ou http://127.0.0.1:3000 na produção. Uma origem diferente faz o Google recusar o callback.

Variáveis de ambiente

Todas são opcionais, exceto SPOTIFY_CLIENT_ID, que é obrigatória para autenticar.

Variável Padrão Descrição
SPOTIFY_CLIENT_ID — O Client ID do seu aplicativo do Spotify.
SPOTIFY_REDIRECT_URI http://127.0.0.1:3000/auth/callback Deve corresponder a uma URI de redirecionamento do Dashboard.
PORT 3000 Porta do servidor de API.
WEB_PORT 5173 Porta do servidor de desenvolvimento Vite.
WEB_BASE_URL http://127.0.0.1:${WEB_PORT} URL para a qual a API redireciona após a autenticação.
TOKEN_FILE spotify-token.json Onde o token de autenticação é persistido.
GOOGLE_CLIENT_ID (opcional) Client ID do Google OAuth 2.0. Habilita o YouTube.
GOOGLE_CLIENT_SECRET (opcional) Secret do Google OAuth 2.0. Necessário com o ID.
GOOGLE_REDIRECT_URI http://127.0.0.1:3000/api/auth/youtube/callback URI de redirect registrada no Google Cloud.
YOUTUBE_TOKEN_FILE youtube-token.json Onde o token do YouTube/Google é persistido.

Scripts

Comando Descrição
npm run dev Executa o servidor de API e a interface web juntos.
npm run dev:server Executa apenas o servidor de API (modo de observação).
npm run dev:web Executa apenas o servidor de desenvolvimento Vite.
npm run build Compila o servidor (dist-server) e a web (dist-web).
npm run start Executa o servidor compilado, que serve o build da web.
npm run typecheck Verifica os tipos do projeto inteiro.
npm test Executa a suíte do Vitest uma vez.
npm run test:watch Executa o Vitest em modo de observação.

Arquitetura

O código é dividido de modo que a lógica de domínio fique independente de framework e testável:

HTTP/API   →  PlaylistService   →  PlaylistOrchestrator   →  SpotifyService   →  SpotifyClient
   (Express)      (caso de uso)        (pipeline de busca)     (chamadas à Web API)  (fetch + token)
  • server/spotify — a borda do Spotify.
    • spotifyClient executa as chamadas fetch reais e renova o token.
    • spotifyService encapsula o contrato da Web API (busca com limite de 10 itens, criação de playlist, adição de itens em blocos de 100) e normaliza as respostas.
    • spotifyAuth implementa o fluxo OAuth 2.0 com PKCE; tokenManager faz o cache e renova o token em disco.
  • server/services — o domínio.
    • parser divide o texto de entrada em ParsedTrackLines e monta uma query de busca.
    • matcher pontua uma linha analisada em relação a uma música candidata e escolhe a melhor.
    • dedup remove músicas duplicadas por URI.
    • orchestrator executa as buscas com um limite de concorrencia, escolhe a melhor correspondência por linha e descarta duplicatas.
    • playlistService é o caso de uso que une analisar → buscar → pontuar → deduplicar → criar/adicionar.
  • server/routes — roteadores Express finos sobre o serviço, protegidos por uma verificação de token.
  • web — um pequeno SPA React + Vite que conversa com a API.

Correspondência

Cada linha analisada é pontuada contra cada música candidata usando correspondência componentizada ponderada:

Componente Peso
Artista 0,35
Título 0,45
Query completa 0,20

As pontuações se consolidam em vereditos:

Veredito Faixa de pontuação
excellent 90–100
good 80–89
review 60–79
reject abaixo de 60

Por padrão, uma correspondência é selecionada automaticamente quando sua pontuação é igual ou superior a autoThreshold (padrão 90). Qualquer valor inferior é retornado para revisão, em vez de ser adicionado automaticamente. O orquestrador ignora linhas cuja melhor correspondência não atinja a faixa de revisão (60) e conta linhas duplicadas, de modo que cada música seja adicionada apenas uma vez.

Observações sobre a API do Spotify (2026)

  • POST /playlists/{id}/items aceita no máximo 100 itens por requisição; o serviço faz a divisão em blocos (chunking) para adições maiores.
  • Os resultados de busca são limitados a 10 itens.
  • O campo popularity foi removido da API; ele é mantido opcional para que respostas em cache continuem sendo interpretadas.
  • O campo tracks de uma playlist pode aparecer como items, dependendo da versão da API.

Testes

A suíte do Vitest fica em test/ e cobre o parser, as utilidades de texto, a pontuação/correspondência, a deduplicação e o serviço de playlist de ponta a ponta, com um SpotifyService falso (sem chamadas de rede).

npm test

Sobre este projeto

Este projeto foi um exercício de uso de IA local. Ele foi concebido, implementado e depurado inteiramente a partir do opencode (CLI interativa de engenharia de software) acoplado a um modelo do Ollama: qwen3.8:27b-mlx com janela de contexto de 32k (modelo exato ollama/qwen3.8:27b-mlx-32k). Nada foi enviado a um provedor da nuvem — toda a inferência roda na máquina local.

About

Tool used to create playlist in the Spotify from text list.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages