您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
点击按钮即可将文章 原文 + Telegraph 自动保存到 Telegram 机器人。配置方法看教程。
// ==UserScript== // @name Save to Telegraph // @version 1.001 // @description 点击按钮即可将文章 原文 + Telegraph 自动保存到 Telegram 机器人。配置方法看教程。 // @match *://*/* // @author yzcjd // @author2 ChatGPT4辅助 // @namespace https://greasyfork.org/users/1171320 // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @run-at document-end // @license MIT // ==/UserScript== (function () { 'use strict'; let BOT_TOKEN = GM_getValue("BOT_TOKEN", ""); let CHAT_ID = GM_getValue("CHAT_ID", ""); let TELEGRAPH_TOKEN = GM_getValue("TELEGRAPH_TOKEN", ""); let menuHidden = GM_getValue("MENU_HIDDEN", false); const menuHandles = {}; function registerAllMenus() { for (let key in menuHandles) GM_unregisterMenuCommand(menuHandles[key]); if (!menuHidden) { menuHandles.BOT = GM_registerMenuCommand("设置 Bot Token", () => { const v = prompt("请输入 Bot Token:", BOT_TOKEN); if (v !== null) { BOT_TOKEN = v.trim(); GM_setValue("BOT_TOKEN", BOT_TOKEN); alert("✅ Bot Token 已保存"); } }); menuHandles.CHAT = GM_registerMenuCommand("设置 Chat ID", () => { const v = prompt("请输入 Chat ID:", CHAT_ID); if (v !== null) { CHAT_ID = v.trim(); GM_setValue("CHAT_ID", CHAT_ID); alert("✅ Chat ID 已保存"); } }); menuHandles.TELE = GM_registerMenuCommand("设置 Telegraph Token", () => { const v = prompt("请输入 Telegraph Token:", TELEGRAPH_TOKEN); if (v !== null) { TELEGRAPH_TOKEN = v.trim(); GM_setValue("TELEGRAPH_TOKEN", TELEGRAPH_TOKEN); alert("✅ Telegraph Token 已保存"); } }); menuHandles.TUTOR = GM_registerMenuCommand("使用教程", () => { window.open("https://telegra.ph/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E8%BF%99%E4%B8%AA%E8%84%9A%E6%9C%AC-09-14", "_blank"); }); menuHandles.HIDE = GM_registerMenuCommand("隐藏菜单", () => { menuHidden = true; GM_setValue("MENU_HIDDEN", menuHidden); registerAllMenus(); }); } else { menuHandles.SHOW = GM_registerMenuCommand("显示菜单", () => { menuHidden = false; GM_setValue("MENU_HIDDEN", menuHidden); registerAllMenus(); }); } } registerAllMenus(); const style = document.createElement('style'); style.textContent = ` #save-button { position: fixed; top: 90px; right: 5px; z-index: 99999; background: #f5f5f5; color: #000; padding: 4px 8px; border-radius: 6px; border: 1px solid #ccc; cursor: pointer; font-size: 12px; transform: scale(0.75); transition: all 0.2s; } .btn-click-animate { animation: clickAnim 0.2s ease; } @keyframes clickAnim { 0% { transform: scale(0.75); } 50% { transform: scale(0.9); } 100% { transform: scale(0.8); } } `; document.head.appendChild(style); const btn = document.createElement('button'); btn.id = "save-button"; btn.innerText = "save"; document.body.appendChild(btn); document.documentElement.setAttribute('translate', 'no'); function httpPost(url, data, cb) { GM_xmlhttpRequest({ method: "POST", url: url, headers: { "Content-Type": "application/json" }, data: JSON.stringify(data), onload: res => cb(null, res), onerror: err => cb(err) }); } function extractContent() { const selectors = ['article','.content','#content','.post','.entry-content','.main-content','.article-body','.chapter']; for (let sel of selectors) { const el = document.querySelector(sel); if (el && el.innerText.trim().length>50) return el.innerText.trim(); } return document.body.innerText.trim(); } function extractRealTitle() { const h1 = document.querySelector('h1'); if(h1 && h1.innerText.trim()) return h1.innerText.trim(); const articleH1 = document.querySelector('article h1'); if(articleH1 && articleH1.innerText.trim()) return articleH1.innerText.trim(); const ogTitle = document.querySelector('meta[property="og:title"]'); if(ogTitle && ogTitle.content.trim()) return ogTitle.content.trim(); return document.title.trim() || "未命名"; } const MAX_CHARS = 60000; function splitContent(text) { const segments = []; let start = 0; while(start < text.length){ segments.push(text.slice(start, start + MAX_CHARS)); start += MAX_CHARS; } return segments; } async function createTelegraphPages(segments, titleBase, TELEGRAPH_TOKEN) { const urls = []; for(let i=0;i<segments.length;i++){ const segmentTitle = segments.length>1 ? `${titleBase}(第${i+1}部分)` : titleBase; const contentJson = [{ tag: "p", children: [segments[i]] }]; const res = await new Promise(resolve=>{ httpPost("https://api.telegra.ph/createPage",{ access_token: TELEGRAPH_TOKEN, title: segmentTitle, content: contentJson, author_name: "AutoSave" }, (_, r)=>resolve(JSON.parse(r.responseText))); }); if(res.ok) urls.push(res.result.url); else console.error("❌ Telegraph 创建失败:", res); } return urls; } function formatTelegramMessage(title, originalUrl, telegraphUrls){ const titleLink = `[${title}](${originalUrl})`; // 标题超链接到原文 let archiveLinks = ''; if(telegraphUrls.length===1){ archiveLinks = ` || [存档](${telegraphUrls[0]})`; }else if(telegraphUrls.length>=4){ archiveLinks = ' ' + telegraphUrls.map((u,i)=>`|| [存档${i+1}](${u})`).join(' '); }else{ archiveLinks = ' ' + telegraphUrls.map(u=>`|| [存档](${u})`).join(' '); } return `${titleLink}${archiveLinks}`; } btn.addEventListener('click', async ()=>{ if(!BOT_TOKEN || !CHAT_ID || !TELEGRAPH_TOKEN){ alert("⚠️ 请先通过脚本菜单设置 Bot Token、Chat ID、Telegraph Token!"); return; } btn.classList.add("btn-click-animate"); setTimeout(()=> btn.classList.remove("btn-click-animate"), 200); btn.style.background="#4caf50"; btn.style.color="#fff"; const title = extractRealTitle(); const content = extractContent(); const segments = splitContent(content); const telegraphUrls = await createTelegraphPages(segments, title, TELEGRAPH_TOKEN); const messageText = formatTelegramMessage(title, location.href, telegraphUrls); httpPost(`https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`,{ chat_id: CHAT_ID, text: messageText, parse_mode: "Markdown", disable_web_page_preview: true }, (err,res)=>{ if(!err && res.status===200){ btn.style.background="#4caf50"; btn.style.color="#fff"; }else{ console.error("❌ 发送 Telegram 失败", res?.responseText||err); btn.style.background="#f44336"; btn.style.color="#fff"; } setTimeout(()=>{ btn.style.background="#f5f5f5"; btn.style.color="#000"; },1500); }); }); })();