Plugin ActivityPub

@hellekin Obrigado pelo relatório. Uma certa quantidade de requisições falhas sempre ocorrerá em um serviço ActivityPub, pois os atores no fediverso vêm e vão. Por exemplo, parece que

  • A URL https://activitypub.example do primeiro log não é uma URL real (você a alterou?)
  • O usuário https://mas.to/users/rikvipcode do segundo log não existe mais
  • O usuário https://mastodon.social/users/ejovoni46709 do terceiro log não existe mais

A verbosidade dos logs está lá para ajudar na depuração, no entanto, se eles estiverem poluindo seus logs, você pode alterná-los usando a configuração do site activity pub verbose logging. O padrão é desativado.

Procuraremos fazer melhorias no tratamento de erros na fase dois, se necessário, mas até agora parece que os trechos que você postou são esperados, ou seja, os Atores não estão mais no fediverso.

Atualmente, a maneira como o plugin lida com falhas de entrega é rastreá-las da mesma forma que o Mastodon faz, ou seja, se houver 7 dias de falha para um endpoint, ele será marcado como “indisponível” e as requisições não serão mais tentadas.

3 curtidas

Sim, como indicado na linha anterior.

De fato, mas o código de status é 410, o que significa que a conta pode ter sido movida (se houver uma Tombstone — essa condição é verificada?)

1 curtida

Não. É o erro 410 Gone e significa que o recurso foi excluído. O que estou perdendo agora?

1 curtida

Você perdeu isto:

Olá @angus,

Acabei de configurar um Discourse auto-hospedado novinho em folha com o seu plugin AP em https://federation.cafe, e estou vendo alguns erros 403 nos Logs de Erro do Discourse (e as postagens não estão sendo compartilhadas).

Estou imaginando se pode ser porque existem hífens, talvez?

[Discourse Activity Pub] GET request to https://bofh.social/internal/fetch failed: Expected([200, 201, 202, 301, 302, 307, 308]) <=> Actual(403 Forbidden)

/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/request.rb:66:in `rescue in perform'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/request.rb:50:in `perform'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/request.rb:34:in `get_json_ld'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/request.rb:106:in `get_json_ld'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/json_ld.rb:52:in `request_object'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/json_ld.rb:48:in `resolve_object'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/ap/actor.rb:103:in `resolve_and_store'
/var/www/discourse/plugins/discourse-activity-pub/app/controllers/concerns/discourse_activity_pub/signature_verification.rb:192:in `actor_from_key_id'
/var/www/discourse/plugins/discourse-activity-pub/app/controllers/concerns/discourse_activity_pub/signature_verification.rb:57:in `signed_request_actor'
/var/www/discourse/plugins/discourse-activity-pub/app/controllers/concerns/discourse_activity_pub/signature_verification.rb:27:in `ensure_verified_signature'
activesupport-7.0.4.3/lib/active_support/callbacks.rb:400:in `block in make_lambda'
activesupport-7.0.4.3/lib/active_support/callbacks.rb:180:in `block (2 levels) in halting_and_conditional'
actionpack-7.0.4.3/lib/abstract_controller/callbacks.rb:34:in `block (2 levels) in <module:Callbacks>'
activesupport-7.0.4.3/lib/active_support/callbacks.rb:181:in `block in halting_and_conditional'
activesupport-7.0.4.3/lib/active_support/callbacks.rb:595:in `block in invoke_before'
activesupport-7.0.4.3/lib/active_support/callbacks.rb:595:in `each'
activesupport-7.0.4.3/lib/active_support/callbacks.rb:595:in `invoke_before'
activesupport-7.0.4.3/lib/active_support/callbacks.rb:116:in `block in run_callbacks'
/var/www/discourse/app/controllers/application_controller.rb:418:in `block in with_resolved_locale'
i18n-1.14.1/lib/i18n.rb:322:in `with_locale'
/var/www/discourse/app/controllers/application_controller.rb:418:in `with_resolved_locale'
activesupport-7.0.4.3/lib/active_support/callbacks.rb:127:in `block in run_callbacks'
activesupport-7.0.4.3/lib/active_support/callbacks.rb:138:in `run_callbacks'
actionpack-7.0.4.3/lib/abstract_controller/callbacks.rb:233:in `process_action'
actionpack-7.0.4.3/lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack-7.0.4.3/lib/action_controller/metal/instrumentation.rb:67:in `block in process_action'
activesupport-7.0.4.3/lib/active_support/notifications.rb:206:in `block in instrument'
activesupport-7.0.4.3/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport-7.0.4.3/lib/active_support/notifications.rb:206:in `instrument'
actionpack-7.0.4.3/lib/action_controller/metal/instrumentation.rb:66:in `process_action'
actionpack-7.0.4.3/lib/action_controller/metal/params_wrapper.rb:259:in `process_action'
activerecord-7.0.4.3/lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack-7.0.4.3/lib/abstract_controller/base.rb:151:in `process'
actionview-7.0.4.3/lib/action_view/rendering.rb:39:in `process'
rack-mini-profiler-3.1.0/lib/mini_profiler/profiling_methods.rb:85:in `block in profile_method'
actionpack-7.0.4.3/lib/action_controller/metal.rb:188:in `dispatch'
actionpack-7.0.4.3/lib/action_controller/metal.rb:251:in `dispatch'
actionpack-7.0.4.3/lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
actionpack-7.0.4.3/lib/action_dispatch/routing/route_set.rb:32:in `serve'
actionpack-7.0.4.3/lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack-7.0.4.3/lib/action_dispatch/journey/router.rb:32:in `each'
actionpack-7.0.4.3/lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack-7.0.4.3/lib/action_dispatch/routing/route_set.rb:852:in `call'
railties-7.0.4.3/lib/rails/engine.rb:530:in `call'
railties-7.0.4.3/lib/rails/railtie.rb:226:in `public_send'
railties-7.0.4.3/lib/rails/railtie.rb:226:in `method_missing'
actionpack-7.0.4.3/lib/action_dispatch/routing/mapper.rb:19:in `block in <class:Constraints>'
actionpack-7.0.4.3/lib/action_dispatch/routing/mapper.rb:48:in `serve'
actionpack-7.0.4.3/lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack-7.0.4.3/lib/action_dispatch/journey/router.rb:32:in `each'
actionpack-7.0.4.3/lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack-7.0.4.3/lib/action_dispatch/routing/route_set.rb:852:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:74:in `call'
rack-2.2.7/lib/rack/tempfile_reaper.rb:15:in `call'
rack-2.2.7/lib/rack/conditional_get.rb:27:in `call'
rack-2.2.7/lib/rack/head.rb:12:in `call'
actionpack-7.0.4.3/lib/action_dispatch/http/permissions_policy.rb:38:in `call'
/var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:367:in `call'
rack-2.2.7/lib/rack/session/abstract/id.rb:266:in `context'
rack-2.2.7/lib/rack/session/abstract/id.rb:260:in `call'
actionpack-7.0.4.3/lib/action_dispatch/middleware/cookies.rb:704:in `call'
actionpack-7.0.4.3/lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport-7.0.4.3/lib/active_support/callbacks.rb:99:in `run_callbacks'
actionpack-7.0.4.3/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack-7.0.4.3/lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'
actionpack-7.0.4.3/lib/action_dispatch/middleware/show_exceptions.rb:26:in `call'
logster-2.12.2/lib/logster/middleware/reporter.rb:43:in `call'
railties-7.0.4.3/lib/rails/rack/logger.rb:40:in `call_app'
railties-7.0.4.3/lib/rails/rack/logger.rb:27:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:20:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:29:in `call'
actionpack-7.0.4.3/lib/action_dispatch/middleware/remote_ip.rb:93:in `call'
actionpack-7.0.4.3/lib/action_dispatch/middleware/request_id.rb:26:in `call'
/var/www/discourse/lib/middleware/enforce_hostname.rb:24:in `call'
rack-2.2.7/lib/rack/method_override.rb:24:in `call'
actionpack-7.0.4.3/lib/action_dispatch/middleware/executor.rb:14:in `call'
rack-2.2.7/lib/rack/sendfile.rb:110:in `call'
actionpack-7.0.4.3/lib/action_dispatch/middleware/host_authorization.rb:131:in `call'
rack-mini-profiler-3.1.0/lib/mini_profiler.rb:260:in `call'
message_bus-4.3.2/lib/message_bus/rack/middleware.rb:60:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:228:in `call'
railties-7.0.4.3/lib/rails/engine.rb:530:in `call'
railties-7.0.4.3/lib/rails/railtie.rb:226:in `public_send'
railties-7.0.4.3/lib/rails/railtie.rb:226:in `method_missing'
rack-2.2.7/lib/rack/urlmap.rb:74:in `block in call'
rack-2.2.7/lib/rack/urlmap.rb:58:in `each'
rack-2.2.7/lib/rack/urlmap.rb:58:in `call'
unicorn-6.1.0/lib/unicorn/http_server.rb:634:in `process_client'
unicorn-6.1.0/lib/unicorn/http_server.rb:739:in `worker_loop'
unicorn-6.1.0/lib/unicorn/http_server.rb:547:in `spawn_missing_workers'
unicorn-6.1.0/lib/unicorn/http_server.rb:143:in `start'
unicorn-6.1.0/bin/unicorn:128:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/3.2.0/bin/unicorn:25:in `load'
/var/www/discourse/vendor/bundle/ruby/3.2.0/bin/unicorn:25:in `<main>'

hostname	LILEJAP07-app
process_id	658
application_version	1abfe2e61d12b1b559aab0132ec3fb7cc8b87232
HTTP_HOST	federation.cafe
REQUEST_URI	/ap/actor/5ce52c043e670476a1426f9a66472c07
REQUEST_METHOD	GET
HTTP_USER_AGENT	Akkoma 3.8.0-0-gccae7ef; https://bofh.social <admin@bofh.social>
HTTP_ACCEPT	application/activity+json
HTTP_X_FORWARDED_FOR	91.107.215.39, 172.71.250.70
HTTP_X_REAL_IP	172.71.250.70
time	2:16 pm

Pensamentos?

Eu também estaria interessado em posts completos. Nesse caso, o tipo “artigo” deve ser usado em vez de “nota”.

Na verdade, os anúncios são muito menos interessantes para mim do que os recursos de fórum federados.

Existe um roteiro e/ou um local para enviar doações para recursos como este?

Olá @gme, obrigado por experimentar o plugin

Algumas coisas para notar inicialmente aqui

  1. O plugin MVP é testado contra o Mastodon. Vejo que você está usando Pleroma lá. Sei que Pleroma é compatível com ActivityPub e funciona com Mastodon, no entanto, ainda não analisamos de perto quais ajustes podem ser necessários (se houver) para garantir o suporte a ele. Mas ainda estou interessado em ver o que está acontecendo aqui.

  2. Parece que as requisições falharam devido a um erro de autenticação no seu servidor Pleroma (é isso que um erro 403 significa). Como consigo obter esse endpoint usando uma requisição cURL não autenticada, suspeito que possa ser a autenticação HTTP que está falhando no lado do Pleroma.

Para testar o último (ou seja, 2), você poderia verificar seus logs do Pleroma (parece que você também é o administrador desse servidor?) se possível para ver se consegue mais detalhes sobre essa parte?

Obrigado pelo feedback @bmann. Você poderia detalhar o caso de uso que você tem em mente aqui? Com um exemplo, se possível.

Este tópico é o melhor lugar para se manter atualizado sobre os desenvolvimentos. Quando definirmos um plano de fase 2, eu o compartilharei aqui. Enquanto isso, a melhor maneira de ajudar é compartilhar os casos de uso específicos para os quais você está usando, ou gostaria de usar, o plugin.

5 curtidas

O caso de uso é usar o Discourse como um nó AP mais completo. Existem muitas maneiras mais fáceis de postar conteúdo no AP (por exemplo, usar feeds RSS de categoria e Zapier ou Buffer) — mas desenvolver uma capacidade AP mais completa só pode ser feita como um plugin/integração.

Article é o tipo ActivityStream destinado a artigos completos. Dependendo da interface do cliente, ele mostrará uma prévia e, em seguida, um clique para mostrar o artigo inteiro inline (muito parecido com avisos de conteúdo, mas com “leia mais”).

Note é o tipo de microblog.

Ao ter posts Article completos, as pessoas podem ler / impulsionar / responder diretamente em seus clientes AP.

E, claro, seria interessante saber sobre seu roteiro se você for seguir uma instância AP mais focada em Microblogging, ou ir em direção a um fórum federado como Lemmy ou Kbin, especialmente dadas as notícias recentes do Reddit.

1 curtida

@angus, @pmusaraj vocês viram a chamada aberta de financiamento NGI Sargasso? É um aviso bastante curto, mas pode ser útil para o desenvolvimento posterior deste plugin (a menos que vocês já tenham outros planos).

1 curtida

Olá pessoal, tenho o prazer de anunciar que a segunda fase do trabalho neste plugin foi aprovada. É com isso que já começamos a trabalhar, com o objetivo de lançá-lo em cerca de 3,5 meses.

Suporte para edição de Nota pós-publicação

Suporte para restauração de Notas

Suporte para publicação de posts publicamente, bem como apenas para seguidores

Melhorar a análise de conteúdo de Notas

  • Lidar com caracteres especiais (talvez usar um analisador diferente). Veja mais.

Suporte para uso de Artigo em vez de Nota como Objeto de um post.

  • Configuração em nível de categoria

Suporte para aceitar Atividades em resposta a uma Nota feita remotamente e publicar Atividades em resposta a uma Nota feita no Discourse.

  • Publicar Atividades relativas a respostas feitas no Discourse
    • Permitir que usuários do Discourse sejam Atores
    • Criar objetos de Nota para respostas do Discourse (posts)
    • Publicar Atividades de Criação/Exclusão/Atualização/Desfazer associadas para suas ações equivalentes no Discourse
  • Aceitar Atividades relativas a respostas feitas remotamente
    • Preparar os Atores de Atividades de servidores remotos como usuários do Discourse
    • Criar respostas do Discourse (posts) a partir de objetos de Nota
    • Converter Atividades de Criação/Exclusão/Atualização/Desfazer associadas em suas ações equivalentes no Discourse
  • Adicionar uma configuração de categoria para alternar entre Apenas o Primeiro Post (atual) e “Tópico Completo”, que suporta Atividades de resposta.

Suporte para Atividade de Curtir

Suporte para usuários do Discourse verificarem sua identidade no Mastodon para que posts do Discourse criados a partir de seus Toots sejam associados à sua conta de usuário do Discourse.

  • Permitir que um usuário execute o fluxo de Autorização OAuth do Mastodon com o servidor Mastodon onde sua conta está armazenada. Isso é iniciado nas configurações da conta do usuário no Discourse.
  • Usando o token de acesso do Mastodon do usuário do Discourse, obter e armazenar o ID AP de sua conta Mastodon e armazená-lo com sua conta do Discourse.
  • Associar todas as atividades do Discourse associadas a Atividades AP de um Ator que possua o ID AP de um usuário do Discourse a esse usuário do Discourse, quer tenham sido realizadas antes ou depois que o usuário verificou sua identidade.
15 curtidas

Isso é muito empolgante de se ver — um nível muito alto de federação e interatividade. :tada:

Vocês planejam fazer lançamentos intermediários ou será um grande lançamento em aproximadamente 3,5 meses?

Pode haver alguns lançamentos intermediários, mas ainda não posso prometer nada a respeito. Manterei você informado à medida que avançarmos.

2 curtidas

Concordo 110% — isso inclui muitos aspectos ótimos. :tada:

Há alguma chance de haver pelo menos um lançamento intermediário nessa frente?

Para ser honesto, adicionar um lançamento intermediário de "posts públicos como padrão" seria imediatamente bem-vindo.

2 curtidas

Note que a publicação pública dependeria da federação de ações de edição (o primeiro item listado), acredito.

1 curtida

Não posso fazer promessas nesta fase, mas pode haver atualizações intermediárias para a Federação de Atualização e Segmentação de Público (publicação pública).

4 curtidas

:olhos:

1 curtida

Essa é uma limitação conhecida. Até que as edições federadas sejam suportadas, o plugin bloqueia edições de conteúdo federado, e não há configuração para desabilitar isso.

2 curtidas

Para ser claro, eu estava tentando editar uma postagem aqui no meta e recebi este erro.

3 curtidas

Oh, desculpe por ter entendido mal. @feature@meta.discourse.org e @announcements@meta.discourse.org pelo menos estão sendo federados daqui, e essa escolha é o principal motivo pelo qual não habilitei isso para o Maker Forums…

2 curtidas

Sim, este é o primeiro item da Fase 2 em que trabalhei. Na verdade, já existe um PR para isso, então você terá algum alívio nesse sentido em breve.

2 curtidas