为每个Twitter推文添加推送到Telegram机器人的按钮
// ==UserScript==
// @name Twitter send to Telegram
// @namespace http://tampermonkey.net/
// @version 1.1
// @description 为每个Twitter推文添加推送到Telegram机器人的按钮
// @author zy668
// @match https://twitter.com/*
// @match https://x.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @run-at document-start
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 配置区域 - 请在这里设置你的Telegram Bot信息
let TELEGRAM_BOT_TOKEN = GM_getValue('telegram_bot_token', '');
let TELEGRAM_CHAT_ID = GM_getValue('telegram_chat_id', '');
// 如果未设置Bot信息,提示用户设置
function checkBotConfig() {
if (!TELEGRAM_BOT_TOKEN || !TELEGRAM_CHAT_ID) {
const token = prompt('请输入Telegram Bot Token:');
const chatId = prompt('请输入Telegram Chat ID:');
if (token && chatId) {
TELEGRAM_BOT_TOKEN = token;
TELEGRAM_CHAT_ID = chatId;
GM_setValue('telegram_bot_token', token);
GM_setValue('telegram_chat_id', chatId);
} else {
alert('需要设置Bot Token和Chat ID才能使用推送功能');
return false;
}
}
return true;
}
// 发送消息到Telegram
function sendToTelegram(message) {
if (!checkBotConfig()) return;
const url = `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`;
GM_xmlhttpRequest({
method: 'POST',
url: url,
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
chat_id: TELEGRAM_CHAT_ID,
text: message,
parse_mode: 'HTML'
}),
onload: function(response) {
if (response.status === 200) {
console.log('推送成功');
// 可以添加成功提示
showNotification('推送成功!', 'success');
} else {
console.error('推送失败:', response.responseText);
showNotification('推送失败,请检查配置', 'error');
}
},
onerror: function(error) {
console.error('网络错误:', error);
showNotification('网络错误', 'error');
}
});
}
// 显示通知
function showNotification(message, type = 'info') {
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
padding: 12px 20px;
background: ${type === 'success' ? '#4CAF50' : type === 'error' ? '#f44336' : '#2196F3'};
color: white;
border-radius: 4px;
z-index: 10000;
font-size: 14px;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
`;
notification.textContent = message;
document.body.appendChild(notification);
setTimeout(() => {
notification.remove();
}, 3000);
}
// 获取推文链接
function getTweetUrl(tweetElement) {
// 查找时间链接元素
const timeLink = tweetElement.querySelector('time')?.closest('a');
if (timeLink && timeLink.href) {
return timeLink.href;
}
// 备用方法:查找包含状态链接的a标签
const statusLinks = tweetElement.querySelectorAll('a[href*="/status/"]');
if (statusLinks.length > 0) {
return statusLinks[0].href;
}
return null;
}
// 创建推送按钮
function createPushButton(tweetElement) {
const button = document.createElement('button');
button.innerHTML = '📤';
button.title = '推送到Telegram';
button.style.cssText = `
background: #1DA1F2;
border: none;
border-radius: 50%;
width: 32px;
height: 32px;
color: white;
cursor: pointer;
font-size: 14px;
margin-left: 8px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s ease;
`;
button.onmouseover = () => {
button.style.background = '#0d8bd9';
button.style.transform = 'scale(1.1)';
};
button.onmouseout = () => {
button.style.background = '#1DA1F2';
button.style.transform = 'scale(1)';
};
button.onclick = (e) => {
e.preventDefault();
e.stopPropagation();
const tweetUrl = getTweetUrl(tweetElement);
if (tweetUrl) {
sendToTelegram(tweetUrl);
} else {
showNotification('无法获取推文链接', 'error');
}
};
return button;
}
// 为推文添加推送按钮
function addPushButtonToTweet(tweetElement) {
// 避免重复添加
if (tweetElement.querySelector('.telegram-push-button')) {
return;
}
// 查找推文的操作按钮区域
const actionBar = tweetElement.querySelector('[role="group"]');
if (actionBar) {
const pushButton = createPushButton(tweetElement);
pushButton.classList.add('telegram-push-button');
actionBar.appendChild(pushButton);
}
}
// 处理新的推文元素
function processTweets() {
const tweets = document.querySelectorAll('[data-testid="tweet"]:not(.processed)');
tweets.forEach(tweet => {
addPushButtonToTweet(tweet);
tweet.classList.add('processed');
});
}
// 监听DOM变化
function observeDOMChanges() {
const observer = new MutationObserver((mutations) => {
let shouldProcess = false;
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1) { // Element node
if (node.matches('[data-testid="tweet"]') ||
node.querySelector('[data-testid="tweet"]')) {
shouldProcess = true;
}
}
});
});
if (shouldProcess) {
setTimeout(processTweets, 100);
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
// 添加设置按钮到页面
function addSettingsButton() {
const settingsButton = document.createElement('button');
settingsButton.innerHTML = '⚙️ Telegram设置';
settingsButton.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
background: #1DA1F2;
color: white;
border: none;
padding: 10px 16px;
border-radius: 20px;
cursor: pointer;
z-index: 9999;
font-size: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
`;
settingsButton.onclick = () => {
const newToken = prompt('输入新的Telegram Bot Token:', TELEGRAM_BOT_TOKEN);
const newChatId = prompt('输入新的Telegram Chat ID:', TELEGRAM_CHAT_ID);
if (newToken && newChatId) {
TELEGRAM_BOT_TOKEN = newToken;
TELEGRAM_CHAT_ID = newChatId;
GM_setValue('telegram_bot_token', newToken);
GM_setValue('telegram_chat_id', newChatId);
showNotification('设置已保存', 'success');
}
};
document.body.appendChild(settingsButton);
}
// 初始化
function init() {
// 等待页面加载
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
return;
}
// 处理现有推文
setTimeout(processTweets, 1000);
// 开始监听DOM变化
observeDOMChanges();
// 添加设置按钮
setTimeout(addSettingsButton, 2000);
console.log('Twitter推送到Telegram脚本已启动');
}
// 启动脚本
init();
})();