Como escrevi uma biblioteca para o serviço Yandex.Music

1. Introdução


Sobre mim


Olá pessoal, sou um aluno comum na especialidade de "técnico de software". Desde a infância, gosto de computadores, desde a 7ª série que comecei a aprender programação em si. Sou proprietário de uma assinatura do Yandex Music há mais de um ano e geralmente estou satisfeito com o serviço (embora agora haja repetições contínuas na lista de reprodução do dia).


Antecedentes


Não me lembro exatamente por que decidi procurar a documentação oficial da API desse serviço, como um bot que eu queria escrever para o Telegram, mas me deparei com o fato de que não era ... Depois de algum tempo, deparei com um problema no repositório yandex / audio-js . Lá, os caras fazem exatamente a mesma pergunta que eu: "Onde está a API?" Poucas pessoas estão ansiosas para ouvir música através de um navegador, elas querem um aplicativo, mas também não há aplicativo Linux! Integrar ao seu jogador favorito é impossível!


Então tive a ideia de fazê-lo. Naturalmente, preciso trabalhar de alguma forma com o serviço, fazer muletas em torno de um aplicativo da Web não é uma opção. Entendi que, com esse serviço, aplicativos móveis e aplicativos para Windows (da Microsoft Store), é simplesmente impossível não ter sua própria API interna para interação. Eu estava certo!


Leitura obrigatória perante o corpo principal


Estou ciente de que, estudando a API não pública, vasculho as coisas sujas de outras pessoas. A seguir, serão descritas várias questões controversas, decisões dos desenvolvedores e, em geral, como eles escreveram e como usam. Em alguns lugares, fiquei chocado , mas tenho certeza de que, se o fizessem, havia razões para isso ! Não vamos esquecer que ninguém deveria ter visto isso. Eu também quero dizer que tudo escrito abaixo é minha opinião . Você pode concordar com ele ou não.


Corpo principal


Preparação


API de aplicativo da Web


Acima, eu já escrevi que encontrei a API. Não foi nada difícil. Primeiro de tudo, eu olhei para o aplicativo da Web, o ponto final deles no momento da redação está aqui: https://music.yandex.ru/api/v2.1/ . Eles têm URLs suficientemente longos nos quais eu participo dos dados e também enviam o formulário. Peço também que você preste atenção em indicar a versão da API , é isso.


Você precisa entender que o que encontrei é usado por eles apenas em um aplicativo da web. Não há OAuth. Mais precisamente, é mais provável que exista, mas lá, nas entranhas da nossa sessão no site. Em geral, a biblioteca não é adequada em conexão com muletas na autorização.


API do aplicativo


Parti para procurar mais. Eu estava com preguiça de pegar o telefone, portanto, chegava a aplicativos móveis por último. Naquela época, o computador estava executando o Windows 10 e eu usei ativamente o aplicativo oficial Yandex Music da Microsoft Store . Como resultado, comecei a estudar como isso funciona.


Para a pesquisa, eu precisava de um sniffer para rastrear todo o tráfego de aplicativos. Você poderia usar o Wireshark , mas eu decidi pelo HTTP Analyzer . Parece-me mais leve e perfeitamente adequado à minha tarefa.


Ligue o sniffer, vá para o aplicativo e pronto. As solicitações fluem por fluxo. Sentamos, entendemos, tentamos chamar cada manipulador que está nesta aplicação e descobrimos todos os métodos existentes, seus argumentos e, é claro, respostas JSON .


Captura de tela de uma das solicitações


Na captura de tela acima, você pode notar imediatamente um endereço de API completamente diferente - api.music.yandex.net . Além disso, preste atenção aos títulos. Além das informações sobre meu cliente a partir das quais a solicitação foi feita, há um token OAuth - é disso que você precisa!


API de aprendizado


O estudo ocorreu em conjunto com a escrita de código. Escrevi classes de wrapper para objetos de serviço recebidos da API, implementei pedidos de envio, classifiquei os parâmetros e, em alguns lugares, adivinhei o que esse nome poderia significar. Nesta fase, conheci várias coisas que não esperava ver aqui.


No momento em que este artigo foi escrito, a biblioteca contém 83 classes, e apenas algumas delas são auxiliares. O restante são aulas de música Yandex, que indicam a escala desse serviço e o nível de abstrações.


Enviando ~ 47 métodos foi implementado. E isso não é tudo o que está na API (mais sobre isso abaixo).


Dor


No começo, tentei não prestar atenção, fiquei simplesmente surpreso, porque esse é o Yandex , como pode ser isso. Mas então, em um belo momento, tudo bombardeou. Talvez eu comece com ele.


  1. Dois objetos com diferentes níveis de anexo de campo


    Nova versão do objeto


    O objeto em si é apenas uma "referência" a si mesmo. Para a sua versão completa. Ao solicitar uma lista de faixas, é fornecido seu ID, pelo qual podemos obter informações mais detalhadas. Muitas boas práticas o fazem, mas nem sempre é respeitado (parágrafo 9).


    Versão antiga do objeto


    Tendo implementado a classe para esse objeto no início, pensei em usá-la em qualquer lugar, mas não importa como! Parece-me que os comentários são supérfluos e tudo pode ser visto nas capturas de tela.


    Como não corrigi esse tipo de batente na minha biblioteca, agora a classe TrackShort agora tem o TrackShortOld .


    A propósito, esses dois objetos vivem no mesmo método, no método landing'a .


  2. Versões de API, métodos


    Não pedi apenas que você prestasse atenção em como a versão é especificada na API do aplicativo Web. Geralmente, como geralmente indicamos uma versão? Provavelmente de uma das seguintes maneiras:


    • faça a versão em um subdomínio separado;
    • coloque a versão na parte da solicitação;
    • passe a versão desejada do parâmetro API para a solicitação.

    A Yandex decidiu, nesse caso, fazer o contrário. Temos um método landing3 - sua versão atual no momento da redação. Mas ninguém proíbe o envio de uma solicitação de desembarque2 - uma estrutura completamente diferente, outros objetos.


    Descobri isso por acidente, esquecendo de adicionar um número ao final do nome do método e capturando várias exceções.


  3. Trabalhando com o novo, não desista do antigo


    Vi isso quando escrevi os métodos de envio "Curtir" para todos os objetos que são. Na verdade, não existem muitos deles (lista de reprodução, artista, faixa, álbum). Qual foi a minha surpresa quando vi abordagens diferentes para a mesma ação.


    Gostamos de artistas como este: https://api.music.yandex.net/users/<USER_ID>/likes/artists/add e transfira o artist-id no formulário.


    Gostamos de faixas como esta: https://api.music.yandex.net/users/<USER_ID>/likes/tracks/add-multiple e na forma de track-ids de track-ids .


    Se você não percebeu, quando você gosta da faixa, o método add-multiple é usado, não add . Este método não é usado com outros tipos, mas todos eles existem (valia a pena tentar enviar uma solicitação)! E eu os implementei na minha biblioteca em vez de adicionar . Afinal, esse método é universal. Você pode adicionar uma faixa ou várias.


  4. O que é um identificador de faixa exclusivo


    Muito tempo se passou, mas ainda não entendo quando enviar apenas o id faixa e quando o ID e o album_id são concatenados por dois pontos ( id:album_id ). Às vezes, uma faixa está em vários álbuns, às vezes não há álbum. Casos muito obscuros, olhando de lado, não sei como eles lidam com isso (ou não conseguem, bagus 2).


  5. Muitos campos opcionais


    Eu tenho alguns problemas. Se houver algum problema, ele estará relacionado ao campo obrigatório. Nunca deixo de me surpreender como, em minha opinião, os campos obrigatórios simplesmente não retornam a API.


    • album_id da classe TrackID e TrackShort;
    • order_id da classe AutoRenewable (assinatura);
    • next_revision no feed;
    • cover_uri na faixa;
    • aniversário na conta;
    • tags na lista de reprodução.

    A lista continua, mas tudo está no histórico de confirmações. Talvez este item seja sugado para fora do dedo.


  6. Métodos de similaridade, exceto alguns campos na resposta


    Resposta do status da conta ( api.music.yandex.net/account/status ):


    Resposta do status da conta


    Status da conta do rádio de resposta ( https://api.music.yandex.net/rotor/account/status ):


    Resposta de rádio do status da conta


    Entendo que os direitos são diferentes, agora os campos têm um limite não no número de faixas no cache, mas no número de pulos por hora, mas parece mais algum tipo de duplicação.


    Não sei como é o Yandex, mas juntei-o em uma classe.


  7. Então um ou muitos?


    Eu sempre pensei que, se um método retorna uma lista, mesmo que o resultado seja um elemento, a lista que contém esse elemento será retornada e nada mais, mas aqui e depois e mais.


    recurso e recursos


    Esse recurso retornará, depois recursos , depois recurso e recursos .


  8. Uso indevido de métodos


    Acima, escrevi que eles usam um ou outro método para executar uma ação. Eles foram mais longe.


    Enviar faixas excluídas quando as costas estão bem cientes delas


    Além do ID da lista de reprodução e dos quadros com e por qual faixa excluir, eles, por algum motivo, transmitem faixas que serão excluídas para o método de exclusão de faixas da lista de reprodução. É possível que eu não tenha entendido isso, como todo o resto, mas o método funciona sem muita informação. E que faixas foram apagadas, é melhor descobrir nas costas, do que passar por parâmetro.


  9. Pedidos muito pesados


    Eu escrevi acima que dar uma lista com IDs de faixa é uma boa prática, você obtém informações detalhadas sobre uma faixa somente quando realmente precisa dela. Isso nem sempre é usado aqui.


    Veja como, sem piedade, eles fornecem informações detalhadas de todas as minhas faixas da lista de reprodução "Curtir" em uma solicitação:


    Pedido pesado


    Deu todas as 396 faixas ! Bytes recebidos: 3,75 milhões , e este é mais um download de capa!



Baguetes


  1. Faça o download de todas as faixas para o cache em "Curtir"


    Quando o limite foi atingido, uma adição foi feita no final e removida desde o início. Obrigado pela visualização da fila, mas pensei em baixar as últimas 100 faixas da lista de reprodução. Isso aconteceu no cliente móvel para Android ( assista ao vídeo ).


  2. Parece que não estou confuso quando preciso enviar um id, mas quando id: album_id


    Faixas duplicadas



Anotações


O número de tentativas para ativar o código de presente é 10. Proibição seguinte por 24 horas.


Dependendo do aplicativo em que você está sentado, diferentes ofertas são feitas para você adquirir uma assinatura.


O limite para o número de faixas no cache é uma ilusão, é apenas um número, e o aplicativo não permite que você carregue mais (bagus 2).


Todas essas listas de reprodução inteligentes, sugestões, cores de texto e botão vêm da API - aqui está, o RESTFull real.


A hora de início do anúncio e o próprio anúncio são retornados, mesmo se você tiver uma assinatura.


Um link para XML contendo dados sobre o local do arquivo a ser baixado dura 1 minuto e, em seguida, um erro 410.


Conclusão


Escrevi apenas o que lembrava. Afinal, me deparei com tudo isso por vários meses. Todas as minhas anotações são mensagens em um telegrama, porque quando me deparei com algo assim, compartilhei com os amigos. Eu tentei restaurar os pontos principais.


De maneira alguma eu queria dizer o quão ruim tudo era, de alguma forma colocar os batentes em público especialmente. Talvez isso não seja um batente, mas tudo o que escrevi acima me parece estranho pessoalmente .


Ele compartilhou com você como ele escreveu a biblioteca para a API de serviço Yandex.Music privada e o que encontrou durante o desenvolvimento.


Agora você sabe como e em que aplicativo do Windows funciona e, portanto, minha biblioteca.


A propósito, agora eu tento documentar tudo. Ao documentar minha biblioteca, documento automaticamente a API deles. Está apertado, e ainda preciso ter tempo para encontrar uma empresa para passar pela prática tecnológica industrial.


Obrigado por ler até aqui!

Source: https://habr.com/ru/post/pt462607/


All Articles