Plugin proposto para melhorar a precisão de resposta por e-mail

Nos últimos meses, houve várias solicitações em diversos grupos do Discourse para melhorias na análise de e-mails recebidos. Expressas como histórias de usuário, essas solicitações podem ser amplamente categorizadas como:

  • “Gostaria da capacidade de usar os mesmos recursos HTML ao responder por e-mail que uso ao postar no site.”
  • “Gostaria da capacidade de visualizar e pesquisar as mensagens da nossa lista de e-mails.”
  • “Gostaria que o conteúdo criado por e-mail, tanto via resposta por e-mail quanto importação em massa, fosse consistentemente bem formatado e analisado com precisão.”

Vou linkar exemplos reais dessas solicitações abaixo, mas, por enquanto, o importante a entender é que cada uma dessas três solicitações “diferentes” está, na verdade, pedindo a mesma coisa subjacente: uma análise de e-mails recebidos mais precisa.

Há alguns meses, enviei um e-mail ao @sam sobre permitir que o Discourse utilizasse a API de análise de e-mails comercial que nossa empresa oferece. O Sam sugeriu criar um post exploratório aqui para explicar os benefícios que a integração com nossa API proporcionaria em relação à solução existente de análise de e-mails recebidos do Discourse, e também como nossa API poderia ser integrada como um plugin.

Vou abordar ambos os tópicos em detalhes, começando pelo estado atual da solução de análise de e-mails do Discourse. E, para benefício daqueles que não passaram os últimos anos pensando sobre análise de e-mails, também incluirei algum contexto de fundo sobre o problema.

Este post é bastante longo, mas fique à vontade para pular entre as seções. Aqui está o que será abordado:

  1. O estado atual da análise de e-mails no Discourse
  2. Os benefícios de uma melhor análise de e-mails
  3. Personas de usuários das partes interessadas
  4. A API de Análise de E-mails FWD:Everyone
    A. Remoção de assinaturas e respostas
    B. Normalização de marcação HTML
    C. Suporte a idiomas
    D. Estilização com CSS
  5. Integração Proposta
  6. Testando a API

O estado atual da análise de e-mails no Discourse

O Discourse já possui um recurso de resposta por e-mail que converte respostas de e-mail de usuários em novas postagens do fórum dentro de um tópico. Este recurso funciona da seguinte maneira:

  1. Um usuário recebe uma notificação por e-mail contendo uma nova postagem em um tópico do fórum que está assistindo.
  2. O usuário responde a esse e-mail.
  3. Essa resposta por e-mail é convertida em uma nova postagem no tópico do fórum relevante.

Conceptualmente, este é um recurso inestimável; é o fluxo de trabalho preferido de muitas pessoas e é essencial para muitas comunidades baseadas em listas de e-mails que estão considerando migrar para o Discourse.

O problema é que, quando essas respostas por e-mail são convertidas em postagens do fórum, elas frequentemente são renderizadas com formatação ausente ou incorreta, ou até mesmo texto faltando. Isso é profundamente problemático, por razões que explorarei abaixo.

Problemas comuns incluem:

  • Marcadores não sendo renderizados corretamente
  • Quebras de linha ausentes entre o texto
  • Quebras de linha extras entre o texto
  • Texto escrito pelo usuário sendo completamente excluído

E quando digo que esses problemas são comuns, não quero dizer que ocorrem ocasionalmente ao enviar e-mails em idiomas estrangeiros usando clientes de e-mail obscuros. Quero dizer que ocorrem comumente ao enviar mensagens básicas de resposta por e-mail do Gmail e do Outlook em inglês.

Aqui estão dois exemplos reais de usuários reclamando desses problemas, ambos da lista de e-mails [Python-Dev]:

https://www.prettyfwd.com/t/Wco-c1ZCR7mUwiww0j6s9w/#message-5
https://www.prettyfwd.com/t/Wco-c1ZCR7mUwiww0j6s9w/#message-36

(O Prettyfwd utiliza a API de Análise de E-mails FWD:Everyone.)

Embora eu não tenha tentado importar conteúdo de listas de e-mails existentes com o Discourse, posso dizer por experiência própria que, seja qual for a taxa de erro para respostas por e-mail, a taxa de erro ao renderizar threads inteiras de e-mail será pelo menos uma ordem de magnitude maior. Isso se deve à complexidade aumentada ao remover assinaturas e respostas, contabilizar respostas inline, lidar com marcações profundamente aninhadas, etc.

Como exemplo real, este relato de migração do Mailman para o Discourse, escrito por Tanya Lattner (presidente da fundação LLVM), alude a esses problemas na seção de preocupações técnicas:

Perguntei e descobri que a coisa específica que os deixa chateados é a alta porcentagem de e-mails com conteúdo ausente devido ao corte prematuro. Como as discussões e documentação pré-existentes dos últimos 19 anos do arquivo da lista de e-mails são inestimáveis, eles sentem que não poderão desativar o Mailman até que esse problema seja totalmente resolvido.

Então, como sabemos se o estado atual da análise de e-mails no Discourse é “suficientemente bom”? Ofereceria isso como um teste de três partes:

  1. Os usuários precisam confiar plenamente que, se usarem o recurso de resposta por e-mail, seu conteúdo será analisado com precisão e ficará tão bom quanto se tivessem postado via interface web.
  2. Os administradores do fórum precisam confiar que, se permitirem a resposta por e-mail, isso não criará trabalho extra e reclamações.
  3. Os funcionários do Discourse precisam confiar o suficiente no recurso para promovê-lo ativamente como uma forma de primeira classe de participar.

A menos que possamos dizer com total confiança que cada uma dessas condições está sendo atendida, mesmo que a resposta por e-mail exista como um recurso, a vasta maioria dos benefícios potenciais nunca será alcançada.

Isso é o que está acontecendo atualmente.

Ou seja, eu caracterizaria o código existente de análise de e-mails como uma solução 80-20, mas em um contexto onde uma solução 80-20 não faz realmente sentido; o problema é que, mesmo que, por exemplo, 80% dos e-mails sejam analisados corretamente, é improvável que você esteja obtendo nem mesmo 10% dos benefícios potenciais.

Portanto, embora a resposta por e-mail (e a importação em massa de e-mails) já existam, os usuários, em última análise, não estão obtendo a experiência que procuram, trabalho extra está sendo criado para moderadores e equipe, comunidades estão perdendo conteúdo valioso e crescimento de usuários, etc.

Os benefícios de uma melhor análise de e-mails

Software social só tem sucesso na medida em que atende às necessidades humanas.

As razões pelas quais as pessoas postam em fóruns da web incluem querer compartilhar conhecimento com outros, querer influenciar suas opiniões, querer ser visto como geralmente inteligente, como tendo expertise no domínio, como fazendo contribuições valiosas do mundo real, etc.

E, no que diz respeito à comunicação baseada em texto, a probabilidade de alcançar esses resultados depende não apenas do que é dito, mas também da tipografia com que se diz.

É por isso que existem livros inteiros sobre espaços em branco em Shakespeare. É parcialmente por isso que o NY Times é levado mais a sério do que o NY Post. E é uma grande parte do motivo pelo qual o Facebook venceu o MySpace.[1]

Quando o texto que um usuário escreve acaba mal formatado, sem culpa própria, as necessidades humanas que levam as pessoas a usar software social deixam de ser atendidas. Na verdade, está acontecendo o oposto; os usuários são feitos de parecer tolos.

Mesmo pessoas que não usam o recurso de resposta por e-mail acabam perdendo autoridade e respeito se outras postagens no tópico (e no fórum maior) acabarem parecendo um incêndio em um lixeiro.

Personas de Usuários das Partes Interessadas

Embora todos se beneficiem quando as postagens são renderizadas consistentemente com tipografia esteticamente agradável, as personas de usuários que podem se beneficiar especialmente de uma melhor análise de e-mails recebidos incluem:

  1. Pessoas que são atualmente membros de listas de e-mails como [Python-Dev] e [Django-Dev], que entendem totalmente os benefícios do Discourse e ficam felizes em ver suas comunidades migrarem para o Discourse, mas apenas se puderem continuar a participar de uma maneira indistinguível do GNU Mailman, Google Groups, etc. Aqui está um exemplo real desse tipo de solicitação: https://www.prettyfwd.com/t/Wco-c1ZCR7mUwiww0j6s9w/#message-89
  2. Membros de comunidades baseadas em e-mail que geralmente ficariam felizes em migrar para o Discourse, mas que estariam muito mais entusiasmados em fazê-lo se suas décadas de conteúdo existente fossem facilmente pesquisáveis dentro da mesma plataforma.
  3. Usuários casuais que verificam fóruns intermitentemente. Por exemplo, no Growing Fruit, estou inscrito por e-mail em todos os tópicos sobre o cultivo de pawpaws norte-americanos. Durante o verão e o outono, visito aquele fórum várias vezes ao dia para ler o fluxo constante de novas postagens nesses tópicos, mas fora desses meses, são principalmente as notificações por e-mail nesses tópicos que me mantêm engajado.
  4. Pessoas que usam a web apenas intermitentemente. Frequentemente assume-se que, se as pessoas não usam a web regularmente, isso de alguma forma está relacionado à divisão digital, mas muitas vezes não é esse o caso. Há muitas pessoas que são altamente inteligentes e técnicas, mas que estão isoladas da necessidade de usar a web regularmente por estarem no topo de seus campos. Um exemplo do mundo real aqui é alguém como Donald Knuth, que não usa a web regularmente, apesar de ser um dos principais cientistas da computação vivos. Todo campo tem pessoas assim, e fazê-las compartilhar seu conhecimento é inestimável. Na minha experiência, essas pessoas são improváveis de se tornarem contribuidoras regulares de qualquer fórum, mas se alguém disser a elas que há um tópico que as pessoas estão discutindo e que lhes interessa, elas frequentemente se inscrevem por e-mail e contribuem para esses tópicos específicos.

A grande imagem é que melhorar a análise de e-mails recebidos não deve apenas aumentar o engajamento de pessoas que já são contribuidoras ativas regulares do Discourse, mas também deve desbloquear muitas comunidades que, de outra forma, gostariam de migrar para a plataforma, e também solicitar conteúdo altamente valioso de pessoas que, de outra forma, não contribuiriam.

A API de Análise de E-mails FWD:Everyone

A API de análise de e-mails FWD:Everyone faz duas coisas:

  1. Remove com precisão assinaturas e respostas de cada mensagem de e-mail, permitindo ainda respostas inline a texto citado.
  2. Pega a marcação HTML extremamente complicada gerada por clientes de e-mail e normaliza essa marcação para os ~12 tags HTML que são tipicamente permitidos por sites de conteúdo gerado pelo usuário — tudo isso preservando a intenção do autor na maior extensão possível.

Vou explicar ambos com mais detalhes, mas primeiro aqui está um vídeo que fiz que explica o problema mostrando threads de e-mail do mundo real: https://www.youtube.com/watch?v=nPb3NQlz6V4

Remoção de Assinaturas e Respostas

A API de análise de e-mails FWD:Everyone funciona em e-mails de texto simples e HTML com igual precisão. A API usa preferencialmente a parte da mensagem HTML quando disponível, porque

  • Os recursos de formatação HTML (como negrito, itálico, citações em bloco, trechos de código, etc.) que um autor escolhe usar são uma parte essencial da mensagem do autor, tão importantes quanto o próprio texto.
  • Quando os clientes de e-mail convertem a versão HTML de uma mensagem para a versão de texto simples, muitas vezes o fazem incorretamente. Por exemplo, não apenas os clientes de e-mail frequentemente não fazem nenhuma tentativa de renderizar recursos HTML como listas de marcadores em texto simples, mas muitas vezes o texto dentro de elementos de formatação HTML estará completamente ausente.

Claro, alguns usuários preferem enviar e-mails de texto simples; por isso, e-mails apenas em texto simples devem ter suas assinaturas e respostas removidas com igual precisão.

A API de Análise de E-mails FWD:Everyone faz isso, incluindo o tratamento correto de respostas inline em e-mails de texto simples e HTML.

Em termos de precisão, existem dois tipos de erros que podem ocorrer em qualquer biblioteca de análise de e-mails ao remover assinaturas e respostas:

  • Falsos positivos — Quando o texto que deveria ser incluído na mensagem é incorretamente excluído.
  • Falsos negativos — Quando o texto que não deveria ser incluído na mensagem é incorretamente incluído.

É difícil fornecer estatísticas precisas de precisão porque diferentes comunidades do Discourse (com d minúsculo) usam e-mail de maneiras tão diferentes. Mas, comparado com a solução atual de análise do Discourse, uma expectativa realista pode ser:

  • 100x menos falsos positivos para remoção de assinaturas e respostas
  • 10x menos falsos negativos para remoção de respostas
  • 1x - 10x menos falsos negativos para remoção de assinaturas — provavelmente melhor, mas não uma ordem de magnitude completa melhor.

Para contexto, falsos positivos são geralmente muito piores do que falsos negativos, pois distorcem o que a pessoa escreveu. Mas falsos negativos também são muito ruins, pois fazem o postador (e todos os outros no fórum) parecerem pouco profissionais no melhor dos casos, e completamente tolos no pior.

A abordagem que o FWD:Everyone adota é evitar qualquer truque para remover assinaturas que possa levar a falsos positivos; o aumento ostensivo de falsos negativos que isso levaria é então amplamente equilibrado apenas por ter feito muito mais trabalho para fazer o algoritmo funcionar de maneira legítima, sem precisar cortar cantos.

A razão da grande imagem de por que a API de Análise de E-mails FWD:Everyone será geralmente muito mais precisa do que a solução atual do Discourse é que nossa API foi projetada para analisar threads inteiras de e-mail, o que é um problema muito mais difícil do que analisar postagens únicas de resposta por e-mail. O resultado final é que nosso produto é altamente superengenhariado, pelo menos em relação às necessidades do Discourse e à arte pré-existente existente.

Normalização de Marcação HTML

Para que as respostas enviadas por e-mail (e threads de e-mail importadas) pareçam iguais a qualquer outro conteúdo gerado pelo usuário, elas devem, em última análise, ser renderizadas usando o mesmo subconjunto de HTML que é permitido quando os usuários respondem via site.

Isso é surpreendentemente complicado.

E-mails compostos em clientes de e-mail como Gmail e Outlook são codificados usando alguma combinação de ~50 tags HTML, ~25 atributos HTML e ~175 estilos CSS. Além disso, essa marcação é frequentemente altamente ofuscada; você pode esperar que um parágrafo de texto se pareça com algo assim:

<p>Algum texto!</p>

Mas, em vez disso, mesmo parágrafos simples são frequentemente codificados usando combinações profundamente aninhadas e completamente sem sentido de divs, spans, tabelas, listas, etc. Esta é a principal fonte de complexidade tanto para remover respostas quanto para normalizar marcação.

Independentemente disso, após a análise, cada mensagem é renderizada usando apenas a seguinte marcação:

Elementos de bloco permitidos: <p>, <ul>, <ol>, <li>, <blockquote>, <pre>
Elementos inline permitidos: <code>, <a>, <b>, <i>, <u>, <s>, <span>

Notas:

  • Os únicos atributos permitidos (exceto em tags <a>) são 'style' e 'dir'.
  • O único estilo inline permitido é 'font-weight'.
  • Tags <a> também podem ter atributos 'href', 'rel', 'title' e 'target'.
  • Elementos <span> são usados apenas em casos limitados para garantir que os pesos das fontes cascatem corretamente. Assim, eles são sempre usados com um 'font-weight' inline.
  • No futuro, a tag <img> também será usada para exibir imagens inline.

Renderizar postagens nesse subconjunto limitado de HTML permite que qualquer postagem enviada por e-mail seja facilmente renderizada usando a mesma tipografia exata que as postagens enviadas através da interface web.

Tudo isso é feito preservando a intenção do autor na maior extensão possível, enquanto também garante que eles não possam fazer coisas como adicionar dezenas de quebras de linha desnecessárias entre parágrafos.

Veja também: A seção „Estilização com CSS“ abaixo.

Suporte a Idiomas

O EmailReplyTrimmer atualmente tem suporte total ou parcial para 13 idiomas:

Inglês, Norueguês, Francês, Alemão, Português, Espanhol, Italiano, Holandês, Sueco, Chinês, Russo, Polonês, Ucraniano

Em contraste, a API de Análise de E-mails FWD:Everyone atualmente suporta mais de 30 idiomas, incluindo todos os idiomas que o Discourse atualmente suporta:

Inglês, Espanhol, Português, Catalão, Holandês, Francês, Alemão, Italiano, Norueguês, Dinamarquês, Sueco, Finlandês, Russo, Polonês, Ucraniano, Turco, Tcheco, Romeno, Húngaro, Hebraico, Árabe, Persa, Chinês, Japonês, Coreano, Hindi, Indonésio, Tailandês, Filipino, Africâner

A API de Análise de E-mails FWD:Everyone suporta totalmente idiomas RTL. Isso significa que não apenas o texto fluirá corretamente da direita para a esquerda em idiomas como o árabe, mas também os atributos apropriados são aplicados à marcação HTML para que recursos como marcadores sejam renderizados no lado correto da página.

A API às vezes também funcionará em idiomas adicionais dependendo do cliente de e-mail usado, mas o conjunto oficial de idiomas suportados é, no mínimo, testado para funcionar com Gmail, Outlook e Apple Mail. Clientes de e-mail menos populares são explicitamente testados nos idiomas onde têm o maior uso. E como a API é testada contra milhares de threads de e-mail de listas de e-mails públicas, há inúmeras correções para comportamento errático do mundo real de origem desconhecida.

Nota: que suportar uma ampla variedade de idiomas é importante por mais do que apenas exibir texto nesses idiomas. É muito comum as pessoas escreverem texto em inglês, mas terem seu cliente de e-mail configurado para usar, por exemplo, hebraico. Portanto, em casos como este, analisar corretamente uma resposta em inglês exigiria não apenas suportar totalmente o hebraico, mas também suportar idiomas da direita para a esquerda de forma mais geral.

Suportar idiomas de uma ampla variedade de famílias linguísticas também ajuda a garantir que o Unicode esteja sendo processado e armazenado corretamente, em vez de de maneiras que possam causar problemas no futuro à medida que o suporte a mais idiomas não ocidentais for adicionado.

Estilização com CSS

Como mencionado acima, uma força chave de nossa API é sua capacidade de normalizar a marcação HTML de maneira pensativa e lógica. Esse processo de normalização é projetado para otimizar o texto para legibilidade e acessibilidade, enquanto preserva a intenção original do autor na maior extensão possível.

Como tal, todo o texto aparece apenas dentro de elementos inline ou de bloco (nenhum texto flutuando livremente), e todos os elementos inline aparecem apenas dentro de elementos de bloco. Isso torna fácil estilizar texto, por exemplo, para garantir que diferentes elementos tenham a quantidade correta de espaço em branco entre eles.

Como exemplo de como isso é valioso, clientes de e-mail permitem que os usuários façam coisas bobas como inserir uma lista de marcadores diretamente antes ou depois de uma linha de texto, sem quebra de linha no meio. O código (vastamente simplificado) gerado por um cliente de e-mail ao fazer isso pode se parecer com algo assim:

<div>
    Algum texto
    <div> </div>
    <span>&nbsp;&nbsp;&nbsp;&nbsp;&#8226; Um marcador</span>
     <div> </div>
     Mais algum texto
</div>

A API de Análise de E-mails FWD:Everyone normalizaria a marcação acima para parecer assim:

<p>Algum texto</p>
<ul>
    <li>Um marcador</li>
</ul>
<p>Mais algum texto</p>

Essa marcação normalizada é fácil de entender e estilizar, e visualmente agora também há quebras de linha antes e depois da lista de marcadores. Afeições como essas tornam o texto mais bonito e mais fácil de ler, preservando a intenção do autor. Esses tipos de affordances de usuário garantem que ótimo conteúdo enviado por e-mail esteja consistentemente conferindo status social, em vez de miná-lo.

A marcação simplificada e normalizada gerada por nossa API também garante que, ao pensar em como estilizar texto, designers e desenvolvedores só precisem pensar na saída que a API permite, em vez de como o e-mail original pode ter sido formatado. E como a saída permitida pela API é virtualmente idêntica ao que o cliente web do Discourse permite, isso deve ser próximo de uma solução plug-and-play.

Integração Proposta

A funcionalidade de resposta por e-mail seria integrada ao Discourse como um plugin, que poderia então ser ativado por padrão para todas as instâncias hospedadas do Discourse.

O código existente de análise de e-mails seria usado para instâncias do Discourse que não têm esse plugin ativado.

Além disso, caso a API de Análise de E-mails FWD:Everyone ficasse temporariamente indisponível, qualquer mensagem recebida seria processada usando o código existente de análise de e-mails. Então, uma vez que a API voltasse online, qualquer mensagem que não tivesse sido editada via interface web desde a postagem poderia então ser reprocessada pela API.

O plugin também poderia ser disponibilizado para instâncias auto-hospedadas do Discourse para ser ativado opcionalmente.

Para grupos migrando de listas de e-mails existentes para o Discourse, cada thread de e-mail na lista de e-mails também poderia ser analisada via API, mas isso provavelmente seria integrado aos scripts e processos de migração existentes do Discourse, em vez de ser feito via plugin.[2]

Testando a API

A API está totalmente disponível para qualquer pessoa testar, embora com um limite de taxa muito baixo para usuários não autenticados.

Para aqueles com contas do Gmail, as maneiras mais fáceis de testar a API são:

Diferenças chave entre essas duas ferramentas baseadas na web e a API real são que a primeira:

  1. Não processará threads que contêm mensagens estilizadas usando tabelas HTML
  2. Não removerá respostas na primeira mensagem de uma thread. (Por exemplo, se uma thread tiver mais de 100 mensagens, o Gmail a dividirá em várias threads.)

Para testar a API diretamente via código, existem scripts iniciantes para Python e Ruby:

E aqui está a documentação relevante, incluindo problemas conhecidos e o roteiro do produto:

[1] Viewing American class divisions through Facebook and MySpace.

[2] Ao importar conteúdo em massa de uma lista de e-mails existente, vale a pena fazer uma verificação rápida de sanidade em algumas threads para garantir que elas estejam sendo analisadas corretamente. Alguns grupos serão analisados com precisão quase perfeita como estão, mas outros podem se beneficiar muito de algumas horas de trabalho preventivo. Por exemplo, alguns softwares de lista de e-mails exigem um pouco de código personalizado para cada lista para remover qualquer texto anexado ao final de cada mensagem, enquanto para outros softwares de lista de e-mails isso pode ser feito de uma maneira previsível que funcionará para qualquer lista hospedada nessa plataforma. Devido a problemas potenciais como este, o processo de importação em massa deve preferencialmente ser executado como parte de uma migração supervisionada, em vez de ser feito via plugin.

4 curtidas

Fez algum progresso com isso? Parece muito interessante.

Como um usuário entusiasta do Discourse, a única coisa que eu gostaria seria poder converter um tópico de e-mail existente em um tópico do Discourse - com os autores e horários preservados e toda a enrolação removida.

O motivo para isso é a tendência humana de iniciar uma conversa em grupo por e-mail, e depois de 10-20 “responder a todos” alguém percebe e diz “isso não deveria estar no Fórum”? Aí já é tarde demais…

Fazer isso manualmente é desanimador. Mas se esta API pudesse ser aproveitada para fazer isso de alguma forma - maravilhoso!!!

@nathank Não dediquei nenhum trabalho à escrita de um wrapper de API, apenas por falta de interesse até agora. Não é um grande esforço, mas é trabalho suficiente para que não faça muito sentido, a menos que haja uma demanda mais concreta. Dito isso, a própria API continua melhorando.

1 curtida