Skip to content

Latest commit

 

History

History
139 lines (72 loc) · 21.9 KB

README.md

File metadata and controls

139 lines (72 loc) · 21.9 KB

SpotSurvey-TelegramBot

SpotSurveyBot é um bot de Telegram que permite a geração de playlists no Spotify com música recomendadas a partir de preferências do usuário. Essas preferências são escolhidas através de menus interativos no chat do Telegram, onde usuários podem escolher entre 5 itens dos top artistas e/ou músicas (associados às suas contas do Spotify) como seeds para o endpoint do Spotify que permite gerar uma coleção de músicas recomendadas. Através dessas preferências (associadas à conta do Telegram), utiliza-se a API do Spotify para gerar a lista de recomendações

O bot foi desenvolvido como projeto final da disciplina MAC0546(2020) - Fundamentos da Internet das Coisas.

Atualmente, ele não está em execução, visto complicações adicionais em manter um app que coleta tokens de acesso à conta do Spotify de terceiros

De modo geral, a utilização do bot funciona da seguinte forma:

  • Realizar o processo de autenticação com o Spotify (através do comando /login),
  • selecionar seeds que gostaria de usar na recomendação (com comando /setup_seed)
  • (Opcional) selecionar filtros (caso não sejam definidas, as músicas recomendadas serão músicas similares às seeds selecionadas)
  • Quando quiser gerar uma nova playlist (excluindo as músicas anteriores da playlist criada pelo bot e colocando músicas recomendadas), utilizar o comando /generate_playlist
  • Se quiser se desassociar do bot, excluindo informações registradas, o acesso a sua conta pelo bot e, opcionalmente, a última versão da playlist gerada pelo bot, utilizar o comando /logout.

Obs1: Apesar de muitos casos onde a interação com o usuário poderia gerar erros terem sido tratados, é possível que existam alguns tipos de interações que não foram planejadas. Para maior confiança no funcionamento geral do bot, recomendo seguir o modo como as interações foram pensadas, o que está descrito na seção "Utilizando o Bot"

Obs2: No estado atual do projeto, a sua utilização pública não é recomendada, visto a falta de testes suficientes para garantir a estabilidade do programa sobre diversas situações (por exemplo, não foram feitos muitos testes sobre seu funcionamento com a utilização simultânea por vários usuários, apesar do desenvolvimento em geral ter considerado isso de forma superficial). Além disso, o modo como está estruturado iria necessitar de algumas mudanças para permitir que o programa parasse de depender do serviço do localtunnel para utilizar um servidor com domínio registrado e SSL para proteção dos dados enviados (visto que há troca de tokens de acesso do Spotify durante as operações do bot).

Setup do bot (para reprodução)

O SpotSurveyBot é executado como um conjunto de containers do Docker, mas antes de executá-los, alguns passos adicionais são necessários.

Antes de mais nada, o código do bot utiliza um arquivo que guarda variáveis de ambiente chamado .env. Como ele guarda os tokens de acesso às APIs usadas (Telegram e Spotify), ele não está presente nesse repositório. No seu lugar, existe um arquivo .env_model que possui os campos que devem ser definidos para execução do bot. Quando for executar, renomeie o arquivo de .env_model para .env e preencha os campos vazios com as informações relevantes (o que será mencionado mais adiante).

1º passo: Registro de um bot no Telegram

Primeiramente, você deve possuir uma conta no Telegram e iniciar um conversa com BotFather, um perfil que serve para registro de bots no Telegram. Você deverá então criar um bot. Para mais informações sobre como criar um bot usando o BotFather, acesse https://core.telegram.org/bots#6-botfather.

Alguns detalhes sobre a criação do bot:

  • O name do bot pode pode ser o que você quiser

  • O Username do bot, além de seguir a restrição de terminar em 'bot' (como mencionado na criação de bots), deve ser único. Não poderá ser nomeado 'SpotSurveyBot' ou 'SpotSurveyTestBot', visto que já tenho ambos os nomes registrados à minha conta.

  • Como mencionado no tutorial de criação de bots, você pode adicionar quais comandos existirão no bot (com o comando do BotFather '/setcommands'). Isso é útil pois facilita o uso dos comandos do bot ao permitir autocomplete. A lista de comandos que esse bot aceita está descrita na subseção Lista de comandos, seção Utilizando o Bot.

  • O SpotSurveyBot só funciona em chats privados (ou seja, não pode ser adicionado em grupos). Se quiser garantir isso, use o comando '/setjoingroups' do bot para o estado disabled.

Após o registro, você receberá o token de autorização de uso do bot que você acabou de criar. Copie o token e o associe à variável TELEGRAM_TOKEN no arquivo .env (que você deverá ter obtido ao renomear o arquivo .env_model). Também preencha o campo telegramBotLink do arquivo webserver/config.yaml com a URL do bot criado (por exemplo, 'https://telegram.me/SpotSurveyBot', substituindo 'SpotSurveyBot' pelo Username dado ao bot)

2º passo: Registro de aplicação no Spotify

Para utilizar a API do Spotify, necessária para o funcionamento do SpotSurveyBot, deve-se primeiro registrar a aplicação na dashboard do Spotify. Para isso, uma conta do Spotify é necessária.

Após se logar com sua conta Spotify, crie uma aplicação. Após isso, você irá para a dashboard de sua aplicação. Lá você encontrará o seu Client ID e, escondido sob um botão, o seu Client Secret, dois tokens necessários para o funcionamento do bot. Copie eles para as variáveis SPOTIFY_CLIENT_ID e SPOTIFY_CLIENT_SECRECT do arquivo .env, respectivamente. Note que você precisará adicionar uma URI de redirecionamento em edit settings, sendo esse o endereço para o qual o usuário será redirecionado ao aceitar (ou negar) o acesso da aplicação a certas informações e operações sobre sua conta. O valor a ser colocado será tópico do próximo passo.

3º passo: Configurando servidores e tunneling

Como o SpotSurveyBot é basicamente um servidor que recebe atualizações do Telegram quando há uma interação com o usuário, até poderíamos criar um servidor local. Porém, isso não foi possível com esse bot por dois fatores: pessoas que não estão conectadas na rede local não conseguiriam interagir com o bot e, da forma como o processo de autenticação da API do Spotify funciona, após o usuário permitir a aplicação se conectar com o Spotify, ocorre um redirecionamento para uma URL. Como a intenção era que o bot pudesse ser acessado de qualquer lugar, essa URL teria que ser um domínio registrado. Como pessoalmente não possuo nenhum domínio registrado no qual poderia utiliza para executar o bot, resolvi usar um serviço de tunelamento de um domínio específico para um servidor local. Mais especificamente, usei o localtunnel.

Da forma como o projeto está configurado, há dois serviços (docker containers) que rodam instâncias do localtunnel sobre dois subdomínios diferentes: o primeiro redireciona para a porta 5000 e conecta à internet (sob um domínio fixo) um servidor web local criado com Flask. O segundo redireciona para a porta 5001 e permite o estabelecimento de um Webhook do Telegram, permitindo acesso às atualizações vindas do Telegram. Você deve então:

  • Escolher dois subdomínios únicos para os serviços do localtunnel e colocar seus nomes após a opção '--subdomain' no campo services[localtunnel_web][command] e services[localtunnel_bot][command], no arquivo docker-compose.yml. É imprescindível para o funcionamento correto do bot que esses sejam subdomínios únicos. Para checar se os subdomínios selecionados estão disponíveis, você pode instalar a aplicação CLI do localtunnel usando npm install -g localtunnel e rodar o túnel usando lt --port 5000 --subdomain your-sub-domain-here, ou você pode checar o log dos containers rodando os serviços do localtunnel ao executar todos os serviços do docker-compose conjuntamente (explicado nos próximos passos) e verificar se a URL alocada para você possui o subdomínio selecionado (algo similar a https://your-sub-domain-here.loca.lt), caso ele já não esteja sendo usado por alguém, ou se ele possui um subdomínio aleatório, caso contrário.

  • Verificando que os subdomínios escolhidos não estão sendo usados e conseguindo as URLs alocadas para você, registre a URL que será alocada pelo serviço localtunnel_web do docker-compose, com um '/callback' no fim (algo como https://your-sub-domain-for-webserver-here.loca.lt/callback) tanto no arquivo bot/config.yaml, campo spotify[url][redirectURL], quanto nas configuração do dashboard de sua aplicação no Spotify (cliquem em edit settings e adicione essa URL no campo redirect URIs).

  • Também será necessário registrar a URL associada ao serviço localtunnel_bot do docker-compose (algo como https://your-sub-domain-for-bot-here.loca.lt/) no arquivo bot/config.yaml, campo spotify[telegram][webhookURL].

Nota importante: O funcionamento dos serviços do localtunnel não é perfeito. Caso os subdomínios escolhidos sejam fáceis, outros usuários poderão ocupá-los. Um possível bug é você não poder mais acessar um subdomínio que teoricamente ninguém está utilizando caso haja uma interrupção abrupta na sua conexão com a internet (caso ela caia ou você suspenda seu computador). Nesses casos, as operações desse passo deverão ser refeitas. Outra possibilidade é do serviço parar por erro interno dos servidores que hospedam o localtunnel. Nesses casos, os containers responsáveis pela comunicação com o localtunnel em teoria irão reiniciar, o que pode resolver o problema (caso contrário, uma possível solução seria reiniciar o processo do docker-compose).

4º passo: Iniciando bot

Chegando aqui, tudo o que resta é executar os containers do Docker utilizando o docker-compose. Para isso, primeiro tenha instalado e corretamente configurado o Docker-Compose. Para iniciar o bot, execute o seguinte comando sobre a pasta raiz do projeto:

docker-compose up --build

Isso irá criar as imagens do servidor web e do bot e utilizará as imagens do Redis, que servirá como banco de dados do bot, e os serviços do localtunnel, que serão conectados ao seus respectivos serviços.

Nota importante: Caso o bot não esteja conseguindo se comunicar com o Telegram (quando você manda mensagens ou comandos que supostamente deveriam ter algum retorno do Bot), tente comentar a linha 178 do arquivo bot/bot.py. Em testes anteriores, o bot funcionava com a linha comentada, mas ao fazer um teste em uma versão "pura" do código (clonando o repositório do Github), rodar essa linha de código permitiu a conexão do bot com o Telegram.

Utilizando o Bot

O bot é utilizável em clientes de Telegram acessando o link associado que depende de seu Username (se ele for 'SpotSurveyBot', acessando o link 'https://telegram.me/SpotSurveyBot' irá te direcionar para o bot). Acessando o link e entrando no chat associado ao bot, o usuário irá ver um botão escrito 'Começar' na parte de baixo. Ao clicar nele, o usuário inicia a conversa com o bot (esse é um comportamento padrão para a maioria dos bots de Telegram).

É interessante destacar que o bot funciona exclusivamente em chat privado com os usuários, sendo que todas as informações armazenadas sobre um usuário do Telegram não estão associadas ao usuário em si, mas sim ao chat que o usuário mantém com o bot.

Lista de comandos

Para conseguir uma lista dos comandos disponíveis ao usuário para serem utilizados em momentos que não sejam durante a execução de outro desses comandos (alguns comandos iniciam uma 'conversa' com o usuário, onde esses comandos não deveriam ser utilizados para não interromper o fluxo da conversa e, possivelmente, gerar erros de execução), execute o comando /help. Esses comandos são:

  • /start: Em uso normal retorna a mensagem de introdução do bot

  • /login: Usado para obter acesso a informações e conseguir realizar operações sobre a conta Spotify do usuário através do processo de autenticação da API do Spotify.

  • /setup_seed: Inicia uma conversa com o usuário onde ele seleciona quais itens ele gostaria de selecionar como seeds para a recomendação (de 1 a 5 itens entre artistas e músicas). A interação com o usuário é feita através de menus de seleção e o usuário escolhe os itens enviando mensagens no chat com os números associados a eles (mais detalhes em seção própria)

  • /setup_attributes: Comando opcional que inicia uma conversa com usuário onde ele irá receber uma mensagem perguntando o nível de um certo atributo que ele deseja selecionar para a recomendação de músicas, enviará uma mensagem com o número associado, e receberá a próxima mensagem pergunta o nível de outro atributo. Atributos do tipo Level servem com uma indicação da preferência do usuário, enquanto as do tipo Range excluem músicas com atributos fora do faixa de valores associada.

  • /get_setup: Retorna mensagem com as escolhas feitas pelo usuário durante comandos /setup_seed e /setup_attributes

  • /generate_playlist: Troca músicas atuais da playlist do Spotify pelas músicas recomendadas, utilizando os parâmetros selecionados durante os comandos /setup_seed e /setup_attributes

  • /logout: Exclui todos os dados relacionados ao usuário (mais especificamente, do chat utilizado), opcionalmente excluindo a playlist gerada.

Primeiro passo: Login com conta do Spotify

Todas as operações principais do SpotSurveyBot necessitam que o usuário se autentique com sua conta Spotify, permitindo assim que o bot obtenha dados necessários e permissão para fazer operações sobre a conta do usuário que utiliza o SpotSurveyBot. Para tanto, como explicado durante a mensagem de início do bot, utilize o comando /login para iniciar o processo.

Será enviado uma mensagem com um link embutido. Acessando o link, ele dará em uma página de autenticação de usuário do Spotify (caso o usuário já não tenha realizado essa operação antes), onde o usuário se logará em sua conta Spotify, e, após isso, outra página irá pedir sua aprovação sobre a disponibilização de certos dados e permissão de certas operações para a aplicação registrada no Spotify (ver 2º passo do setup). Caso aceite, o usuário será redirecionado para uma página de alerta do localtunnel, que avisará dos potenciais riscos que acessar páginas desse domínio associadas ao localtunnel podem trazer (caso nunca passado por essa página antes). Como esse aviso se referencia ao programa desenvolvido aqui, publicamente disponível, basta prosseguir que o usuário será redirecionado para um cliente do Telegram.

Retornando ao Telegram, pressione o botão 'Começar' para efetuar o login. Juntamente com isso, a playlist do spotify que será criado em seu usuário e associada ao seu chat com o bot será criada.

Segundo passo: Associar seeds ao usuário (chat)

Antes de se gerar uma playlist com músicas recomendadas, é necessária que o usuário dê algumas informações sobre suas preferências atuais em músicas. Essas informações serão utilizadas no processo de recomendação de músicas.

Para recomendar músicas, a API do Spotify apenas exige que um conjunto de 1 a 5 itens entre artista, músicas ou gêneros seja especificado. O comando /setup_seed é responsável por coletar essas informações. Ele permite que o usuário escolha 5 itens entre os 30 top artistas e as 50 top faixas relacionados à conta do Spotify do usuário (o conceito de top vem do próprio Spotify). Para garantir que haja ao menos algumas recomendações (o máximo são 20 músicas, mas pode ser 0 também), sugere-se não escolher somente artistas muito pouco conhecidos ou faixas muito pouco reproduzidas.

Após executar o comando e iniciar a 'conversa', o usuário irá se deparar com uma mensagem que serve como um tipo de menu, mostrando os itens (artistas ou músicas) em páginas de 10 itens cada, com informações sobre eles (para artistas, um link para seu perfil no Spotify e quais gêneros de músicas estão associados a ele, para músicas, um link para a música no Spotify e quais artistas participaram dela). Para ir navegar entre as páginas, o usuário usa os botões 'Previous' e 'Next'. Para ir do modo de seleção entre artistas e músicas, há um botão que faz essa troca ('Select Artists/Tracks'). Para seleciona um ou mais itens de um tipo, o usuário deve estar em uma página correspondente ao tipo de item que quer selecionar (uma indicação de que tipo de página se está, além da estrutura da listagem de itens, são as mensagens presentes no topo e no fim dela) e mandar uma mensagem com os números que deseja selecionar, separados por vírgula. Quando acabar de selecionar os itens, basta pressionar o botão 'Done', que irá confirmar se o usuário gostaria de encerrar o processo. Se sim, as músicas e/ou artistas selecionados serão salvos no banco de dados, associados ao usuário/chat que está usando.

Terceiro passo (opcional): Definir parâmetros para recomendação de músicas

Em teoria, somente as seeds são necessárias para poder pedir à API do Spotify por recomendação de músicas. Entretanto, o usuário pode também definir alguns parâmetros sobre as músicas que deseja ser recomendado utilizando o comando /setup_attributes.

Utilizando esse comando, usuários podem definir valores para atributos de duas formas: definindo um nível (Level) para o atributo, o que irá guiar a recomendação de músicas sem excluir as que possuem o atributo em questão fora do valor definido, ou irão definir um intervalo (Range) onde qualquer música do pool de músicas que acompanha cada seed selecionada (por experiência, cada seed selecionada trazia cerca de 150 músicas) que possuir um certo atributo fora do intervalo definido será excluída da recomendação. Pode-se imaginar que, ao se definir muitos atributos como do tipo Range ou selecionar intervalos de valores muito distintos dos disponíveis no pool de músicas disponíveis, chega-se fácil num resultado de que nenhuma música é recomendada. E foi exatamente o que aconteceu numa primeira versão do bot. Por isso, a maioria da seleção de atributos só pode ser do tipo Level, como forma de reduzir a incidência de vezes em que nenhuma música é recomendada para o usuário (apesar de isso ainda poder acontecer, caso as seeds selecionadas sejam somente de artistas muito pouco conhecidos ou músicas com baixo número de reproduções). A lógica do funcionamento desses dois tipos de seleção de atributos ainda existe; o que foi alterado foi só a exclusão das perguntas que geravam a seleção de atributos do tipo Range, com a exceção do atributo 'Duration'.

Explicado isso, o funcionamento do comando é o seguinte: após iniciar o processo, será mostrada uma mensagem que indica qual atributo será definido e qual o seu tipo (como citado anteriormente, a maioria é do tipo Level) (a seleção do atributo pode ser ignorada também, caso o usuário não tenha nenhuma preferência sobre um atributo específico). O usuário seleciona alguma das opções enviando uma mensagem com o número associado com a opção desejada (caso queria cancelar a operação, enviar o comando /cancel). Após enviar uma resposta válida, a próxima seleção é apresentada, repetindo o processo até a última seleção de atributo.

Quarto passo (opcional): Checar as seeds e os parâmetros definidos

Antes de executar o comando de gerar uma playlist recomendada (/generate_playlist), o usuário pode checar o que será utilizado durante na geração das recomendações: as seeds selecionadas com o comando /setup_seed e/ou os atributos selecionados com o comando /setup_attributes.

Quinto passo: Gerar a playlist:

Após definir parâmetros, vem então o passo principal: conseguir uma lista de músicas recomendadas, remover as músicas antigas da playlist associada ao usuário e colocar as novas músicas recomendadas. E é exatamente isso que o comando generate_playlist faz.

Vale mencionar aqui que a recomendação das músicas em si não é feita pelo bot, mas sim por serviços internos do Spotify. O que o bot faz é coletar informações através do usuário que serão colocadas como parâmetros para uma requisição à API do Spotify e receberá uma recomendação de músicas dela.

Sexto passo: E agora?

Após conseguir gerar as músicas, não há muito mais o que o bot possa fazer. O usuário pode num tempo futuro, alterar as seeds ou os atributos utilizados para conseguir novos tipos de recomendações (como já teria suas informações básicas registradas, não haveria necessidade de se logar de novo, bastando começar o processo do passo dois, por exemplo).

Caso o usuário queria, é possível se desvincular completamente do bot, excluindo todas informações registradas sobre ele, usando o comando /logout. O comando permite também a exclusão da playlist associada ao usuário do próprio Spotify. Note que, caso opte por não excluir a playlist e vá realizar o processo de login novamente (com o comando /login), uma nova playlist de mesmo nome será criada e a playlist antiga não sofrerá atualizações quando se realizar o processo de geração de músicas recomendadas, sendo o alvo dessa operação somente a playlist mais nova (a que ainda está associada ao usuário no Telegram).