Skip to content

Instantly share code, notes, and snippets.

@shelllee
Last active February 14, 2025 08:29
Show Gist options
  • Save shelllee/370ee8d78edbd8fc5ca638576463190f to your computer and use it in GitHub Desktop.
Save shelllee/370ee8d78edbd8fc5ca638576463190f to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Wechat Official Accounts Assistant
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Auto load original images and copy information from Wechat Official Accounts articles
// @author Cline
// @match https://mp.weixin.qq.com/s/*
// @grant none
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
let isLoading = false;
let initialScrollPosition = 0;
let hasCopied = false;
function smoothScrollTo(position) {
return new Promise(resolve => {
window.scrollTo({
top: position,
behavior: 'smooth'
});
const checkScrollEnd = setInterval(() => {
if (Math.abs(window.scrollY - position) < 10) {
clearInterval(checkScrollEnd);
resolve();
}
}, 16);
setTimeout(() => {
clearInterval(checkScrollEnd);
resolve();
}, 1000);
});
}
async function smoothScroll() {
if (isLoading) return;
isLoading = true;
initialScrollPosition = window.scrollY;
const maxScroll = Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight
);
window.scrollTo(0, 0);
await new Promise(resolve => setTimeout(resolve, 100));
await smoothScrollTo(maxScroll);
await new Promise(resolve => setTimeout(resolve, 100));
processImages();
await smoothScrollTo(initialScrollPosition);
isLoading = false;
}
function getOriginalImageUrl(url) {
let cleanUrl = url.split('?')[0];
cleanUrl = cleanUrl.replace(/\/\d+$/, '/0');
const isGif = url.includes('wx_fmt=gif');
return `${cleanUrl}?wx_fmt=${isGif ? 'gif' : 'png'}`;
}
function processImages() {
const images = document.querySelectorAll('img');
images.forEach(img => {
if(!img.dataset.processed && img.src) {
img.dataset.processed = 'true';
img.src = getOriginalImageUrl(img.src);
}
});
}
function parseDate(dateStr) {
dateStr = dateStr.replace(/\s+/g, '');
const patterns = [
/(\d{4})[-/](\d{1,2})[-/](\d{1,2})/,
/(\d{4})年(\d{1,2})月(\d{1,2})日/,
/(\d{1,2})[-/](\d{1,2})[-/](\d{4})/
];
for (const pattern of patterns) {
const match = dateStr.match(pattern);
if (match) {
let year, month, day;
if (match[1].length === 4) {
[, year, month, day] = match;
} else {
[, month, day, year] = match;
}
month = String(month).padStart(2, '0');
day = String(day).padStart(2, '0');
return `${year}.${month}.${day}`;
}
}
const now = new Date();
return `${now.getFullYear()}.${String(now.getMonth() + 1).padStart(2, '0')}.${String(now.getDate()).padStart(2, '0')}`;
}
// Keep all text content:
// 1. Basic CJK: \u4e00-\u9fff
// 2. CJK Extension A: \u3400-\u4dbf
// 3. CJK Punctuation: \u3000-\u303f
function cleanText(text) {
if (!text) return '';
return text
.trim()
.replace(/[^\u4e00-\u9fff\u3400-\u4dbf\u3000-\u303fA-Za-z0-9\[\]【】\.-]/g, '_')
.replace(/^_+|_+$/g, '')
.replace(/_+/g, '_');
}
function getArticleInfo() {
// Try SSR data first
if (window.__QMTPL_SSR_DATA__) {
const { nick_name, title, publishTime } = window.__QMTPL_SSR_DATA__;
if (nick_name && title) {
return {
accountName: nick_name,
title: title,
publishTime: publishTime || ''
};
}
}
// Fallback to DOM elements
return {
accountName: document.querySelector('#js_name, .profile_nickname')?.textContent.trim() || '',
title: document.querySelector('#activity-name, .rich_media_title')?.textContent.trim() || '',
publishTime: document.querySelector('#publish_time')?.textContent.trim() || ''
};
}
function tryToCopy() {
if (hasCopied) return;
const { accountName, title, publishTime } = getArticleInfo();
if (!accountName || !title) return;
const formattedDate = parseDate(publishTime);
const result = cleanText(`${accountName}_${title}_${formattedDate}`);
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(result).then(() => {
//hasCopied = true;
});
}
}
// Initialize
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => setTimeout(smoothScroll, 100));
} else {
setTimeout(smoothScroll, 100);
}
// Check and copy text regularly
setInterval(tryToCopy, 1000);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment