You are viewing the Portuguese (Brazil) site, but your language preference is set to English. Switch to English site →

Menu

Expand
Classifique esta página:

Lembretes de agendamentos com Rubi e Rails

Ahoy! Agora recomendamos que você crie seus lembretes de agendamento por SMS com a funcionalidade de programação de mensagens integrada da Twilio. Acesse a documentação de recursos de mensagens para saber mais sobre como programar mensagens SMS!

Pronto para implementar lembretes de agendamentos em seu aplicativo? Veja como funciona em um nível alto:

  1. Um administrador cria um agendamento para uma data e hora futuras e armazena o número de telefone de um cliente no banco de dados para esse agendamento
  2. Um processo em segundo plano verifica o banco de dados em um intervalo regular, procurando agendamentos que exijam o envio de um lembrete
  3. Em um horário configurado antes do agendamento, um lembrete de SMS é enviado ao cliente para lembrá‐lo do agendamento

Blocos de construção

Aqui estão as tecnologias que usaremos para fazer isso:

  • Ruby on Rails para criar um aplicativo da web orientado por banco de dados
  • O recurso de mensagens da API REST da Twilio para enviar mensagens de texto
  • Delayed::Job para nos ajudar a programar e executar tarefas em segundo plano de forma recorrente

Como ler este tutorial

Para implementar lembretes de agendamentos, trabalharemos em uma série de histórias de usuários que descrevem como implementar totalmente lembretes de agendamentos em um aplicativo da web. Veremos o código necessário para satisfazer cada história e exploraremos o que precisávamos adicionar em cada etapa.

Tudo isso pode ser feito com a ajuda da Twilio em menos de meia hora.

Vamos começar!

Criar um agendamento

Como usuário, quero criar um agendamento com um nome, números de telefone de convidado e um horário no futuro.

Para criar um app de lembrete de agendamento automatizado, provavelmente devemos começar com um agendamento. Esta história requer que criemos um pouco de IU e um objeto de modelo para criar e salvar um novo Appointment em nosso sistema. Em um nível alto, vamos adicionar o que precisamos:

  • Um formulário para inserir detalhes sobre o agendamento
  • Uma rota e uma função de controlador no servidor para processar o formulário
  • Uma rota e uma função de controlador no servidor para lidar com a solicitação POST do formulário
  • Um objeto de modelo Appointment persistente para armazenar informações sobre o usuário

Vamos começar analisando o modelo, onde decidimos quais informações queremos armazenar com o agendamento.

Visite nosso modelo de agendamento

O gerador do Rails

Normalmente, neste ponto do tutorial, criaríamos nosso modelo, exibição e controlador desde o início (veja a verificação da conta como exemplo). Mas como o modelo de agendamento é tão direto e queremos realmente apenas a estrutura principal do CRUD básico, vamos usar o gerador do Rails de uma vez.

Uma observação sobre as ferramentas

Neste app, estamos usando o Rails 4, mas será muito semelhante para o 3 e inferior. Também utilizaremos a biblioteca auxiliar twilio-ruby. Por fim, usamos o bootstrap para simplificar o design e, neste caso, há uma gem que irá gerar as exibições do tema do bootstrap chamadas de twitter-bootstrap-rails. Confira essas ferramentas quando tiver uma chance, agora vamos continuar gerando nossa estrutura principal.

Gerar um Modelo, uma Exibição e um Controlador

Rails generate é uma ferramenta de linha de comando que gera componentes em rails, como modelos, exibições, testes e muito mais. Para nossos propósitos, usaremos o gerador big kahuna, scaffold para gerar tudo de uma só vez.

Veja como fizemos isso. De dentro do nosso app rails, executamos:

$ bin/rails generate scaffold Appointment name:string phone_number:string time:datetime

Isso diz ao nosso gerador para criar o 'scaffolding' para um recurso chamado Appointment, que tem as propriedades name, phone_number e time.

Agora vamos para o modelo que foi gerado para adicionar algumas coisas a ele.

Aprimorar o modelo de agendamento

Modelo de agendamento

O modelo de agendamento é muito simples, mas como os humanos estarão interagindo com ele, vamos nos certificar de que adicionamos alguma validação de dados.

Validação de dados

As validações são importantes, pois queremos garantir que apenas dados precisos estejam sendo salvos em nosso banco de dados. Nesse caso, queremos apenas validar se todos os nossos campos obrigatórios estão presentes. Podemos fazer isso criando uma declaração validates com presence: true.

É provável que nosso Modelo de Agendamento seja criado por uma pessoa admin no local do agendamento. Bem, seria ótimo se pudéssemos dar ao nosso usuário admin algum feedback quando ele criasse o agendamento. Felizmente no Rails se adicionarmos validações aos nossos modelos, obteremos relatórios de erros gratuitamente com o objeto flash da sessão.

Uma observação: para executar esta demonstração, você precisará executar rake db:migrate, que executaria migrações em nossa pasta db/migrate. Neste tutorial, vamos nos concentrar nos conceitos principais, mas se você quiser saber mais sobre migrações, leia o Guia do Rails sobre o assunto.

Loading Code Sample...
        
        
        app/models/appointment.rb

        Appointment Model

        app/models/appointment.rb

        Agora, estamos prontos para ir até o nível do controlador do aplicativo, começando com as rotas de solicitação HTTP necessárias.

        Configure algumas rotas

        Rotas

        Em um aplicativo do Rails, o Resource Routing (Roteamento de recursos) mapeia automaticamente as capacidades de CRUD de um recurso para seu controlador. Como nosso Appointment é um recurso ActiveRecord, podemos simplesmente dizer ao Rails que queremos usar essas rotas, o que vai economizar algumas linhas de código.

        Isso significa que nesta linha de código temos automaticamente uma rota appointment/new que renderizará automaticamente nosso arquivo appointment/new.html.erb.

        Loading Code Sample...
              
              
              config/routes.rb

              Routes

              config/routes.rb

              Vamos olhar mais detalhadamente este formulário.

              Nosso novo Formulário de Agendamento

              Novo formulário de agendamento

              Quando criamos um novo agendamento, precisamos de um nome de convidado, um número de telefone e uma hora. Usando a tag form_for do Rails, podemos vincular o formulário ao objeto do modelo. Isso gerará a marcação html necessária que criará um novo Agendamento no envio.

              Loading Code Sample...
                    
                    
                    app/views/appointments/_form.html.erb

                    Appointment Form

                    app/views/appointments/_form.html.erb

                    Vamos destacar uma tag auxiliar específica que o Rails nos dá para formulários vinculados ao modelo.

                    Hora e hora de novo

                    Data e hora

                    Uma possível perda de tempo é descobrir como lidar com a data e a hora do agendamento. Na realidade, são duas entradas de usuário separadas, uma para o dia e outra para a hora do agendamento. Precisamos de uma maneira de combinar essas duas entradas separadas em um parâmetro no lado do servidor. Mais uma vez, o Rails lida com isso fornecendo as tags data_select e time_select que o servidor coleta automaticamente em um parâmetro que mapeia para a propriedade appointment.time.

                    Loading Code Sample...
                          
                          
                          app/views/appointments/_form.html.erb

                          Entradas de data e hora

                          app/views/appointments/_form.html.erb

                          Vamos voltar ao controlador para ver o que acontece quando criamos este agendamento.

                          Manipulador de criação de agendamento

                          Lidar com o POST do formulário

                          Um dos outros controladores práticos criados pela rota do recurso Appointment foi appointment/create, que lida com o POST a partir do nosso formulário.

                          Em nosso controlador, usamos as informações de nosso formulário e criamos um novo modelo Appointment. Se o agendamento for salvo no banco de dados com êxito, redirecionaremos para a exibição de detalhes do agendamento, que mostrará ao criador o novo agendamento e permitirá que ele seja editado ou excluído.

                          Loading Code Sample...
                                
                                
                                app/controllers/appointments_controller.rb

                                Lidar com o POST do formulário, criar um agendamento

                                app/controllers/appointments_controller.rb

                                Em seguida, vamos dar uma olhada nos controladores gerados para edição e exclusão.

                                Interação com agendamentos

                                Interação com agendamentos

                                Como usuário, quero exibir uma lista de todos os agendamentos futuros e poder excluir esses agendamentos.

                                Se você é uma organização que lida com muitos agendamentos, provavelmente deseja poder visualizá‐los e gerenciá‐los em uma única interface. É isso que vamos abordar nesta história do usuário. Criaremos uma IU para:

                                • Mostrar todos os agendamentos
                                • Excluir agendamentos individuais

                                Vamos começar olhando para o controlador.

                                Mostrar uma lista de agendamentos

                                Mostrar uma lista de agendamentos

                                No nível do controlador, tudo o que faremos é obter uma lista de todos os agendamentos no banco de dados e renderizá‐los com uma exibição. Também devemos adicionar um prompt se não houver agendamentos, pois esta demonstração depende de haver pelo menos um agendamento no futuro.

                                Loading Code Sample...
                                      
                                      
                                      app/controllers/appointments_controller.rb

                                      Mostrar uma lista de agendamentos

                                      app/controllers/appointments_controller.rb

                                      Vamos voltar ao modelo para ver nossa lista de agendamentos.

                                      Visualizar todos os agendamentos

                                      Visualizar todos os agendamentos

                                      A exibição de índice lista todos os agendamentos que são automaticamente ordenados por date_created. A única coisa que precisamos adicionar para preencher nossa história de usuário é um botão de exclusão. Adicionaremos o botão de edição apenas para começar.

                                      Auxiliares de URL

                                      Você pode notar que, em vez de codificar os urls para Editar e Excluir, estamos usando auxiliar de URL do Rails. Se você visualizar a marcação renderizada, verá estes caminhos:

                                      • /appointments/ID/edit para edição
                                      • /appointments/ID para exclusão, com um método HTTP DELETE anexado à consulta

                                      Estes auxiliares de URL podem tomar um objeto de agendamento ou um ID.

                                      Há alguns outros auxiliares neste código que o Rails gera para nós. O que quero salientar é a tag :confirm. A tag de confirmação é um atributo de dados que interrompe a solicitação DELETE real com um alerta javascript. Estas são as práticas recomendadas ao chamar DELETE em um objeto. Se o usuário confirmar, processamos a solicitação normalmente, caso contrário, nenhuma ação será tomada.

                                      Loading Code Sample...
                                            
                                            
                                            app/views/appointments/index.html.erb

                                            View All Appointments

                                            app/views/appointments/index.html.erb

                                            Agora vamos dar uma olhada no que acontece no controlador quando pedimos para excluir um agendamento.

                                            Procurar um agendamento

                                            Procurar um agendamento

                                            Neste controlador precisamos de abrir um registo de agendamento e depois eliminá‐lo. Primeiro, vamos dar uma olhada em como estamos fazendo o agendamento.

                                            Como provavelmente precisaremos de um registro de agendamento na maioria de nossas exibições, devemos apenas criar um método de instância privada que possa ser compartilhado entre vários controladores.

                                            Em set_appointment, utilizamos o parâmetro de id, que passou pela rota, para procurar o agendamento. Então, na parte superior do nosso controlador, usamos o filtro before_action, assim:

                                            before_action :set_appointment, only: [:show, :edit, :update, :destroy]
                                            

                                            Isso diz ao aplicativo a quais controladores aplicar este filtro. Neste caso, só precisamos de um agendamento quando o controlador lidar com um único agendamento.

                                            Loading Code Sample...
                                                  
                                                  
                                                  app/controllers/appointments_controller.rb

                                                  Procurar um agendamento

                                                  app/controllers/appointments_controller.rb

                                                  Agora vamos dar uma olhada no que acontece quando um agendamento é realmente excluído.

                                                  Excluir um agendamento

                                                  Excluir um agendamento

                                                  Agora que temos o agendamento, basta chamar .destroy nele. Em um aplicativo de produção, você pode querer avaliar se deve ser usado .delete em vez de destruir, já que ambos são formas válidas de excluir uma linha de banco de dados no Rails. Para nossos fins, usaremos a destruição menos eficiente por dois motivos:

                                                  1. Ela lida com a limpeza do banco de dados
                                                  2. Ela mantém o Appointment na memória, para que possamos enviar uma mensagem de sucesso ao usuário
                                                  Loading Code Sample...
                                                        
                                                        
                                                        app/controllers/appointments_controller.rb

                                                        Excluir um agendamento

                                                        app/controllers/appointments_controller.rb

                                                        Agora que podemos interagir com nossos agendamentos, vamos nos aprofundar em enviar lembretes quando um desses agendamentos estiver chegando.

                                                        Enviar o lembrete

                                                        Enviar o lembrete

                                                        Como um sistema de agendamentos, desejo notificar um usuário via SMS sobre um intervalo arbitrário antes de um agendamento futuro.

                                                        Há muitas maneiras de criar essa parte de nosso aplicativo, mas não importa como você o implemente, deve haver duas partes em movimento:

                                                        • Um script que verifica o banco de dados quanto a qualquer agendamento que esteja por vir e, em seguida, envia um sms
                                                        • Um trabalhador que executa esse script continuamente
                                                        Loading Code Sample...
                                                              
                                                              
                                                              app/models/appointment.rb

                                                              Enviar o lembrete

                                                              app/models/appointment.rb

                                                              Vamos dar uma olhada em como decidimos implementar este último com Delayed::Job.

                                                              Trabalhando com Delayed::Job

                                                              Trabalhando com Delayed::Job

                                                              Como mencionamos anteriormente, há muitas maneiras de implementar um agendador/trabalhador, mas no Rails o Delayed::Job é o mais estabelecido.

                                                              O Delayed Job precisa de um back‐end de algum tipo para enfileirar os trabalhos futuros. Aqui, adicionamos o adaptador ActiveRecord para delayed_job, que usa nosso banco de dados para armazenar o banco de dados 'Jobs'. Há muitos backends compatíveis, então use a gem correta para seu aplicativo.

                                                              Depois de incluir a gem, precisamos executar bundle install e executar a tarefa do rake para criar o banco de dados.

                                                              rails g delayed_job:active_record

                                                              Você pode ver todas essas etapas no repositório do github para este projeto.

                                                              Loading Code Sample...
                                                                    
                                                                    
                                                                    The Rails Generator

                                                                    Gemfile for Appointment Reminders

                                                                    The Rails Generator

                                                                    Agora estamos prontos para criar o trabalho real.

                                                                    Enviar um lembrete

                                                                    Enviar um lembrete

                                                                    A próxima etapa no envio de um lembrete para nosso usuário é criar o script que será acionado em algum intervalo antes do horário do agendamento. Acabaremos por querer agendar esse lembrete quando o agendamento for criado, por isso faz sentido escrevê‐lo como um método no modelo de Agendamento.

                                                                    A primeira coisa que fazemos é criar um Twilio Client que enviará nosso SMS via API REST da Twilio. Precisaremos de três coisas para criar o Twilio Client:

                                                                    • Nosso Account SID (SID da conta) da Twilio
                                                                    • Nosso Auth Token (Token de autenticação) da Twilio
                                                                    • Um número Twilio em nossa conta que possa enviar mensagens de texto

                                                                    Todos esses recursos podem ser encontrados no console.

                                                                    Em seguida, tudo o que precisamos fazer para enviar um sms é usar o messages.create() integrado para enviar um SMS para o telefone do usuário.

                                                                    Modelo de retorno de chamada

                                                                    Como fizemos do nosso script de lembrete um método no modelo, obtemos uma ferramenta muito útil; um callback (retorno de chamada). Ao usar o retorno de chamada before_create, garantimos que o :reminder será chamado sempre que um agendamento for criado.

                                                                    Loading Code Sample...
                                                                          
                                                                          
                                                                          app/models/appointment.rb

                                                                          Enviar um lembrete

                                                                          app/models/appointment.rb

                                                                          A última etapa é garantir que esse retorno de chamada sempre termine sendo programado pelo Delayed Job.

                                                                          Agendar um Lembrete

                                                                          Agendar um Lembrete

                                                                          Bem, estamos quase terminando, agora tudo o que precisamos fazer é escrever um controlador de agendamento extremamente complicado que faça o seguinte:

                                                                          • Procurar todos os agendamentos futuros
                                                                          • Adicioná‐los a uma tabela de Jobs
                                                                          • Verificar se ele está dentro do intervalo minutes_before_appointment
                                                                          • Acionar o método do lembrete

                                                                          Ah espere, o Delayed Job faz isso gratuitamente em um método útil chamado handle_asynchronously que diz para o Delayed Job agendar este trabalho sempre que esse método for disparado. Uma vez que o nosso tempo de trabalho depende da instance do Agendamento individual, temos de passar o método handle_asynchronously para uma função que irá calcular o tempo. Nesse caso, minutes_before_appointment é definido como 30 minutos, mas você pode usar qualquer intervalo Time aqui.

                                                                          Agora, quando criarmos um agendamento, veremos uma nova linha na tabela de Trabalhos, com um tempo e um método que precisa ser disparado. Além disso, delayed_job salva erros e tentativas para que possamos depurar qualquer coisa errada antes que ele falhe. Depois de disparar um trabalho, ele o remove do banco de dados, portanto, em um bom dia, devemos ver um banco de dados vazio.

                                                                          Loading Code Sample...
                                                                                
                                                                                
                                                                                app/models/appointment.rb

                                                                                Agendar um Lembrete

                                                                                app/models/appointment.rb

                                                                                Tudo pronto

                                                                                Uau, este foi um grande empreendimento mas, na realidade, tivemos que escrever muito pouco código para obter lembretes automatizados de agendamentos disparados com a Twilio.

                                                                                Para onde ir em seguida?

                                                                                Para onde ir em seguida?

                                                                                E com um pequeno código e um pouco de configuração, estamos prontos para receber lembretes automatizados de agendamentos disparados em nosso aplicativo. Bom trabalho!

                                                                                Se você for um desenvolvedor do Ruby que trabalha com a Twilio, talvez queira conferir outros tutoriais no Ruby:

                                                                                Clique para ligar

                                                                                Coloque um botão em sua página da web que conecta os visitantes ao suporte ao vivo ou à equipe de vendas por telefone.

                                                                                Autenticação de 2 fatores

                                                                                Melhore a segurança da funcionalidade de login do seu app Ruby adicionando autenticação de dois fatores por mensagem de texto.

                                                                                Isso ajudou?

                                                                                Obrigado por conferir este tutorial! Se você tiver algum feedback para compartilhar, entre em contato pelo Twitter... adoraríamos ouvir suas ideias e saber o que você está desenvolvendo!

                                                                                Jarod Reyes Kevin Segovia Daniel Erazo
                                                                                Classifique esta página:

                                                                                Precisa de ajuda?

                                                                                Às vezes, todos nós precisamos; a programação é difícil. Receba ajuda agora da nossa equipe de suporte, ou confie na sabedoria da multidão navegando pelo Stack Overflow Collective da Twilio ou buscando a tag Twilio no Stack Overflow.

                                                                                Loading Code Sample...
                                                                                      
                                                                                      
                                                                                      

                                                                                      Obrigado pelo seu feedback!

                                                                                      Selecione o(s) motivo(s) para seu feedback. As informações adicionais que você fornece nos ajudam a melhorar nossa documentação:

                                                                                      Enviando seu feedback...
                                                                                      🎉 Obrigado pelo seu feedback!
                                                                                      Algo deu errado. Tente novamente.

                                                                                      Obrigado pelo seu feedback!

                                                                                      thanks-feedback-gif