Bot de linha que verifica se uma mensagem contém boatos na Internet.
Este é um dos subprojetos de 真的假的。
Este diagrama de estado descreve como o bot LINE se comunica com os usuários:
O desenvolvimento do rumors-line-bot requer que você conclua as seguintes configurações.
Depois de clonar este repositório e cd no diretório do projeto, instale as dependências.
$ git clone --recursive [email protected]:cofacts/rumors-line-bot.git # --recursive for the submodules
$ cd rumors-line-bot
Siga todas as etapas do tutorial oficial do LINE.
Crie o arquivo .env
a partir do modelo .env.sample
, pelo menos preencha:
API_URL=https://dev-api.cofacts.tw/graphql
LINE_CHANNEL_SECRET=<paste Messaging API's channel secret here>
LINE_CHANNEL_TOKEN=<paste Messaging API's channel access token here>
LINE_LOGIN_CHANNEL_ID=<paste LINE Login channel ID here>
LIFF_URL=<paste LIFF app's LiFF URL>
Outras variáveis de ambiente personalizáveis são:
REDIS_URL
: se não for fornecido, redis://127.0.0.1:6379
será usado.PORT
: Em qual porta o servidor do bot de linha irá escutar.GTM_ID
: ID do Gerenciador de tags do Google. Para os eventos e variáveis que enviamos para dataLayer
, consulte a seção "Gerenciador de tags do Google" abaixo.DEBUG_LIFF
: Desativa a verificação do navegador externo no LIFF. Útil ao depurar LIFF em navegador externo. Não habilite isso na produção.RUMORS_LINE_BOT_URL
: URL público do servidor que é usado para gerar URLs de imagens de tutorial e URL de retorno de chamada de autenticação do LINE Notify. Você precisará Node.JS
16+ para continuar.
$ npm i
Ative periféricos como Redis e MongoDB usando:
$ docker-compose up -d
Em seguida, ative o aplicativo, incluindo o servidor chatbot e o webpack-dev-server para LIFF, usando:
$ npm run dev
O servidor será iniciado em localhost:5001
(ou na PORT
que você especificou em seu arquivo .env
).
Se você deseja parar os periféricos, execute docker-compose stop
.
Basta executar npm test
. Ele irá ativar automaticamente a janela de encaixe mencionada e executar testes de unidade.
Recomendamos usar ngrok
para criar um endereço público que direcione o tráfego do servidor LINE para sua máquina local. Com ngrok
no seu caminho, basta
$ ngrok http 5001
ngrok
fornecerá um URL público. Use isto para definir o URL do webhook do seu canal (consulte a seção "Console do canal" no tutorial oficial do LINE).
Recomendamos usar o arquivo de configuração ngrok para configurar um túnel com um subdomain
fixo. Desta forma, o URL público pode ser corrigido (significa que não há cópia e colagem repetitiva nas configurações do canal LINE!), desde que o subdomain
não esteja ocupado por outros.
Dentro do console do LINE Developers em seu canal Message API, em Messaging API > Webhook settings, defina o URL do Webhook como ${ngrok_url}/callback
e ative Use webhook . Clique em verificar para confirmar que está conectado com sucesso à sua máquina local.
Estamos usando o LIFF para coletar o motivo do usuário ao enviar artigos e feedbacks negativos.
Se você não precisar desenvolver o LIFF, poderá usar diretamente LIFF_URL
fornecido em .env.sample
, que direciona para o site de teste do LIFF.
Se quiser modificar o LIFF, talvez seja necessário seguir estas etapas:
Para criar aplicativos LIFF, siga as instruções do documento oficial, que envolve
chat_message.write
no escopo (para LIFF enviar mensagens). Após adquirir o URL LIFF, coloque-o em .env
como LIFF_URL
.Endpoint URL
para começar com seu endpoint chabbot e adicione /liff/index.html
como postfix. Para desenvolver o LIFF, após npm run dev
, ele está acessível em /liff/index.html
do servidor dev (http://localhost:5001) ou servidor chatbot de produção.
No modo de desenvolvimento, ele gira um webpack-dev-server em localhost:<LIFF_DEV_PORT>
(o padrão é 8080
) e /liff
do servidor chatbot faz proxy de todas as solicitações para o webpack-dev-server.
Uma dica para desenvolver LIFF em navegador é:
https://<your-dev-chatbot.ngrok.io>/liff/index.html?p=<page>&...
no navegador do desktop.liff.logout()
manualmente no console JS para acionar um novo login. liff.init()
ainda funcionaria no navegador de desktop, para que o aplicativo fosse renderizado, permitindo-nos depurar layouts da web no desktop. liff.sendMessages()
não funcionaria, no entanto. liff.closeWindow()
também não funcionará se a janela do seu navegador tiver passado por redirecionamentos de login.
O servidor bot LINE inicia um servidor GraphQL que une a API GraphQL do Cofacts e a API específica para o chatbot LINE.
Sempre que a API Cofacts for atualizada, use npm run cofactsapi
para buscar o esquema mais recente da API Cofacts.
Durante o desenvolvimento, use o seguinte comando para iniciar um livro de histórias em sua máquina local:
npm run storybook # Then visit http://localhost:6006
Você também pode visitar https://cofacts.github.io/rumors-line-bot para um livro de histórias pré-construído no branch master
.
Na produção, os arquivos LIFF são compilados no diretório /liff
e servidos como arquivos estáticos pelo servidor do chatbot.
Se você receber 400 bad request
no LIFF, pesquise a chamada de função liff.init
no binário JS compilado e veja se o ID do LIFF é consistente com seu URL LIFF, que deve ser o caminho sem o início https://liff.line.me/
.
O ID LIFF é definido usando o plugin Webpack Define durante a construção, portanto, trocar a variável env da URL LIFF sem reconstruir os binários LIFF causará 400 solicitações incorretas.
Usamos ttag para oferecer suporte ao i18n em tempo de construção para o chatbot.
Consulte a documentação do ttag para anotar strings a serem traduzidas.
Para extrair strings anotadas para arquivos de tradução, use:
$ npm run i18n:extract
Os arquivos de tradução estão localizados em i18n/
, no formato Gettext PO.
en_US.po
: Como o idioma usado no código já é o inglês, este arquivo de tradução vazio existe para simplificar as configurações.zh_TW.po
: tradução para chinês tradicional.ja.po
: tradução japonesa. Você pode substituí-lo por qualquer idioma que deseja oferecer suporte, aproveitando o comando Gettext msginit
.
Você precisará alterar o script i18n:extract
e i18n:validate
em package.json
para refletir a mudança de localidade.
Por padrão, o chatbot será construído na localidade en_US
.
No Heroku, defina LOCALE
como en_US
, zh_TW
ou qualquer outro código de idioma que exista no diretório i18n/
.
Se você quiser construir usando o docker, pode ser necessário modificar o Dockerfile para incluir o LOCALE
desejado.
Pré-requisitos:
Para usar mensagem push: no arquivo .env
, defina NOTIFY_METHOD=PUSH_MESSAGE
Para usar o LINE Notify:
Callback Url
: RUMORS_LINE_BOT_URL
/authcallback/line_notify.env
, define LINE_NOTIFY_CLIENT_ID=<paste LINE Notify Client ID here>
LINE_NOTIFY_CLIENT_SECRET=<paste LINE Notify Client Secret here>
NOTIFY_METHOD=LINE_NOTIFY
RUMORS_LINE_BOT_URL=<line bot server url>
LINE_FRIEND_URL=https://line.me/R/ti/p/<paste your chatbot ID here>
Você pode configurar um ponto de entrada da página de configuração ( LIFF_URL
?p=setting) no gerenciador de contas -> menu avançado
$ npm run notify
$ node build/scripts/scanRepliesAndNotify.js
Rumores-line-bot usa serviços de nuvem do Google que são autenticados e autorizados usando contas de serviço do Google Cloud e credenciais padrão de aplicativo.
Crie uma conta de serviço no projeto, baixe sua chave e use GOOGLE_APPLICATION_CREDENTIALS
env var para fornecer o caminho para a chave da conta de serviço baixada. Consulte a documentação para obter detalhes.
Usamos o Dialogflow para detectar se o usuário está tentando bater um papo. Se a entrada do usuário corresponder a qualquer uma das intenções do Dialogflow, poderemos retornar diretamente respostas predefinidas nessa intenção.
Para usar o Dialogflow, faça a seguinte configuração:
dialogflow.sessions.detectIntent
.DAILOGFLOW_LANGUAGE
: Vazio para o idioma padrão do agente ou você pode especificar um idioma.DAILOGFLOW_ENV
: padrão para agente de rascunho ou você pode criar versões diferentes. Crie uma dimensão personalizada (escopo do usuário) para Message Source
e uma matriz personalizada (escopo de ocorrências) para Group Members Count
. O índice padrão de ambos é 1. Se os índices criados pelo GA não forem 1, encontre cd1
e cm1
no código e altere-os para cd$theIndexGACreated
e cm$theIndexGACreated
respectivamente.
Use npm run typecheck
para verificar os tipos; use npm run typegen
para gerar o tipo do esquema GraphQL.
Prepare o arquivo .env
(que deve ser idêntico ao seu ambiente de implantação) e execute docker build .
para gerar a imagem do docker.
.env
será copiado para a imagem do construtor para gerar o arquivo estático LIFF com o env. Ao construir a imagem, você pode simplesmente incluir as "variáveis de tempo de construção" (denotadas em .env.sample
) em .env
para garantir que nenhuma credencial do servidor vaze no código do cliente construído.
Como as imagens do docker construídas codificarão URLs públicos em arquivos construídos estaticamente, essas variáveis de tempo de construção quando executamos a imagem como um contêiner. Portanto, cada ambiente de implementação separado exigirá uma construção separada da imagem.
Você pode testar a imagem construída localmente usando docker-compose.yml
; apenas descomente a seção do bot de linha e forneça o nome da imagem construída.
Para produção, consulte rumores-deploy para obter um exemplo docker-coompose.yml
que executa essa imagem.
Enviamos variáveis e eventos no dataLayer
do Gerenciador de tags do Google quando o usuário interage com o LIFF.
Você pode preparar a seguinte configuração no arquivo .env
:
GTM_ID
: ID do contêiner do Gerenciador de tags do Google ( GTM-XXXXXXX
) O aplicativo irá disparar os seguintes eventos personalizados no dataLayer
GTM:
dataLoaded
- quando os dados são carregados no artigo, comentário ou feedback LIFF.routeChangeComplete
- quando LIFF é carregado ou muda de caminho.feedbackVote
- quando o usuário envia um feedback.chooseArticle
- quando o usuário escolhe um artigo no Articles LIFF. Além disso, ele enviará a seguinte variável personalizada para dataLayer
;
pagePath
– definido quando o evento routeChangeComplete
é acionado. O caminho da página do roteador do LIFF.userId
- definido após LIFF obter o token de ID e decodificar o ID do usuário LINE dentro dele.articleId
e replyId
: definido no ciclo de vida Article, Comment e Feedback onMount()
é chamado. Ou quando o evento chooseArticle
é acionado.doc
- Definir quando o evento dataLoaded
é acionado. O próprio conteúdo carregado no objeto (artigo no Artigo LIFF, comentário no Comentário LIFF e feedback no feedback LIFF). Formato do evento enviado: Event category
/ Event action
/ Event label
Usamos a dimensão Message Source
(Custom Dimemsion1) para classificar diferentes fontes de eventos
user
para mensagens individuaisroom
| group
para mensagens em grupoUserInput
/ MessageType
/ <text | image | video | ...>
UserInput
/ ArticleSearch
/ ArticleFound
Article
/ Search
/ <article id>
para cada artigo encontradoUserInput
/ ArticleSearch
/ ArticleNotFound
UserInput
/ ArticleSearch
/ ArticleFoundButNoHit
UserInput
/ IsForwarded
/ Yes
| No
UserInput
/ IsCooccurrence
/ Yes
| No
UserInput
/ ChatWithBot
/ <intent name>
Article
/ Selected
/ <selected article id>
Reply
/ Search
/ <reply id>
para cada respostaArticle
/ NoReply
/ <selected article id>
Reply
/ Selected
/ <selected reply id>
Reply
/ Type
/ <selected reply's type>
UserInput
/ Feedback-Vote
/ <articleId>/<replyId>
/feedback/yes
ou /feedback/no
também é enviada.Article
/ Create
/ Yes
Article
/ Create
/ No
Article
/ ProvidingReason
/ <articleId>
/reason
também é enviada./articles
é enviadautm_source=rumors-line-bot&utm_medium=richmenu
utm_source=rumors-line-bot&utm_medium=push
LIFF
/ ChooseArticle
/ <articleId>
utm_source
, utm_medium
também se aplicam./setting
da página é enviadautm_source=rumors-line-bot&utm_medium=reply-request
&utm_source=rumors-line-bot&utm_medium=tutorial
Tutorial
/ Step
/ ON_BOARDING
Tutorial
/ Step
/ RICH_MENU
Tutorial
/ Step
/ <TUTORIAL_STEPS>
Group
/ Join
/ 1
( Event category
/ Event action
/ Event value
)Group Members Count
(métrica personalizada1) para registrar a contagem de membros do grupo quando o chatbot ingressou.Group
/ Leave
/ -1
( Event category
/ Event action
/ Event value
)Observação:
- Definimos o valor do evento ga 1 como junção, -1 como saída. Para saber a contagem total de grupos do chatbot atualmente ingressado, você pode ver diretamente o valor total do evento (para detalhes, consulte Contagem implícita).
- Para saber se um grupo está ingressando ou saindo, você deve encontrar a última ação
Join
ouLeave
doClient Id
.- Além disso, você deve encontrar a última ação
Join
doClient Id
para obter umaGroup Members Count
mais precisa.Group Members Count
só é registrada quando o chatbot entra no grupo. Para saber a contagem exata, você deve obtê-la diretamente na linha de mensagens-api.
UserInput
/ ArticleSearch
/ ArticleFound
Article
/ Search
/ <article id>
para cada artigo encontradoArticle
/ Selected
/ <selected article id>
Reply
/ Selected
/ <selected reply id>
UserInput
/ Intro
/ContentProxy
/ Forward
/ <content type>
/ <content length>
(valor) LICENSE
define o contrato de licença para o código-fonte neste repositório.
LEGAL.md
é o contrato de usuário para usuários do site Cofacts.