Kit de Construção para Discord Bot 🤖

Propósito deste plugin

Este plugin faz várias coisas:

  1. Permite que você alimente um bot do Discord usando seu servidor Discourse para realizar ações que integrem os dois sistemas. Faça um fork deste repositório e expanda-o com Ruby simples para criar todos os tipos de funcionalidades para o bot.

  2. Funcionalidades existentes que servem como exemplos e utilitários úteis:

  • Oferece algumas postagens automáticas bidirecionais de conteúdo que atendem a certos critérios.
  • Comando para copiar mensagens ad hoc para o Discourse.
  • Comando para sincronizar a associação a grupos com a associação a funções (roles) do seu servidor Discord com sua instância do Discourse.

O plugin fornece um esqueleto extensível sobre o qual você pode construir recursos adicionais. PRs (Pull Requests) para adições geralmente úteis são bem-vindos.


esses não são os dois comandos de sincronização, apenas uma ilustração da interação do bot que é possível. o segundo comando na captura de tela foi descontinuado durante o desenvolvimento :wink:

A configuração é necessariamente complexa, mas é ótima para fãs de ambos os sistemas que estão dispostos a dedicar tempo para entender como cada sistema funciona, pelo menos em nível funcional e conceitual. Você precisa entender alguns fundamentos de como o gerenciamento de usuários do Discourse e do Discord funciona para obter o melhor deste plugin.

Comandos do Bot

Existem quatro comandos:

  1. Ping!
  2. !disckick
  3. !discsync
  4. !disccopy

Ping!

Para verificar se o bot está respondendo, basta digitar “Ping!” e o bot deve responder com “:robot: : Pong!” - maravilhoso, não é? :smiley: (isso é uma espécie de meme, btw!)

!disckick <min_trust_level: padrão 2>

Digitar isso expulsará qualquer usuário que exista no seu Discourse, mas com um Nível de Confiança abaixo do valor fornecido. O padrão, se você não fornecer um valor, é 2.

Exemplo:

!discsync <clean up: padrão false, min_visibility: padrão 0, include automated groups: padrão false>

Este comando tentará copiar todos os grupos para Funções (Roles) no Discord que correspondam aos critérios fornecidos (ou padrões, se não fornecidos). Em seguida, tentará popular as funções de acordo com a associação a Grupos no Discourse. É uma sincronização unidirecional apenas. Nenhum dado do Discourse é alterado.

!disccopy <number_of_messages> <optional_target_category_name> <optional_target_topic_name>

Permite copiar o histórico de mensagens do Discord para sua instância do Discourse diretamente do chat do Discord. Isso pode lidar com milhares de mensagens de uma só vez (mas para esse volume, levará algum tempo).

Comunicação bidirecional

Aqui estão as configurações:

  • Você pode designar um Canal de Anúncios no Discord nas configurações do plugin.
  • Agora você pode digitar no Canal de Anúncios designado do Discord e isso publicará sua mensagem no Tópico do Discourse designado nas configurações do plugin.
  • Você pode configurar uma lista de Categorias no Discourse para postar no canal de Anúncios do seu Discord se alguém postar lá ou adicionar um novo Tópico (um ou ambos).
  • Cópia de chat automatizada por mensagem, por canal, para qualquer Categoria com nome idêntico no Discourse: se o nome do canal corresponder ao nome da Categoria, a mensagem será copiada para o Discourse.

image

Além disso, adicionei um novo arquivo para gerenciar eventos do Discord suportados pela API discordrb, sendo a lógica de Anúncios o primeiro exemplo (sinta-se à vontade para desenvolver novos e enviar um PR se forem úteis para a comunidade em geral).

NB: Para qualquer mensagem copiada para o Discourse a partir do Discord, o Usuário será exibido corretamente se esse usuário tiver feito login no Discourse usando o login do Discord (assim, o Bot do Discord consegue corresponder os usuários).

Estado deste plugin

Este é um plugin complexo de configurar. Isso era praticamente inevitável.

No entanto, é brincadeira de criança usá-lo uma vez que tudo esteja funcionando.

Considere o código atualmente em Beta. Foi testado, inclusive em Produção, mas provavelmente contém bugs. Recomendo testá-lo primeiro em um servidor Discord novo antes de aplicá-lo ao seu servidor Discord principal de “Produção”, a menos que você esteja apenas começando.

Qualquer bug tem muito mais probabilidade de afetar sua instância do Discord do que a do Discourse, pois não são feitas alterações no Discourse. No entanto, escrevi-o de uma forma que significa que a maioria das coisas é recuperável e você pode simplesmente repetir algo para corrigir um problema, geralmente. O Discourse é usado como mestre para informações de associação e grupo, e esses dados são usados para atualizar a associação e as Funções (Roles) no seu servidor Discord.

Instruções de Configuração

Pré-requisitos

  1. Um servidor Discord no qual você é Administrador.
  2. Um App do Discord (veja abaixo).
  3. Um Bot do Discord (veja abaixo).
  4. Acesso ssh root ao seu servidor Discourse.
  5. Atualizações no app.yml para instalar o plugin.
  6. Todos os usuários do seu Discourse precisarão fazer login usando o login OAuth do Discord que aparecerá na sua página de login assim que o plugin for instalado.

App do Discord

Vá para cá e crie um aplicativo:

Clique em “New Application” (Novo Aplicativo).

Você precisará criar um Bot e ele ficará mais ou menos assim (deixe-o não ‘público’):

Você precisará autorizar o bot no navegador, veja OAuth2 - Documentation - Discord

Depois que o bot for configurado, copie o Token. Você precisará inseri-lo no Discourse mais tarde.

Alterações no app.yml

plugin

Você precisa de apenas um plugin para isso agora que o Login Social do Discord é nativo no núcleo do Discourse (yeah :tada: )

Então, no prompt, execute ./launcher rebuild app como de costume.

Isso deve funcionar, sem problemas.

Você pode receber alguns erros no console e nos logs indicando uma falha do bot na primeira construção, pois você ainda não inseriu as credenciais do bot na interface frontal das configurações do Discourse. (lidar com isso de forma mais elegante é uma tarefa pendente, eu apagarerei esta parte quando isso for feito). Isso não fará mal algum, no entanto, e o próprio Discourse funcionará normalmente.

Uma vez na área de administração do seu Discourse, vá para Configurações do Plugin e preencha estes:

Você obterá os IDs da interface do Discord. Você precisará ativar o Modo Desenvolvedor para permitir que você copie esses IDs. No Discord, vá para suas Configurações → Aparência → AVANÇADO e ative o Modo Desenvolvedor:

Você pode então obter os IDs na interface, por exemplo:

Você também precisará preencher as Configurações do OAuth do Discord. O Client ID e o Secret são do seu mesmo App do Discord.

Depois de definir essas configurações, volte para o prompt raiz no linux e digite:

./launcher restart app

Se você configurou corretamente seus servidores Discord e Discourse, deverá ver o bot entrar no servidor.

Se o bot cair (ele ficará offline), você precisará fazer a mesma coisa novamente para trazê-lo de volta. Maior independência do bot em relação ao servidor principal do Discourse é uma tarefa pendente. Dito isso, executei um bot em Produção por um longo tempo e ele ainda não caiu.

Futuros comandos?

Se você tiver uma ideia para outro comando que aproveite a ligação entre Discourse e Discord e que você acredite ser útil para a comunidade em geral, me avise nas respostas e podemos analisar o potencial para implementar isso. NB: este bot não tem a intenção de realizar tarefas fora do escopo do Discourse.

Limitações

O objetivo principal deste plugin era permitir que o usuário criasse um bot em seu Discord que fosse alimentado por seu servidor Discourse e pudesse realizar algumas funções básicas de gerenciamento de associação. Também fornece uma base para quaisquer interações adicionais semelhantes a bots entre os dois sistemas para o futuro. Parte da motivação para usar bots é que eles são simplesmente divertidos.

Os comandos do bot são ad hoc por sua própria natureza.

Problemas Conhecidos

  • O bot iniciará uma instância de si mesmo se você entrar em uma sessão de console rails no servidor. Isso fará com que o bot pareça responder duas vezes (mas na verdade há dois bots agora). No console rails, pare o bot adicional simplesmente digitando: ::DiscordBot::Bot.discord_bot.stop Isso agora não deve mais ser necessário!

  • O Robô é um pouco tagarela durante atualizações do Discourse ‘online’, pois continua sendo reativado durante o processo de atualização. Isso remonta a descobrir uma boa maneira de executar o bot em um processo separado e gerenciado, em vez de uma thread ramificada do servidor web. Acredito que isso seja tudo inofensivo, no entanto, e se a saída dos bots for apenas para o seu canal de administração no Discord, você realmente se importa? Isso deve estar quase resolvido agora, com o bot anunciando a si mesmo apenas duas vezes durante uma reconstrução.

Agradecimentos

Há vários apoiadores a agradecer por este plugin, que me levou muito tempo para chegar a este estágio, incluindo @Wedgebert, @FoohonPie. Obrigado ao Jeff por sua generosa contribuição. Obrigado a @angus por todo o encorajamento e por lidar com o apoio financeiro.

O plugin foi inspirado no trabalho que @Watercolor_Games fez em um estágio anterior e depende do plugin de OAuth do Discord criado por @featheredtoast.

O plugin depende da biblioteca Ruby discordrb semi-oficial apoiada pelo Discord e do trabalho fantástico que a equipe do Discord fez para tornar seu sistema acessível. Obrigado a @Falco por me ajudar com uma dependência de maneira extremamente responsiva.

Além disso, é claro, isso não seria possível sem o incrível ecossistema de plugins do Discourse (yeah!)

Estado destas instruções

Elas serão melhoradas com o tempo e eu agradeço o feedback. Há áreas que certamente serão pouco claras.

47 curtidas
Discord<-> Discourse Selective Group Sync
Discord login and obtain discord roles in discourse
Discord and Discourse - Better Together | Blog
Convert Existing Plugin to do Discord to Discourse role/group sync
Slack Bot Construction Kit :robot:
2019: The Year in Review
Creat a user automatically when granted a Discord Role?
Discord Sync: sync a Discourse forum with a Discord server
Creating bot on discourse
Using "custom" ruby gems
Discourse Trust Levels for Discord
Discord is taking aim at Discourse. How does Discourse remain unique and stand out from the crowd?
Discord is taking aim at Discourse. How does Discourse remain unique and stand out from the crowd?
Copy + Pasting text from Discord into Discourse mangles paragraph breaks
Discord Role Badge Sync
Discord Bot: Topics not Posts
How do I go about making a very customized theme?
API feature request for additonal info about external accounts
Can anyone help me to add chat option of discord on forum?
How to Integrate/Sync Discord User MEE6 Points with Discourse Leaderboard?
LF Developer, Theme Creator, and Discord/Discourse Hero
Discord Sync: sync a Discourse forum with a Discord server
[PAID] Discourse/Discord integration needed (roles/user groups)
Can anyone help me to add chat option of discord on forum?
Discord and Discourse - Better Together | Blog
How to easily make Discourse bots?
Discourse to Discord bot possible?
Migrating from Discord to Discourse
Convert Existing Plugin to do Discord to Discourse role/group sync
Is migration from other chat apps supported?
Partially enable login option
Introducing Discourse Chat (BETA)
Which instant messenger do you use with Discourse?
Request widgetbot.io
Discord Sync: sync a Discourse forum with a Discord server

Ei, estou super interessado nisso.

Seria possível fazer o oposto? Adoraria uma maneira de criar uma configuração do Discourse para meu servidor do Discord. Não tenho certeza se existe um evento da API do Discord para atribuição de funções, mas você provavelmente poderia verificar quando alguém faz login com o Discord ou usar CRON.

2 curtidas

Sim, absolutamente.

Você poderia construir isso como um comando de bot para aplicação sob demanda, mas com um recurso de repetição que executaria o comando novamente após um período (legal, mas não muito transparente e sem como gerenciar individualmente essas recorrências).

OU

Como sugeri acima, agendá-lo como uma tarefa no Discourse, como um job Sidekiq. Isso poderia ser um plugin separado (na verdade, comecei o esqueleto dessa abordagem antes de migrar para uma solução apenas de bot, principalmente porque a abordagem de ‘bot’ era meio que a ‘coisa’ do Discord, divertida e oferecia uma abordagem e resultado únicos), mas se eu conseguir fazer o Discourse disparar comandos de bot, isso se torna irrelevante (ainda não tive a chance de testar isso). Assim, poderíamos escrever o código uma vez e fazê-lo funcionar de qualquer maneira (ótimo!).

Ambas as soluções dependeriam do mesmo login OAuth.

Embora essa seja uma ideia excelente, não pode ser uma prioridade para mim no momento, pois tenho muito outro trabalho de cliente para entregar agora. Mas, se você desejar apoiar tal extensão, podemos discutir offline em uma mensagem privada e agendá-la.

4 curtidas

Pode ser interessante brincar um pouco, mas estou longe do nível de habilidade necessário para me voluntariar a desenvolver/manter um addon como este. Talvez eu faça um fork bagunçado em algum momento, mas certamente não quero ter meu nome em nada oficial. :slight_smile:

3 curtidas

Com certeza, se suje. É a única maneira de aprender. :).

4 curtidas

Correção de bug menor implantada:

Recebi isso durante a reconstrução:

O bot ainda está offline. Verifiquei tudo três vezes e está tudo configurado corretamente. Não tenho certeza de como prosseguir agora… Talvez eu precise abrir uma porta na minha instância de servidor?

2 curtidas

Obrigado por testar isso e tão pouco tempo após a atualização. Vou tentar reproduzir o problema e retorno em breve. Não alterei nada em relação à configuração da porta.

2 curtidas

Sem problemas na reconstrução por aqui, o Bot inicia corretamente… você alterou algo na configuração do seu servidor no meio do caminho?

Seu 400 Bad Request indica que seu servidor enviou uma solicitação corrompida ou inválida ao servidor do Discord, e esta foi a resposta. Isso sugere que a solicitação foi recebida corretamente e não foi bloqueada.

Isso pode ocorrer por:

  • solicitações malformadas
  • falta de autorização
  • exceder os limites de taxa

Infelizmente, a mensagem de erro não parece ajudar a determinar qual desses foi o problema específico.

Presumivelmente, seu Discourse está ativo? Verifique se todas as configurações dos plugins estão preenchidas corretamente.

Apenas para descartar um problema temporário, execute ./launcher restart app quando tiver oportunidade… isso levará seu site offline por apenas alguns segundos (desculpe por isso!).

Vejo que ele executa o bot no bloco after_initialize, o que impedirá as migrações (e rebuilds) se o bot estiver mal configurado ou se o Discord estiver fora do ar.

Talvez tente tratar essa exceção e apenas registrar o erro?

5 curtidas

Ele roda em uma thread separada? Então espero que isso não seja um problema?

No entanto, esse callback parece ser executado várias vezes durante um rebuild, então o principal problema é que um bot mal configurado poderia realmente exceder os limites de taxa se a autorização falhar muitas vezes em rápida sucessão. Se isso acontecer, a conta, no pior caso, pode ser bloqueada por algum tempo.

De qualquer forma, farei um patch rápido para lidar com isso na implementação atual, a fim de reduzir o impacto. Obrigado pela sugestão.

ATUALIZAÇÃO: @falco, isso foi feito, por exemplo:

image

3 curtidas

Primeiramente, quero agradecer por criar isso. Assim que conseguir fazê-lo funcionar, será uma grande ajuda para nós gerenciarmos nosso Discourse e Discord para uma comunidade de voluntários.

Estou enfrentando um erro 400 ao tentar executar este bot. Antes da adição deste plugin, estávamos usando com sucesso o plugin oficial de autenticação do Discord e webhooks por meio do plugin de integração de chat. Já validei que ambos ainda estão funcionando corretamente.

Criei o bot dentro do mesmo aplicativo do Discord que havia criado anteriormente, autorizei o bot no servidor do Discord, e ele aparece na lista de membros como offline. Sua documentação não especificava qual valor de permissão aplicar, mas, como a maioria dos bots que já encontrei para o Discord solicita isso, configurei com um valor de permissão 8 para Administrador.

Dentro do servidor do Discord, copiei o ID da função que ele criou, que foi nomeada como meu aplicativo, e o ID do canal para texto de administrador. Adicionei a função do aplicativo a esse canal com todos os direitos, só para ter certeza, e depois adicionei os IDs ao Discourse e reiniciei.

Infelizmente, não importa o que eu tente, estou recebendo um erro 400. Até tentei uma reconstrução, só para ter certeza.

3 curtidas

Obrigado pelas palavras gentis. Isso também foi possível graças à generosidade dos financiadores.

Sim, está ótimo. Deve ter permissão de Admin.

Este é o segundo relato desse problema.

Se você remover intencionalmente o último caractere do token nas configurações (lembre-se do que isso é), você receberá um 401 em vez disso?

Vamos mover isso para mensagem privada, pois pode ficar confuso :wink: (podemos sempre postar a solução aqui).

4 curtidas

Só para atualizar, caso mais alguém veja isso: estamos investigando ativamente o problema, mas ainda não identificamos a causa. Se mais alguém estiver enfrentando esse problema, por favor, avise — isso ajudaria a ter mais pessoas testando.

1 curtida

Isso já foi corrigido. Foi um caso estranho de rastrear.

Obrigado a @ransim por levantar o problema e trabalhar comigo para chegar à raiz dele.

Um grande agradecimento ao pessoal do #ruby_discordrb no Discord API pela ajuda paciente e imediata!

@neemiasvf

5 curtidas

@merefield sem problema, seu plugin é ótimo. Mas agora encontrei alguns problemas.
como este:

Discourse Sync: Iniciando. Por favor, tenha paciência, estou limitado pela taxa de requisições para respeitar os serviços do Discord.
Discourse Sync: Verificando se há algum grupo elegível para sincronização ...
Discourse Sync: 1 grupo(s) elegível(is) foi(Foram) encontrado(s)
Discourse Sync: Preparando lista de usuários que também têm uma conta registrada no Discord ...
Discourse Sync: Preparando lista de grupos aos quais usuários com conta registrada no Discord pertencem no Discourse ...
Discourse Sync: 0 grupo(s) elegível(is) foi(Foram) encontrado(s) com usuários do Discord
Discourse Sync: Nenhum usuário foi encontrado em grupos elegíveis para sincronização usando os critérios fornecidos ou padrão!

meu comando é: !discsync 4

e o comando alterado: !discsync false 5 false

Discourse Sync: Iniciando. Por favor, tenha paciência, estou limitado pela taxa de requisições para respeitar os serviços do Discord.
Discourse Sync: Verificando se há algum grupo elegível para sincronização ...
Discourse Sync: 10 grupo(s) elegível(is) foi(Foram) encontrado(s)
Discourse Sync: Preparando lista de usuários que também têm uma conta registrada no Discord ...
Discourse Sync: Preparando lista de grupos aos quais usuários com conta registrada no Discord pertencem no Discourse ...
1 curtida

Olá @p0nda, desculpe pela resposta tardia.

Se você incluir parâmetros, precisa incluir todos eles. Pode ser que o sistema esteja interpretando de forma estranha.

3 curtidas

Não consegue fazer as configurações estendidas do bot aparecerem? Já apliquei as alterações no app.yml e instalei os plugins. A configuração do OAuth está funcionando, mas não as configurações do bot. Alguma ideia?

1 curtida

As configurações do OAuth estão lá, mas não há configurações de bot.

1 curtida

Estes

2 curtidas