Lately my laziness has reached terminal stage. While surfing the web I often run into interesting stuff I want to send to my phone, yet I can’t be bothered to log into WeChat every single time—having to open WeChat, pick up the phone, and scan a code is just too much hassle.

表情包
Then I remembered I once set up “Vinking酱” on my server with the help of Server酱’s Wecom酱, basically just to receive blog-comment notifications. Maybe I could push text straight from the browser to WeChat through Vinking酱 and save myself the trouble. I spent a tiny bit of time whipping up a simple userscript and dropped it into Tampermonkey.
The plugin works by first grabbing the user’s selection with window.getSelection().toString(), then listening for the key comboctrl +alt +P. If something is selected, pressing the combo fires the text off to WeChat. During testing, however, WeChat often received only part of a long chunk—everything after & vanished. I finally realized I’d forgotten to escape & , so the remainder was treated as a query-string parameter. After adding special-character handling, it behaved exactly as I wanted.

效果
const REPLACEMENT_TEXT = '{and}';
function setupEventHandlers() {
document.body.onmouseup = function() {
let selectText = window.getSelection().toString().trim();
if (selectText.includes("&")) {
selectText = selectText.replace(/&/g, REPLACEMENT_TEXT);
}
if (selectText) {
document.body.onkeydown = function(event) {
if (event.ctrlKey && event.altKey && event.keyCode === 80) {
var Tip = confirm("已经获取选中文字:\n" + selectText + "\n需要转发到 Vinking酱 吗?");
if (Tip) {
/*处理转发*/
}
}
};
}
};
}
setupEventHandlers();
I also threw together a second plugin that extracts a webpage’s QR code, turns it into a URL, and forwards that to WeChat. It relies on jsQR.js, html2canvas.min.js, and jQuery. CORS crushed my spirit, though; after wrestling with it for ages, my laziness flared up and I gave up.
const BUTTON_STYLE = {
position: 'fixed',
bottom: '50px',
right: '20px'
};
const createButton = document.createElement("button");
createButton.id = "getURL";
Object.assign(createButton.style, BUTTON_STYLE);
createButton.innerHTML = "截取二维码";
document.body.appendChild(createButton);
const createImage = document.createElement("canvas");
createImage.id = "qrcanvas";
createImage.style.display = 'none';
document.body.appendChild(createImage);
const c = document.getElementById("qrcanvas");
const ctx = c.getContext("2d");
createButton.onclick = async function() {
try {
const canvas = await html2canvas(document.body);
const oImg = new Image();
oImg.src = canvas.toDataURL();
await new Promise(resolve => oImg.onload = resolve);
c.setAttribute("width", oImg.width);
c.setAttribute("height", oImg.height);
ctx.drawImage(oImg, 0, 0, oImg.width, oImg.height);
const imageData = ctx.getImageData(0, 0, oImg.width, oImg.height);
const code = jsQR(imageData.data, imageData.width, imageData.height, { inversionAttempts: "dontInvert" });
if (code) {
const Tip = confirm("二维码获取成功,需要转发到 Vinking酱 吗?");
if (Tip) {
// 处理转发
}
} else {
alert("没有找到二维码");
}
} catch (error) {
console.error("Error capturing canvas:", error);
}
}