
Você quer testar a funcionalidade? Escreva para o bot usando este link e ele responderá.
E para aqueles que estão interessados em como funciona e como um aluno de 16 anos conseguiu escrevê-lo, terei o prazer de contar tudo em detalhes neste artigo.
fundo
Tudo começou com meu outro bot para VK em node js , que descriptografava mensagens de voz (e como esses bots custam um centavo a dúzia, decidi não escrever um artigo sobre seu desenvolvimento, embora também tenha vários recursos distintos). Depois que o lancei, meu pai sugeriu que eu desenvolvesse outro bot para nosso bate-papo familiar via telegrama. A essência desse bot era simples - extrair a data e a hora de uma mensagem de texto de uma pessoa e, usando mensagens atrasadas de telegrama, criar lembretes direto no bate-papo familiar.
Mas logo fiquei desapontado. Descobri que os bots não podem fazer mensagens adiadas, então decidi escrever meu próprio sistema para armazenar e executar lembretes.
Desenvolvimento de
Informação geral
Este bot foi escrito em node js e vive em heroku .
É capaz de armazenar qualquer lembrete de texto com precisão de minuto.
Ele também pode trabalhar em conversas em grupo.
No momento, o bot reconhece a data e a hora apenas em russo.
SmartScheduler é um projeto de código aberto disponível no meu github .
Extrair data e hora da mensagem
Decidi começar com a tarefa mais difícil: dividir um lembrete de texto em uma data e um lembrete em si. Para fazer isso, tivemos que levar em consideração todos os padrões possíveis para escrever a data por uma pessoa, de " às 12h00 " até "no próximo domingo às vinte e cinco às oito da noite ".
Um grande banco de dados (constValues.js) foi criado, armazenando expressões constantes e suas propriedades que uma pessoa usa em sua fala. Em seguida, as funções foram escritas para reconhecer cada grafia da época.
Por exemplo , uma função é usada para reconhecer uma data na forma "até X % time_type %"
FindAdditiveLiterals
e para encontrar o dia da semana FindDayOfWeek
.
Cada opção de designação de tempo tinha sua própria prioridade.
Como resultado, o algoritmo do analisador tem a seguinte aparência:
- A string original é dividida em palavras. O número de palavras com que se realiza a busca do tempo não pode ultrapassar 40.
- Um array de palavras é passado pela função de conversão de palavra em número.
- Todas as indicações de tempo são encontradas na mensagem e as palavras usadas nas indicações também são marcadas (por exemplo, na indicação "despertador 8 horas" as palavras "8" e "horas" são marcadas).
- Se alguma característica de tempo não for encontrada (por exemplo, mês) em uma mensagem de texto, o valor atual dessa característica é considerado.
- Para o veredicto final, são selecionadas as indicações de tempo com maior prioridade e as indicações adjacentes que têm a mesma palavra fonte (por exemplo, na palavra "10:30" tanto a hora quanto o minuto são indicados simultaneamente).
- , , , .
- , .
- ,
{ string: answer, string: text, date: date }
{ string: answer, string: text }
(answer – , text – , date – ).
As próximas perguntas eram onde armazenar todos os lembretes e como controlar sua implementação.
Inicialmente, eu queria usar a biblioteca node-schedule , mas desisti dessa ideia, já que não queria entupir a RAM com todos os lembretes.
Em vez disso, decidi estudar como os bancos de dados SQL funcionam e criar o meu próprio.
Depois de ler muitos artigos na Internet, criei um banco de dados postgresql na plataforma heroku, já que você pode embutir bancos de dados em seus aplicativos, o que é muito conveniente.
Para interagir com o banco de dados, escrevi um pequeno script (db.js) no qual implementei todas as funções necessárias, como inicializar o banco de dados, obter uma lista de lembretes, etc.
Existem duas tabelas em meu banco de dados: a primeira para armazenar lembretes e a segunda para armazenar os fusos horários dos usuários (mais sobre isso depois).
Depois disso, implementei salvar um lembrete analisado de uma mensagem de texto no banco de dados. O cronômetro, que funciona uma vez por minuto, verifica a hora dos lembretes. Se chegar a hora de um lembrete, ele será excluído do banco de dados e uma mensagem com o texto do lembrete será enviada ao usuário que o fez.
Também adicionei a exibição de todos os lembretes por meio do comando / list .

(há um comando / N clicável ao lado de cada lembrete, que o remove quando você clica nele)
Configuração de fuso horário
Antes de eu decidir escrever este artigo e colocá-lo no Habr, o fuso horário de Moscou estava codificado nas variáveis de ambiente. Isso era suficiente para uso em nossa família, mas para aproveitar todos os prazeres e conveniências da vida com o bot SmartScheduler que qualquer um pudesse, decidi adicionar uma configuração de fuso horário individual.
Para completar a configuração, você precisa escrever o comando / tz , que o bot avisará o usuário se ele ainda não especificou seu fuso horário:

(devido ao fato de que o fuso horário não foi especificado, a resposta não usa a hora local, mas o horário de Greenwich)
Ao inserir o comando / tz o processo de determinação do fuso horário começa e um teclado aparece com três botões:

- Usando a localização do usuário.
- Entrada manual.
- Cancelar.
O primeiro botão pergunta ao usuário sua localização, com base na qual o fuso horário é calculado.
Exemplo de uso

O segundo botão permite inserir manualmente o fuso horário no formato ± HH: MM ,
onde ± - mais ou menos, HH - horas, MM - minutos.
Exemplo de uso

O terceiro botão cancela o processo de definição.
Depois que o usuário especificar seu fuso horário, o bot exibirá corretamente e salvará o horário do lembrete.
Melhorias finais
Terminada a funcionalidade principal, acrescentei o teclado principal com as funções principais, corrigi as respostas para os comandos / start e / help , e para as pequenas coisas.
Também decidi substituir o fuso horário padrão para todos os usuários por Moscou .
Resultado
A principal vantagem do bot SmartScheduler é, obviamente, a análise de datas, que permite que você anote de forma rápida e conveniente as informações ou tarefas necessárias na forma de um lembrete, mesmo nas situações mais imprevisíveis.
Você não precisa mais folhear o calendário em busca do dia certo e girar o relógio para acertar a hora, basta dizer humanamente ao bot “o quê” e “quando”, e ele fará tudo sozinho.
Conclusão
Antes de desenvolver bots em node js, eu não estava familiarizado com javascript, portanto, todo o conhecimento que usei para escrever o código foi retirado da Internet, onde muitas vezes você pode encontrar não exatamente o que realmente precisa. Por causa disso, provavelmente, em algum lugar do meu código existem erros muito estúpidos, para os quais ainda não sei muito o que identificar.
Inicialmente, meu objetivo não era criar o mais avançado e ideal do ponto de vista da estrutura do projeto, o mais importante para mim era adquirir novos conhecimentos, aprender uma nova linguagem de programação para melhorar o entendimento da ciência da computação em geral e criar um produto MVP.
Mas se esse desenvolvimento estiver em demanda, continuarei a aprimorá-lo com prazer, e se você tiver alguma ideia ou encontrar um bug, seja bem-vindo ao github do projeto. Já tenho ideias onde e como mudar o quê (por exemplo, reescrever o terrível código spaghetti no módulo de análise usando o padrão Visitor normal), bem como planos para adicionar suporte para o idioma inglês.
Espero que este bot ajude você e também ajude a mim e minha família em nossas atividades diárias.
Obrigado pela atenção!
UPD: Adicionado suporte para mensagens de voz por demanda popular.
UPD 2: O bot recebeu uma grande atualização desde que o artigo foi publicado. Lista de mudanças .