Vídeos do YouTube com onebox embedding pararam de funcionar

Há alguns dias (diria que logo após atualizar para o Discourse 2.5 beta 5 e continua no beta 6, mas pode ser apenas uma coincidência) a incorporação de vídeos do YouTube funciona de forma intermitente. Após algumas horas sem funcionar, volta a incorporar normalmente. Desde ontem, parou de funcionar completamente.

Não vejo nenhum erro suspeito específico nos logs do fórum.

Seria um problema de tempo limite? Há alguma maneira de investigar isso especificamente?

Obrigado desde já!

Encontrei algo estranho ao examinar o tráfego gerado ao solicitar uma recriação de uma postagem contendo um link do YouTube.
A solicitação falha com o erro 404. :thinking:

Mais um pouco de detalhe extra.
Estou executando o Discourse 2.5.0.beta6 atualizado para o commit 2d880b42a3 (reconstruído logo antes de enviar esta postagem).

Ao criar uma nova postagem com um link do YouTube, no console do Google Chrome, vejo um erro extra logo antes do 404 para o GET ao onebox, referindo-se a um erro de registro do Service Worker.

Quero ressaltar que qualquer onebox funciona, exceto o do YouTube. :confused:

O navegador não pode fornecer o motivo real pelo qual um onebox está falhando. Você precisa tentar fazer uma solicitação semelhante a partir do seu servidor.

Entendo o que você está sugerindo, mas:

  • se eu repetir a simples chamada GET (passando cabeçalhos e outros parâmetros como esperado) para /onebox?url=…, simplesmente recebo o erro HTML 404

  • se eu repetir, no servidor, a requisição que o onebox faz, copiando-a do código Ruby de youtube_onebox.rb, ou seja, curl 'https://www.youtube.com/oembed?format=json&url=https://www.youtube.com/watch?v=Xl-PTTeRsik' para um dos vídeos não incorporados, parece funcionar perfeitamente.
    A chamada realmente retorna:
    {"author_name":"AstronautiCAST","version":"1.0","height":270,"author_url":"https:\/\/www.youtube.com\/user\/AstronautiCAST","provider_name":"YouTube","provider_url":"https:\/\/www.youtube.com\/","thumbnail_height":360,"width":480,"html":"\u003ciframe width=\"480\" height=\"270\" src=\"https:\/\/www.youtube.com\/embed\/Xl-PTTeRsik?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen\u003e\u003c\/iframe\u003e","type":"video","thumbnail_width":480,"title":"Loading cargo into HTV-9 Konutori","thumbnail_url":"https:\/\/i.ytimg.com\/vi\/Xl-PTTeRsik\/hqdefault.jpg"}root@fait-2020:/var/discourse#
    que contém tudo que o onebox precisa para a incorporação.

Não estou entendendo :confused:

@Falco, peço desculpas por incomodar, mas a falta de oneboxing do YouTube está realmente prejudicando a experiência do usuário em nosso fórum.

Ontem, tentei várias coisas, como tentar ler o código-fonte (para entender em qual estágio e sob qual condição um erro 404 seria retornado pelo onebox) e até clonar o fórum de produção atual em um novo droplet separado na Digital Ocean.

Ler o código não ajudou muito, principalmente devido à minha falta de conhecimento real sobre a plataforma.
Uma pergunta permanece em aberto: o processo de oneboxing registra algo em algum lugar? Seria muito útil entender o erro que faz o onebox desistir e retornar 404.

O Droplet clonado foi uma tentativa de verificar se o IP do servidor de produção estava bloqueado pelo YouTube e, ao mesmo tempo, se havia algo relacionado ao nome de domínio que usamos.
Bem, mesmo com o endereço IP e o nome de domínio diferentes, o oneboxing do YouTube não funcionou.

Espero realmente que alguém possa me sugerir pelo menos uma maneira de rastrear o que o oneboxing faz.

Tenho a causa raiz: o YouTube bloqueou nosso IP, mas não está claro por que, já que, no momento em que isso aconteceu, não estávamos realizando nenhuma reprocessamento massivo ou similar.

Pergunta para @Falco ou @codinghorror: a instalação da versão 2.5.0beta 5 ou 6 acionou algum reprocessamento, o que teria excedido o limite de solicitações?

Não, não adicionamos nenhuma renderização recente. Parece uma mudança do YouTube, já que outros usuários também reclamaram.

Tente uma varredura de proxy usando "Onebox Assistant", crawl for those previews reliably!

Obrigado a todos pelas respostas.
No entanto, continua pouco claro para mim por que, ao imitar a solicitação que o motor onebox faz (ou pelo menos espero que seja esse o caso. É o @Falco?), recebo uma resposta JSON com uma resposta adequada e não um 429.

Existe outra solicitação feita pelo Onebox que recebe um 429 antes de realizar a solicitação conforme minha captura de tela, que é curl 'https://www.youtube.com/oembed?format=json&url=https://www.youtube.com/watch?v=Xl-PTTeRsik'?

É óbvio que essas solicitações foram feitas a partir do próprio servidor que executa o Discourse (mesmo IP de saída).

Uma única chamada curl dificilmente dispara um limite de taxa?

Tente uma série delas em rápida sucessão? Execute em um script bash repetitivo? (Mas não exagere, ou você pode ser banido)

Bem, simplesmente tentar recarregar um único post com um único link para o YouTube nos leva a um erro 404 do onebox…

Uma descoberta interessante após um fim de semana de resolução de problemas.
Isso pode ser algo que você gostaria de verificar, @Falco ou @codinghorror?

No momento, ao ler o código-fonte de youtube_onebox.rb, vejo que ele suporta 3 URLs das quais o ID do vídeo é extraído:

  1. http://youtu.be/<videoid>
  2. https://www.youtube.com/embed/<videoid>
  3. https://www.youtube.com/watch?v=<videoid>

Toda tentativa de criar onebox para vídeos cujos links estão nos formatos 1 e 3 falha com o onebox retornando 404 (o que acredito estar relacionado ao nosso IP sendo bloqueado).

Quando tento incorporar links no formato 2, funciona!

Fico me perguntando se e como isso pode estar relacionado ao fato explicado neste post.

Alguma compreensão (e registro de logs) sobre o funcionamento interno do onebox (ou seja, qual(is) chamada(s) exata(s) é(são) feita(s) ao YouTube) seria super útil…

Voltei aqui para encerrar este tópico.
Ontem, o YouTube removeu nosso banimento e estamos de volta aos negócios.

Há alguns pontos que, na minha opinião, seria interessante entender de qualquer forma:

  • seria possível registrar os detalhes do onebox em caso de falha? Isso seria muito útil para entender exatamente por que o onebox falha.
  • já que o único elemento necessário para fazer onebox de vídeos do YouTube é o ID do vídeo, não seria uma boa ideia tentar buscar dados em cada um dos 3 tipos de URL antes de retornar um 404 (como dito acima, a URL /embed/ de alguma forma nunca parou de funcionar, mesmo durante o banimento).

Obrigado a todos que responderam às minhas perguntas desesperadas! :clap:

ISSO!!! (é uma ótima ideia, já mencionei antes)

Acho que parte do desafio aqui é que, se o destino retornar uma página sem tags og, o Onebox não saberá que isso ocorreu devido a algum redirecionamento. No entanto, isso poderia ser registrado (“ONEBOX: nenhuma tag og encontrada”?), e todos os erros que resultam em oneboxes em branco deveriam ser registrados.

tl;dr Gostaria de acrescentar que estamos enfrentando o que parece ser o mesmo problema. Se houver um problema de limite de taxa devido a alguma mudança recente, acredito que outros usuários começarão a experimentá-lo durante a migração, o reprocessamento de postagens ou talvez apenas devido a um fórum muito movimentado. O fato de o onebox aparentemente falhar silenciosamente significa que esses problemas só se tornam visíveis quando os usuários começam a reclamar que os oneboxes do YouTube estão faltando.

Contexto

Estamos na versão 2.6.0.beta 1.

Os usuários estavam recebendo mensagens sobre conteúdo não seguro. Após investigação, o Chrome parecia estar reclamando de imagens vinculadas a sites HTTP. Portanto, configurei o Discourse para baixar todas as imagens/mídias e servi-las via HTTPS.

Assim que alterei a configuração, isso significou realizar um reprocessamento das postagens históricas. Desde esse reprocessamento, uma grande parte dos vídeos do YouTube que antes eram exibidos como oneboxes agora voltou a aparecer como URLs vinculadas.

Temos um tópico com 10.000 postagens que consiste exclusivamente em respostas com vídeos do YouTube, e todas as postagens são URLs e não oneboxes.

Durante o reprocessamento, todas as tarefas em fila foram processadas organicamente, então não se trata de tarefas presas em uma fila de tarefas excluídas.

Não vi as mesmas mensagens de erro que @marcozambi descreveu, mas acredito que também estamos atingindo um limite de taxa.

O que tentei?

Em apoio à teoria do limite de taxa, um pequeno trecho de código que escrevi para reprocessar postagens funcionou (onebox) para os primeiros 80+ vídeos do YouTube em um tópico e depois falhou ao converter os vídeos restantes.

Nesse ponto, mesmo editando a postagem, fazendo uma pequena alteração e salvando novamente, não foi possível forçar a expansão do URL como onebox. Ao mesmo tempo, todas as filas estavam vazias ou tinham tarefas mínimas sendo processadas instantaneamente, como eu esperava.

Tentativas de reexecutar esse código ao longo de 30 minutos não conseguiram forçar a conversão dos links em oneboxes. Não acho que 80 seja um número mágico aqui, apenas o que estava disponível dentro da cota que tínhamos.

@marcozambi mencionou que o formato de link do YouTube /embed/ funcionou quando outros falharam, então ajustei o código para usar uma substituição por regex nos links do YouTube para convertê-los para o formato /embed/.

O código funcionou.

Reexecutar o código apenas para reprocessar as postagens novamente não conseguiu convertê-las em representações de onebox.

Meu plano é experimentar uma tarefa que converta todos os links do YouTube no grande tópico para o formato /embed/ do YouTube. Se isso falhar ou atingirmos um limite de taxa mais alto, então darei uma olhada no Onebox Assistant de @merefield.

Vou postar uma atualização mais tarde.

OK, definitivamente algo estranho está acontecendo e parece estar relacionado a limites de taxa.

Não tenho certeza se estamos sendo limitados por taxa porque fiz um rebake massivo e fomos para o canto da punição, ou se estamos atingindo limites que outros também encontrarão.

O oneboxing de vídeos do YouTube parece ter um limite e, uma vez atingido, o oneboxing falha silenciosamente.

Acho que isso precisa ser alterado por motivos, espero, óbvios, mas especificamente para qualquer pessoa que faça uma migração ou rebake e não terá ideia de que muitos Oneboxes não expandidos ou que já foram expandidos agora são apenas URLs normais.

@marcozambi mencionou acima que o formato de URL do YouTube que inclui /embed/ antes do ID do vídeo funciona quando os outros formatos estão falhando (presumivelmente devido a um problema de limite de taxa).

Aqui está um vídeo que ilustra bem esse fenômeno.

Quando este screencast foi capturado, não havia jobs entupindo as filas e o fórum estava, de resto, funcionando bem.

Antes deste vídeo, os links do YouTube já haviam começado a falhar na expansão pelo OneBox.

O que você verá é a janela de composição onde o Onebox falha ao expandir um link do YouTube no formato https://youtu.be/<video-id>.

Em seguida, mudo o formato para https://youtube.com/embed/<video-id> e o Onebox o expande.

Então tento novamente com o formato original e ele falha.

Durante a captura deste vídeo, monitorei as abas de console do navegador e de rede. Reconheço que o problema está certamente entre nosso servidor e o YouTube, e não entre meu navegador e nosso servidor, mas os incluo abaixo caso sejam úteis.

(peço desculpas pela imagem com zoom reduzido - espero que fiquem visíveis quando ampliadas)

E aqui está o rastreamento de rede quando o Onebox funcionou.

Não estou convencido de que o formato de link /embed/ seja uma panaceia aqui.

Acho que parece ser uma rota que possui limites de taxa separados, de modo que, quando a rota https://youtu.be/<video-id> atinge um limite, há outra rota com um limite separado na rota https://youtube.com/embed/<video-id>.

A evidência de que ambas as rotas são limitadas vem de uma utilidade que escrevi para alterar o formato dos embeds do YouTube em um thread de postagem monstruoso com 10 mil postagens, onde 99% das respostas eram vídeos do YouTube.

Neste estágio, o Onebox já estava falhando ao expandir os links no formato https://youtu.be/<video-id>.

Minha utilidade, que alterava a URL do vídeo do YouTube para o formato https://youtube.com/embed/<video-id>, foi executada nas primeiras 3000 postagens do thread.

Funcionou bem para as primeiras 1108 postagens e, em seguida, embora tenha alterado o formato para as próximas ~1900 postagens, elas não foram expandidas pelo Onebox.

Durante esse período, muitos jobs foram gerados (meu código usava post.revise) e todos foram processados sem erros ou retentativas.

Anedoticamente, notei que o processamento dos jobs parecia acelerar dramaticamente em certo estágio. Acredito que isso possa ter ocorrido porque o código do Onebox estava recebendo rapidamente algum tipo de erro do YouTube, mas não fiz medições de tempo e poderia ter sido várias outras coisas.

Ficarei feliz em tentar fornecer evidências mais detalhadas aqui, mas não tenho certeza do que posso fazer sem instrumentar o gem do Onebox.

Sou um hacker e não um especialista em Ruby, mas estaria disposto a seguir algumas instruções de alto nível.

Executar alguns scripts curl repetitivos e curtos na linha de comando do servidor com o mesmo user-agent pode ajudá-lo a isolar um problema de limite de taxa.

Concordo que a solução alternativa provavelmente funciona apenas porque se trata de uma contagem separada.

Aqui estão mais alguns resultados. Note que há muitas suposições no post abaixo, baseadas na falta de conhecimento real.

Vou seguir este post com minha opinião sobre o que está acontecendo e o que deveria acontecer.

Obrigado pela resposta, Robert.

Note que a Oneboxing de vídeos usando a rota /watch estava (e ainda está!) falhando quando tentei isso, então não precisei de um loop para forçar a falha.

Então, uma suposição que fiz é que o user-agent que o Onebox está usando é Discourse Forum Onebox v2.6.0.beta1, baseado neste código…

Escolhi um vídeo aleatório e tentei usar curl para ler os cabeçalhos.

Fiz isso dentro do contêiner Docker do meu site ao vivo, o que produziu a seguinte resposta.

Resultado do primeiro curl usando a rota /watch?

comando

curl --user-agent "Discourse Forum Onebox v2.6.0.beta1" -sD - -o /dev/null "https://m.youtube.com/watch?v=s0ONj4TG0UA"

resposta:

curl --user-agent "Discourse Forum Onebox v2.6.0.beta1" -sD - -o /dev/null "https://m.youtube.com/watch?v=s0ONj4TG0UA"
HTTP/2 303 
content-length: 0
p3p: CP="This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl=en-GB for more info."
cache-control: no-cache
x-frame-options: SAMEORIGIN
content-type: text/html; charset=utf-8
location: https://www.youtube.com/watch?v=s0ONj4TG0UA&app=desktop
accept-ch-lifetime: 2592000
x-content-type-options: nosniff
accept-ch: DPR
expires: Tue, 27 Apr 1971 19:44:06 GMT
strict-transport-security: max-age=31536000
date: Fri, 07 Aug 2020 11:35:21 GMT
server: YouTube Frontend Proxy
x-xss-protection: 0
set-cookie: VISITOR_INFO1_LIVE=rcVTSJn81Ck; path=/; domain=.youtube.com; secure; expires=Wed, 03-Feb-2021 11:35:20 GMT; httponly; samesite=None
set-cookie: YSC=cFXIPerzT3Y; path=/; domain=.youtube.com; secure; httponly; samesite=None
set-cookie: GPS=1; path=/; domain=.youtube.com; expires=Fri, 07-Aug-2020 12:05:20 GMT
alt-svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"

Então fui redirecionado usando uma resposta 303 para a URL no cabeçalho location, que era https://www.youtube.com/watch?v=s0ONj4TG0UA&app=desktop.

Isso simplesmente teve o efeito de adicionar &app=desktop à URL.

Resultado do segundo curl para a URL redirecionada - ainda na rota /watch?

comando
curl --user-agent "Discourse Forum Onebox v2.6.0.beta1" -sD - -o /dev/null "https://www.youtube.com/watch?v=s0ONj4TG0UA&app=desktop"

resposta

HTTP/2 429 
x-content-type-options: nosniff
expires: Tue, 27 Apr 1971 19:44:06 GMT
x-frame-options: SAMEORIGIN
cache-control: no-cache
p3p: CP="This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl=en-GB for more info."
accept-ch-lifetime: 2592000
content-type: text/html; charset=utf-8
accept-ch: DPR
strict-transport-security: max-age=31536000
content-length: 48982
date: Fri, 07 Aug 2020 11:46:00 GMT
server: YouTube Frontend Proxy
x-xss-protection: 0
set-cookie: VISITOR_INFO1_LIVE=VQwNuouhq-s; path=/; domain=.youtube.com; secure; expires=Wed, 03-Feb-2021 11:46:00 GMT; httponly; samesite=None
set-cookie: YSC=8IRfPRFRY6c; path=/; domain=.youtube.com; secure; httponly; samesite=None
set-cookie: GPS=1; path=/; domain=.youtube.com; expires=Fri, 07-Aug-2020 12:16:00 GMT
set-cookie: VISITOR_INFO1_LIVE=VQwNuouhq-s; path=/; domain=.youtube.com; secure; expires=Wed, 03-Feb-2021 11:46:00 GMT; httponly; samesite=None
set-cookie: YSC=8IRfPRFRY6c; path=/; domain=.youtube.com; secure; httponly; samesite=None
set-cookie: GPS=1; path=/; domain=.youtube.com; expires=Fri, 07-Aug-2020 12:16:00 GMT
alt-svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"

Então estou recebendo um código de resposta 429 “muitas solicitações”, mas sem receber um cabeçalho retry-after — pare e desista, sem negociação.

De qualquer forma, se é isso que o Onebox está vendo, ele está ignorando a resposta ou, pelo menos, não sei onde procurar se estiver sendo registrado.

Embora isso possa ser algo legítimo a fazer para um único 429, ver muitas respostas 429 em um período muito curto de tempo não pode ser ignorado.

Resultado do terceiro curl - desta vez usando a rota /embed/

Para completar, tentei imediatamente obter o mesmo vídeo, mas desta vez usando a rota /embed/.

comando

curl --user-agent "Discourse Forum Onebox v2.6.0.beta1" -sD - -o /dev/null "https://www.youtube.com/embed/s0ONj4TG0UA"

resposta

HTTP/2 200 
accept-ch-lifetime: 2592000
content-type: text/html; charset=utf-8
expires: Tue, 27 Apr 1971 19:44:06 GMT
x-content-type-options: nosniff
cache-control: no-cache
p3p: CP="This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl=en-GB for more info."
strict-transport-security: max-age=31536000
accept-ch: DPR
date: Fri, 07 Aug 2020 11:55:29 GMT
server: YouTube Frontend Proxy
x-xss-protection: 0
set-cookie: VISITOR_INFO1_LIVE=PNE6x6djF00; path=/; domain=.youtube.com; secure; expires=Wed, 03-Feb-2021 11:55:29 GMT; httponly; samesite=None
set-cookie: VISITOR_INFO1_LIVE=PNE6x6djF00; path=/; domain=.youtube.com; secure; expires=Wed, 03-Feb-2021 11:55:29 GMT; httponly; samesite=None
set-cookie: GPS=1; path=/; domain=.youtube.com; expires=Fri, 07-Aug-2020 12:25:29 GMT
set-cookie: YSC=pDW-hdbauK8; path=/; domain=.youtube.com; secure; httponly; samesite=None
alt-svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
accept-ranges: none
vary: Accept-Encoding

200 - Sucesso.

O plugin lazy-yt parece reescrever URLs no formato /watch

Não tenho certeza se isso é de alguma importância, mas… o plugin embutido lazy-yt está habilitado por padrão? Notei isso na minha instalação de desenvolvimento.

Parece que ele faz um monkey patch no método to_html do YouTube Oneboxer.

Não sei se é significativo, mas o método to_html do Onebox original retorna o formato de URL /embed/

Enquanto o plugin lazy-yt usa o formato de URL /watch?v=.

Há mais alguma coisa que eu possa fazer para mostrar que há um problema que precisa de alguma forma de atenção? O próximo post explicará o que acho ser a causa raiz.