您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
6/19/2025, 10:33:41 PM - What a dumb script lol. Sends any mail from your mailbox(when you go to the page) to a discord webhook.
// ==UserScript== // @name Torn Newsletter To Discord // @namespace Violentmonkey Scripts // @match https://www.torn.com/messages.php* // @grant GM_xmlhttpRequest // @version 1.1 // @license MIT // @author Bilbosaggings [2323763] (BillyBourbon) // @description 6/19/2025, 10:33:41 PM - What a dumb script lol. Sends any mail from your mailbox(when you go to the page) to a discord webhook. // ==/UserScript== const webhookUrl = 'REPLACE_WITH_YOUR_DISCORD_CHANNELS_WEBHOOK_URL_HERE'; const factionDiscordRoleId = 'REPLACE_WITH_THE_DISCORD_ROLE_ID_OF_YOUR_FACTION' // IE '813511364311384126' const mailContainerSelector = '.mailbox-container'; const localStorageKey = 'NewsletterToDiscord'; const webhookBasePayload = { 'username' : 'Faction Newsletter Script' }; (() => { function timeStringToTimestamp(timeDate){ const [time, date] = timeDate.split(' ') const [hour, minute, second] = time.split(':') const [day, month, year] = date.split('/') const longYear = 2000 + parseInt(year) const dateParsed = new Date(longYear, (parseInt(month) - 1), parseInt(day), parseInt(hour), parseInt(minute), parseInt(second)) const timestampSeconds = Math.floor(dateParsed.getTime()/1000) return timestampSeconds } function waitForMailContainer(){ const container = document.querySelector(mailContainerSelector) if(container){ console.log(`Found '${mailContainerSelector}'`) handleMailContainer(container) } else{ console.log(`Waiting For '${mailContainerSelector}'`) setTimeout(waitForMailContainer, 500) } } function handleMailContainer(container){ let storedData = localStorage[localStorageKey] if(storedData === undefined) { storedData = { timestampLastNewsletter: Math.floor((new Date().getTime()/1000) - (60*60*24)) } } else { storedData = JSON.parse(storedData) } console.log({ storedData }) const mailList = container.querySelector('.container-body-list') const mails = mailList.querySelectorAll('.row-color-marker') const mailsToSend = [] let updatedTimestamp = storedData.timestampLastNewsletter ?? 0 for(const mail of mails){ const mailObject = handleMail(mail) if(mailObject.isFactionMail && mailObject.timestamp > storedData.timestampLastNewsletter){ mailsToSend.push(mailObject) updatedTimestamp = mailObject.timestamp > updatedTimestamp ? mailObject.timestamp : updatedTimestamp } } if(mailsToSend.length > 0){ try{ sendMailsToDiscord(mailsToSend) if(updatedTimestamp > storedData.timestampLastNewsletter){ console.log('Updating Stored Data') storedData.timestampLastNewsletter = updatedTimestamp localStorage[localStorageKey] = JSON.stringify(storedData) } } catch(e){ console.error('Error Uploading Newsie To Discord. Error: ', e) } } } function handleMail(mail){ const mailTime = mail.querySelector('.date-time').innerText const mailContent = mail.querySelector('.mail-link') const mailSender = mailContent.querySelector('.sender-name') const mailSenderName = mailSender.innerText.trim() const mailSenderProfileLink = mailSender.href const mailSenderId = mailSenderProfileLink.split('XID=')[1].trim() const mailBody = mailContent.querySelector('.subject') const mailTitle = mailBody.innerText.trim() const mailText = mailBody.getAttribute('title').replace(/\u00A0/g, ' ').trim() const mailLink = mailBody.href.trim() const isFactionMail = mailText.startsWith('This is a newsletter from your faction:') const mailObject = { timestamp: timeStringToTimestamp(mailTime), sender : { name : mailSenderName, id : mailSenderId, link : mailSenderProfileLink }, title : mailTitle, content : mailText, mailLink, isFactionMail } return mailObject } function sendMailsToDiscord(mailObjects){ const embedChunks = [] mailObjects.forEach((obj, i) => { if(!embedChunks[Math.floor(i/5)]) embedChunks.push([]) if(!obj.title || !obj.content || !obj.timestamp || !obj.sender) return const embed = mailObjectToDiscordEmbed(obj) embedChunks[Math.floor(i/5)].push(embed) }) console.log({embedChunks}) embedChunks.forEach((embeds, chunkCount) => { console.log(`Attempting To Send Chunk (${chunkCount + 1}) Of (${embedChunks.length})`) if(embeds.length === 0) { console.log(`Aborting Send. Chunk (${chunkCount + 1}}) Contains 0 Embeds`) return } const payload = { ...webhookBasePayload, content: `New Faction Newsletter <@&${factionDiscordRoleId}>`, embeds } console.log(`Chunk (${chunkCount + 1}) Payload: `, {payload: {stringified: JSON.stringify(payload), parsed: payload}}) GM_xmlhttpRequest({ method: "POST", url: webhookUrl, headers: { "Content-Type": "application/json" }, data: JSON.stringify(payload), onload: (response) => { console.log(`Successfully Sent Chunk (${chunkCount + 1}) On Webhook: `, response.status, {response}); }, onerror: (err) => { console.error(`Failure Sending Chunk (${chunkCount + 1}) On Webhook: `, err); } }); }) } function mailObjectToDiscordEmbed(object){ const { sender: { name: senderName, id: senderId, link: senderProfileLink }, timestamp, title, content, mailLink } = object const embed = { "author": { "name": `${senderName} [${senderId}]`, "url": senderProfileLink.trim() }, "title": title.trim(), "url": mailLink.trim(), "description": content.replace(/ +/g, "\n").replace(/ {2,}/g, "\n").trim(), //This feels dumb "color": 11342935, // Pink :) "footer": { "text": "Some Footer Text | Made By Bilbosaggings[2323763]" }, "timestamp": new Date(timestamp * 1000).toISOString() } return embed } waitForMailContainer() })()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址