InscriptionConnexion
ou plutot je le fais faire par chat GPT
:fouet:



en gros je voudrais que les liens twitter poster sur le forum redirige sur exactement le même statut/profil mais sur nitter j'ai mit le script sur tamper monkey mais ça ne marche pas
:Sourire1:




des clés qui s'y connaissent pour me dire ce qui va pas ?
:Sourire1:




le code :


// ==UserScript==
// @name Onche.orgX.com to Nitter (robuste)
// @namespace onche.org
// @version 1.1.0
// @description Sur onche.org uniquement : réécrit tous les liens x.com (y compris via redirections) vers Nitter et intercepte les clics dynamiques
// @author onche.org
// @match *://onche.org/*
// @match *://www.onche.org/*
// @match *://*.onche.org/*
// @icon nitter.net https://nitter.net/favicon.ico
// @grant none
// @run-at document-start
// ==/UserScript==

(() => {
const NITTER_INSTANCE = "nitter.net" https://nitter.net";;

const isXHost = (h) => /(^|\.)x\.com$/i.test(h || "");
const isOncheHost = (h) => /(^|\.)onche\.org$/i.test(h || "");

const normalizeXPath = (p = "") =>
p.replace(/^\/i\/web\/status\//, "/status/").replace(/^\/i\/status\//, "/status/");

const toNitterFromUrl = (u) => {
if (!u) return null;
try {
const host = (u.hostname || "").toLowerCase();
if (!isXHost(host)) return null;
const n = new URL(NITTER_INSTANCE);
n.pathname = normalizeXPath(u.pathname || "/");
n.search = u.search || "";
n.hash = u.hash || "";
return n;
} catch { return null; }
};

const toNitterString = (urlLike, base = location.href) => {
try {
const u = urlLike instanceof URL ? urlLike : new URL(String(urlLike), base);
const n = toNitterFromUrl(u);
return n ? n.toString() : null;
} catch { return null; }
};

// Détecter et réécrire les redirections type /out?url=... etc.
const extractRedirectTarget = (a) => {
try {
const u = new URL(a.href, location.href);
if (!isOncheHost(u.hostname)) return null;
// Cherche un param qui ressemble à une URL cible
const candidates = ["url", "u", "target", "to", "redirect", "r", "dest", "link"];
for (const key of candidates) {
const val = u.searchParams.get(key);
if (val) {
try {
return new URL(val, location.href);
} catch { /* ignore */ }
}
}
// Certains sites encodent l'URL dans le chemin après /out/
const pathMatch = u.pathname.match(/\/(out|redirect)\/(.+)$/i);
if (pathMatch && pathMatch[2]) {
const decoded = decodeURIComponent(pathMatch[2]);
try { return new URL(decoded, location.href); } catch {}
}
} catch {}
return null;
};

const rewriteAnchor = (a) => {
if (!a || !a.href) return;

// 1) lien direct vers x.com
const direct = toNitterString(a.href);
if (direct) {
a.href = direct;
try { a.relList?.add("noopener", "noreferrer"); } catch {}
if (!a.target) a.target = "_blank";
a.dataset.nitterRewritten = "1";
return;
}

// 2) lien onche.org qui redirige vers une URL externe (paramètre ?url=... etc.)
const targetUrl = extractRedirectTarget(a);
if (targetUrl) {
const nitterUrl = toNitterFromUrl(targetUrl);
if (nitterUrl) {
// Met à jour le paramètre de redirection SI tu veux garder la redirection
try {
const u = new URL(a.href, location.href);
const candidates = ["url", "u", "target", "to", "redirect", "r", "dest", "link"];
let replaced = false;
for (const key of candidates) {
if (u.searchParams.has(key)) {
u.searchParams.set(key, nitterUrl.toString());
replaced = true;
}
}
// OU : pointer directement vers Nitter (plus simple, sans passer par /out)
a.href = nitterUrl.toString();
a.relList?.add("noopener", "noreferrer");
if (!a.target) a.target = "_blank";
a.dataset.nitterRewritten = "1";
return;
} catch {}
}
}

// 3) Attributs de données courants
for (const attr of ["data-href", "data-url"]) {
const v = a.getAttribute(attr);
const n = toNitterString(v);
if (n) {
a.setAttribute(attr, n);
if (!a.href || isOncheHost(new URL(a.href, location.href).hostname)) {
a.href = n;
}
a.dataset.nitterRewritten = "1";
return;
}
}
};

const scan = (root = document) => {
try {
const anchors = root.querySelectorAll('a[href]:not([data-nitter-rewritten])');
anchors.forEach(rewriteAnchor);
} catch {}
};

// Intercepter les clics qui passeraient par des handlers JS
window.addEventListener("click", (ev) => {
const path = ev.composedPath ? ev.composedPath() : null;
const node = (path && path.find((n) => n && n.tagName === "A")) || ev.target.closest?.("a");
if (!node) return;
const a = node;
// Résoudre la destination finale si possible
const candidate =
toNitterString(a.href) ||
toNitterString(a.getAttribute?.("data-href")) ||
toNitterString(a.getAttribute?.("data-url"));

if (candidate) {
// Empêche une éventuelle redirection intermédiaire vers x.com
ev.preventDefault();
ev.stopPropagation();
window.open(candidate, "_blank", "noopener,noreferrer");
}
}, true); // capture

// Lancer scan au bon moment
const ready = () => scan();
if (document.readyState === "interactive" || document.readyState === "complete") ready();
else document.addEventListener("DOMContentLoaded", ready, { once: true });

// Observer le contenu dynamique
const mo = new MutationObserver((mut) => {
for (const m of mut) {
m.addedNodes.forEach((node) => {
if (node.nodeType !== 1) return;
if (node.tagName === "A") rewriteAnchor(node);
else scan(node);
});
if (m.type === "attributes" && m.target?.tagName === "A" && m.attributeName === "href") {
rewriteAnchor(m.target);
}
}
});

try {
mo.observe(document.documentElement, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["href"]
});
} catch {}
})();
il y a un mois
up
il y a un mois
j'arrive même pas à comprendre ce que tu veux faire, que chaque lien posté affiche en fait une même page de profil twitter ?
il y a un mois
Rien compris a ce que tu veux fair
il y a un mois
j'arrive même pas à comprendre ce que tu veux faire, que chaque lien posté affiche en fait une même page de profil twitter ?
en gros tu clique sur un lien twitter sur le forum ça te redirige sur exactement le même post mais sur nitter comme ça pas besoin de compte twitter pour lire les commentaire
il y a un mois
up
il y a un mois
ou plutot je le fais faire par chat GPT
:fouet:



en gros je voudrais que les liens twitter poster sur le forum redirige sur exactement le même statut/profil mais sur nitter j'ai mit le script sur tamper monkey mais ça ne marche pas
:Sourire1:




des clés qui s'y connaissent pour me dire ce qui va pas ?
:Sourire1:




le code :


// ==UserScript==
// @name Onche.orgX.com to Nitter (robuste)
// @namespace onche.org
// @version 1.1.0
// @description Sur onche.org uniquement : réécrit tous les liens x.com (y compris via redirections) vers Nitter et intercepte les clics dynamiques
// @author onche.org
// @match *://onche.org/*
// @match *://www.onche.org/*
// @match *://*.onche.org/*
// @icon nitter.net https://nitter.net/favicon.ico
// @grant none
// @run-at document-start
// ==/UserScript==

(() => {
const NITTER_INSTANCE = "nitter.net" https://nitter.net";;

const isXHost = (h) => /(^|\.)x\.com$/i.test(h || "");
const isOncheHost = (h) => /(^|\.)onche\.org$/i.test(h || "");

const normalizeXPath = (p = "") =>
p.replace(/^\/i\/web\/status\//, "/status/").replace(/^\/i\/status\//, "/status/");

const toNitterFromUrl = (u) => {
if (!u) return null;
try {
const host = (u.hostname || "").toLowerCase();
if (!isXHost(host)) return null;
const n = new URL(NITTER_INSTANCE);
n.pathname = normalizeXPath(u.pathname || "/");
n.search = u.search || "";
n.hash = u.hash || "";
return n;
} catch { return null; }
};

const toNitterString = (urlLike, base = location.href) => {
try {
const u = urlLike instanceof URL ? urlLike : new URL(String(urlLike), base);
const n = toNitterFromUrl(u);
return n ? n.toString() : null;
} catch { return null; }
};

// Détecter et réécrire les redirections type /out?url=... etc.
const extractRedirectTarget = (a) => {
try {
const u = new URL(a.href, location.href);
if (!isOncheHost(u.hostname)) return null;
// Cherche un param qui ressemble à une URL cible
const candidates = ["url", "u", "target", "to", "redirect", "r", "dest", "link"];
for (const key of candidates) {
const val = u.searchParams.get(key);
if (val) {
try {
return new URL(val, location.href);
} catch { /* ignore */ }
}
}
// Certains sites encodent l'URL dans le chemin après /out/
const pathMatch = u.pathname.match(/\/(out|redirect)\/(.+)$/i);
if (pathMatch && pathMatch[2]) {
const decoded = decodeURIComponent(pathMatch[2]);
try { return new URL(decoded, location.href); } catch {}
}
} catch {}
return null;
};

const rewriteAnchor = (a) => {
if (!a || !a.href) return;

// 1) lien direct vers x.com
const direct = toNitterString(a.href);
if (direct) {
a.href = direct;
try { a.relList?.add("noopener", "noreferrer"); } catch {}
if (!a.target) a.target = "_blank";
a.dataset.nitterRewritten = "1";
return;
}

// 2) lien onche.org qui redirige vers une URL externe (paramètre ?url=... etc.)
const targetUrl = extractRedirectTarget(a);
if (targetUrl) {
const nitterUrl = toNitterFromUrl(targetUrl);
if (nitterUrl) {
// Met à jour le paramètre de redirection SI tu veux garder la redirection
try {
const u = new URL(a.href, location.href);
const candidates = ["url", "u", "target", "to", "redirect", "r", "dest", "link"];
let replaced = false;
for (const key of candidates) {
if (u.searchParams.has(key)) {
u.searchParams.set(key, nitterUrl.toString());
replaced = true;
}
}
// OU : pointer directement vers Nitter (plus simple, sans passer par /out)
a.href = nitterUrl.toString();
a.relList?.add("noopener", "noreferrer");
if (!a.target) a.target = "_blank";
a.dataset.nitterRewritten = "1";
return;
} catch {}
}
}

// 3) Attributs de données courants
for (const attr of ["data-href", "data-url"]) {
const v = a.getAttribute(attr);
const n = toNitterString(v);
if (n) {
a.setAttribute(attr, n);
if (!a.href || isOncheHost(new URL(a.href, location.href).hostname)) {
a.href = n;
}
a.dataset.nitterRewritten = "1";
return;
}
}
};

const scan = (root = document) => {
try {
const anchors = root.querySelectorAll('a[href]:not([data-nitter-rewritten])');
anchors.forEach(rewriteAnchor);
} catch {}
};

// Intercepter les clics qui passeraient par des handlers JS
window.addEventListener("click", (ev) => {
const path = ev.composedPath ? ev.composedPath() : null;
const node = (path && path.find((n) => n && n.tagName === "A")) || ev.target.closest?.("a");
if (!node) return;
const a = node;
// Résoudre la destination finale si possible
const candidate =
toNitterString(a.href) ||
toNitterString(a.getAttribute?.("data-href")) ||
toNitterString(a.getAttribute?.("data-url"));

if (candidate) {
// Empêche une éventuelle redirection intermédiaire vers x.com
ev.preventDefault();
ev.stopPropagation();
window.open(candidate, "_blank", "noopener,noreferrer");
}
}, true); // capture

// Lancer scan au bon moment
const ready = () => scan();
if (document.readyState === "interactive" || document.readyState === "complete") ready();
else document.addEventListener("DOMContentLoaded", ready, { once: true });

// Observer le contenu dynamique
const mo = new MutationObserver((mut) => {
for (const m of mut) {
m.addedNodes.forEach((node) => {
if (node.nodeType !== 1) return;
if (node.tagName === "A") rewriteAnchor(node);
else scan(node);
});
if (m.type === "attributes" && m.target?.tagName === "A" && m.attributeName === "href") {
rewriteAnchor(m.target);
}
}
});

try {
mo.observe(document.documentElement, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["href"]
});
} catch {}
})();
Tiens j'en ai fais un similaire (merci Claude), il semble fonctionner correctement sur PC et sur mobile. Il redirige vers xcancel
:miko_think3:


pastes.dev https://pastes.dev/GYIWsANHSc
il y a 6 heures
Tiens j'en ai fais un similaire (merci Claude), il semble fonctionner correctement sur PC et sur mobile. Il redirige vers xcancel
:miko_think3:


pastes.dev https://pastes.dev/GYIWsANHSc
Je me disais bien
:mein_kampf:
il y a 6 heures
Je me disais bien
:mein_kampf:
Tu me connais bien aussi
:miko_think3:
il y a 6 heures
Tu me connais bien aussi
:miko_think3:
Je veux dire que je me doutais que ça avait quelque chose a voir avec toi :3
Le timing étais trop parfait sinon
:yotsuya_marlou:
il y a 5 heures
Je veux dire que je me doutais que ça avait quelque chose a voir avec toi :3
Le timing étais trop parfait sinon
:yotsuya_marlou:
Ah je vois, en effet j'avais vu le topic de l'OP il y a quelques jours en cherchant des idées de scripts. Et toi en plus qui me dis que ce serait pratique j'étais obligé
:miko_think3:
il y a 5 heures