Cargar el texto de un tweet

nV8x

Creo que somos bastantes los foreros que de una u otra manera tenemos bloqueado el cargar el contenido embebido de sitios de terceros como Twitter, Instagram, etc., principalmente para bloquear sus rastreadores y para que no sigan nuestra actividad de lo que estemos haciendo aquí.

En cuanto a twitter, me he dado cuenta que en según qué sitios web, aunque tenga bloqueado que cargue twitter, sí puedo ver el texto de los tweets. Ejemplo:


https://www.hollywoodreporter.com/news/general-news/jack-dorsey-satoshi-shirt-super-bowl-1235822589/

Por lo que entiendo que técnicamente sí es factible hacer un fallback mostrando solo el texto si se detecta que ha fallado cargar los scripts de Twitter.

Se podría implementar algo parecido?

Saludos

4
B
#1nV8x:

principalmente para bloquear sus rastreadores y para que no sigan nuestra actividad de lo que estemos haciendo aquí.

¿De qué tenéis miedo? ¿Tan malo es lo que hacéis aquí? Ya tengo curiosidad.

1 3 respuestas
nV8x

#2 miedo ninguno, no soy un Snowden. Simplemente no veo correcto la normalización de que las redes sociales te sigan cual psicópata estes donde estes en Internet solo porque ese sea su modelo de negocio.

1
r2d2rigo

Yo apoyo la mocion, pero porque por alguna extra;a razon los embeds de mediavida me suelen colgar el navegador de vez en cuando (edge en android).

6 1 respuesta
LR

#4 mismo caso por aquí, cuando pilla muchos embeds se hace la picha un lío y se queda bloqueado, en mi caso con Chrome en android

2
Hades13

Día 382829 pidiendo que arreglen los inserts de Reddit también.

O que al menos me deje hacer click ahí y verlo en Reddit como hago cuando no quiero esperar a que carguen los tweets.

2 2 respuestas
Mystee

#6 Y mis dineros de copyright?

2
montaN1

#2 no digas esa manida frase donde haya gente con dos dedos de frente escuchando

1
robolution

#6 Y que arreglen tambien los inserts cuando el enlace de reddit es el recortado de la app oficial, que el media no los pilla

ejemplo:
[media]https://www.reddit.com/r/formula1/s/XKtaNaXMhl[/media]

2 respuestas
Hades13

#9 Pasa lo mismo con TikTok.
Hay que pegar el enlace que te da la app en el navegador y copiar ese nuevo enlace.

Que haya que estar haciendo malabares en una web en la que posiblemente el uso de la versión móvil ronde el 50% le quita las ganas a cualquiera de querer compartir cosas.

Incluso debería reconocer ya ciertos enlaces y poner el \media\ MV sin que tenga que ponerlo el user.
Debería ser el user que NO quiera insertar (que es un porcentaje ínfimo) el que debería tener que poner algo.

Mystee

#9

A mi si que me deja xD

2 respuestas
robolution

#11 No se, a mi la app de android de reddit me da los enlaces en formato corto y esos no los reconoce mv

2 respuestas
Mystee

#12 Con que media lo pones? porque igual con eso cambia xD

2 respuestas
robolution

#13 No deberia de cambiar porque solo hay un media, quiero decir, esta duplicado a la hora de escribir un mensaje supongo que para que quede claro que se puede usar en video y en otras plataformas

SpiuK

Que venga otra vez el que tiraba el server a base de hacer DDOS por que MV no tiene cloudflare habilitado. Asi reinician el server y vuelve a funcionar todo como la otra vez.

sacnoth

#13

https://www.reddit.com/r/formula1/comments/1dyztfj/what_keeps_charles_at_ferrari/?share_id=VqBSF5UvfTh34ENWP5M4n

Este es su media, no sé si habrá forma de conseguirlo en android como dice él.

1 respuesta
tute07011988

Aprovecho, que nunca es mala ocasión, para pedirle a la gente que deje de insertar videos con reproductores que no permiten graduar el volumen o ver la barra de tiempo.

Gracias. Un saludo.

3
Hades13

#11 Obviamente no veo el insert.

#12 #16

El enlace que me da la app:
https://www.reddit.com/r/formula1/s/fms5ZXTTlw

El enlace que me da Safari:
https://www.reddit.com/r/formula1/comments/1dyztfj/what_keeps_charles_at_ferrari/?share_id=jurgz_5qHSXQeP7rqfdEz&utm_content=1&utm_medium=ios_app&utm_name=ioscss&utm_source=share&utm_term=1

El primero no inserta, el segundo sí.
Cuando quiero compartir algo tengo que pegar el enlace corto en Safari y copiar el nuevo enlace para MV.
Lo mismo para TikTok.

De todas formas, para mí debería ser más prioritario que se vieran y tal xd

1
Sust0

Yo me hice una aplicación para los tweets que no tienen video para subir una captura automáticamente a un host de imágenes y te ponga en el portapapeles el código de la web.

1 respuesta
nV8x

#19 la tienes en github?

1 respuesta
Sust0

#20 Quiero ponerle que puedas meter varios tweets y que también puedas elegir coger una screen del portapapeles. De momento la tengo yo porque estaba usando la api de imgur que pide usuario y usaba el mío, pero encontré un hosting para poder subir anónimo bastante decente. Tenía pensado terminarla y ponerle interfaz para ponerla en el foro, a ver si pillo un rato esta semana y la termino.

1
neZbo

El problema creo que está en que el script que se encarga de sacar los datos del tweet en base al tweet id (https://platform.twitter.com/widgets.js) aparte de hacer eso, es el que se encarga de hacer tracking, por lo que es detectado como malicioso y se bloquea, no cargando dinámicamente el contenido del tweet.

Cuando parece que funciona a medias en otras webs como las que menciona #1 seguramente sea porque han usado la funcionalidad de embed tweet, que te proporciona un código html que contiene parte del tweet en cuestión, aparte del script:


Igual me equivoco, pero me da a mí que por ahí van los tiros. No sé si hay alguna forma sencilla de sacar datos del tweet sin usar el script de twitter.

1
MacCulkin

#2 cuando cagas, ¿estás haciendo algo malo? Si no es el caso, ¿por qué cierras la puerta?

3
shortyStyle

Lo de los Tweets y los Reddit embebidos es lo que más jode la experiencia de uso de la web con diferencia.

1 respuesta
HeXaN

#24 En Firefox es de locos lo que tardan en cargar.

3 1 respuesta
shortyStyle

#25 Ni que lo digas, soy usuario de Firefox y es horrible, yo en muchas ocasiones, por no esperar, haco click en el link/texto "Cargando tuit..." que te abre el tweet en otra pestaña y así voy más rápido, imagínate.

Con Safari en el móvil también lo sufro mucho, el otro día se me ocurrió abrir el hilo Multimedia de la invasión de Ucrania, y me petó el Safari gustosamente cada vez que intentaba abrir la web, y no tengo un móvil antiguo precisamente, me pasó con 15 Pro Max.

1
Sust0

Pues anoche me puse un rato y poco a poco voy dándole funcionalidad.

Este sería el resultado de lo que se pondría en el foro.



Está bastante bien tanto si vas a poner un tweet o para echar screenshots rápidas, aunque para esto último seguro que hay buenas extensiones en los navegadores.

2
neZbo

He creado un pequeño script para Tamper Monkey que hace más o menos lo que pide #1 sacando el texto del tweet:

// ==UserScript==
// @name         MV Twitter Fix
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Probando fix para tweets embedidos con anti tracking
// @author       neZbo
// @match        https://www.mediavida.com/foro/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=mediavida.com
// @grant        GM_xmlhttpRequest
// @connect      nitter.lucabased.xyz
// ==/UserScript==

(async function() {
    'use strict'

const nitterInstance = 'https://nitter.lucabased.xyz' // Nitter instances: https://github.com/zedeus/nitter/wiki/Instances

const makeCorsRequest = async (url) => {
    return new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function(response) {
                if (response.status >= 200 && response.status < 300) {
                    resolve(response.responseText)
                } else {
                    reject('Request failed with status: ' + response.status)
                }
            },
            onerror: function(error) {
                reject('Request failed: ' + error)
            }
        })
    })
}

const fetchTweetContent = async (tweetId) => {
        const text = await makeCorsRequest(nitterInstance + '/user/status/' + tweetId)
        const parser = new DOMParser()
        const doc = parser.parseFromString(text, 'text/html')
        const tweetContent = doc.querySelector('div.tweet-content.media-body')
        return tweetContent ? tweetContent.innerHTML : 'Tweet content not found'
}

const tweeterFix = async () => {
    const tweets = document.querySelectorAll('div[data-s9e-mediaembed="twitter"]')
    tweets.forEach(async tweet => {
        const iframe = tweet.querySelector('iframe')
        if (iframe) {
            const tweetId = iframe.src.split('#')[1]
            tweet.innerHTML = ''
            const tweetText = await fetchTweetContent(tweetId)
            const tweetLink = 'https://x.com/user/status/' + tweetId
            tweet.innerHTML ='<blockquote class="twitter-tweet" onclick="window.open(\''+tweetLink+'\', \'_blank\');return false;"><img src="https://cdn-icons-png.freepik.com/256/13480/13480324.png" style="display:inline; width:30px; margin-right: 10px"/><p style="display:inline; color: #111;font: normal 13px Verdana, Geneva, sans-serif;text-decoration: none">'+tweetText+'</p></blockquote>'
        }
    })
}

await tweeterFix()

const twitter_observer = new MutationObserver(async mutationRecords => {
    await tweeterFix()
})

if (document.querySelector("#foros")) twitter_observer.observe(document.querySelector("#foros"), { subtree: true, childList: true })

})()

Limitaciones:

  • No carga ni imágenes ni cadenas de tweets, sólo el texto del tweet en sí.
  • Depende de una instancia de nitter, de momento usa https://nitter.lucabased.xyz Si la chapan o la capan puede dejar de funcionar, aunque se puede mirar de configurar otra instancia de nitter.

Así se vería sin el script:

Así con el script activado:

5
neZbo

He modificado el script para que muestre el usuario y la primera imagen si el tweet tiene imágenes:

// ==UserScript==
// @name         MV Twitter Fix
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Probando fix para tweets embedidos con anti tracking
// @author       neZbo
// @match        https://www.mediavida.com/foro/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=mediavida.com
// @grant        GM_xmlhttpRequest
// @connect      nitter.lucabased.xyz
// ==/UserScript==

(async function() {
    'use strict'

const nitterInstance = 'https://nitter.lucabased.xyz' // Nitter instances: https://github.com/zedeus/nitter/wiki/Instances

const makeCorsRequest = async (url, blob = false) => {
    return new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            responseType: blob ? 'blob' : 'text',
            onload: function(response) {
                if (response.status >= 200 && response.status < 300) {
                    if (blob) resolve(response.response)
                    else resolve(response.responseText)
                } else {
                    reject('Request failed with status: ' + response.status)
                }
            },
            onerror: function(error) {
                reject('Request failed: ' + error)
            }
        })
    })
}

const fetchTweetContent = async (tweetId) => {
        const text = await makeCorsRequest(nitterInstance + '/user/status/' + tweetId)
        const parser = new DOMParser()
        const doc = parser.parseFromString(text, 'text/html')
        const tweetContent = doc.querySelector('div.main-thread')
        const tweetText = tweetContent.querySelector('div.tweet-content.media-body')
        const tweetHeader = tweetContent.querySelector('div.fullname-and-username a.username')
        const tweetImage = tweetContent.querySelector('div.attachments img')
        let allContent = tweetHeader.outerHTML + '<hr style="margin:5px"/>' + tweetText.innerHTML
        if (tweetImage) {
            tweetImage.src = tweetImage.src.replace("https://www.mediavida.com", nitterInstance)
            const localImage = await makeCorsRequest(tweetImage.src, true)
            const localUrl = URL.createObjectURL(localImage);
            tweetImage.src = localUrl
            tweetImage.style = 'width:450px;height:auto;margin:auto;display:block;border-radius:10px;'
            allContent += '<hr style="margin:5px"/>' + tweetImage.outerHTML
        }
        return allContent ? allContent : 'Tweet content not found'
}

const twitterFix = async () => {
    const tweets = document.querySelectorAll('div[data-s9e-mediaembed="twitter"]')
    tweets.forEach(async tweet => {
        const iframe = tweet.querySelector('iframe')
        if (iframe) {
            const tweetId = iframe.src.split('#')[1]
            tweet.innerHTML = ''
            const tweetText = await fetchTweetContent(tweetId)
            const tweetLink = 'https://x.com/user/status/' + tweetId
            tweet.innerHTML ='<blockquote class="twitter-tweet" onclick="window.open(\''+tweetLink+'\', \'_blank\');return false;"><img src="https://cdn-icons-png.freepik.com/256/13480/13480324.png" style="display:inline; width:30px; margin-right: 10px"/><p style="display:inline; color: #111;font: normal 13px Verdana, Geneva, sans-serif;text-decoration: none">'+tweetText+'</p></blockquote>'
        }
    })
}

await twitterFix()

const twitter_observer = new MutationObserver(async mutationRecords => {
    await twitterFix()
})

if (document.querySelector("#foros")) twitter_observer.observe(document.querySelector("#foros"), { subtree: true, childList: true })

})()

Así se vería ahora:

Sigue haciendo cosas raras a veces cuando se trata de respuestas a otros tweets... Ya le daré una vuelta.

1 1 respuesta
nV8x

#29 Gracias crack.

Aunque no me acaba de funcionar por culpa de que uso Multi-Containers en Firefox. Salta un 404 en la linea const tweetText = await fetchTweetContent(tweetId). Tengo MV en su propio container y el de Twitter en otro. He probado de poner el dominio de la instancia de nitter en el mismo container que MV pero nada, tampoco funciona si lo asigno al de Twitter.

1 respuesta