您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在草稿箱文章列表标题后边追加醒目提示,快捷生成草稿文章~
// ==UserScript== // @name ✨微信公众号后台快捷工具✨ // @icon https://res.wx.qq.com/a/fed_upload/9300e7ac-cec5-4454-b75c-f92260dd5b47/logo-mp.ico // @namespace https://greasyfork.org/zh-CN/users/1299634-weidingyi // @version 1.3.0 // @description 在草稿箱文章列表标题后边追加醒目提示,快捷生成草稿文章~ // @author weidingyi // @match https://mp.weixin.qq.com/cgi-bin/appmsg*action=list_card* // @match https://mp.weixin.qq.com/cgi-bin/appmsg*action=list* // @grant unsafeWindow // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @connect app.lfeet.asia // @connect localhost // @grant GM_getValue // @grant GM_setValue // @grant GM_cookie // @license MIT // ==/UserScript== const window = unsafeWindow; (function () { 'use strict'; const TK = window.wx ? window.wx.commonData.data.t : ''; // 定时发表列表 var time_send_list; var get_pub_tip = function (flag, title) { var txt = ''; if (flag) { txt = "<span style='color:green'> [已发表]</span>"; } else { // 检查是否在定时发表列表中 txt = "<span style='color:red'> [未发表]</span>"; title = filter_special_chars(title) let isEq = time_send_list.some(function (item) { item = filter_special_chars(item); return item == title; }); if (isEq) { txt = "<span style='color:#f313d9'> [定时发表中]</span>" } } return txt; }; var filter_special_chars = function (str) { // 匹配空格、!、~ 并替换为空字符串 return str.replace(/[\s+! !~]/g, ''); } /** * escape === false时, 为decode, 反之为encode */ var escape = function (str, escape) { // 临时对nickname decode // var ar=['&','&','<','<','>','>',' ',' ','"','"',"'",''','\\r','<br>','\\n','<br>']; var ar = ['&', '&', '<', '<', '>', '>', ' ', ' ', '"', '"', '\'', ''']; /* // 最新版的safari 12有一个BUG,如果使用字面量定义一个数组,var a = [1, 2, 3] // 当调用了 a.reverse() 方法把变量 a 元素顺序反转成 3, 2, 1 后, // 即使此页面刷新了, 或者此页面使用 A标签、 window.open 打开的页面, // 只要调用到同一段代码, 变量 a 的元素顺序都会变成 3, 2, 1 // 所以这里不用 reverse 方法 if (escape === false) { ar.reverse(); } */ var arReverse = [''', '\'', '"', '"', ' ', ' ', '>', '>', '<', '<', '&', '&']; var target; if (escape === false) { target = arReverse; } else { target = ar; } var r = str; for (var i = 0; i < target.length; i += 2) { r = r.replace(new RegExp(target[i], 'g'), target[1 + i]); } return r; } var get_time_send_list = function () { let api = "https://mp.weixin.qq.com/cgi-bin/home?t=home/index&token=" + TK + "&lang=zh_CN&f=json"; return fetch(api) .then(s => s.json()) .then(s => { let json_timesend_msg = JSON.parse(s.timesend_msg); if (json_timesend_msg.sent_list.length <= 0) { return []; } let list = json_timesend_msg.sent_list[0].appmsg_info return list.map(item => { return item.title; }) }) } var fetch_pub_tip = function () { let list = document.querySelectorAll(".weui-desktop-simple-appmsg__title") list.forEach(function (item, idx) { let tip = document.createElement("b"); // 原始标题 let title = item.firstElementChild.textContent; //去除标题中的特殊字符, 有特殊字符时,搜索不准确, 去之 var keywords = item.textContent.replace(/\s+|$$\d+篇$$|\d+篇|\-|、|\~|\!|\!|\-/g, ''); let check_api_json = "https://mp.weixin.qq.com/cgi-bin/appmsgpublish?sub=search&begin=0&count=10&token=" + TK + "&query=" + keywords + "&f=json"; // 调用搜索api, 检查是否发表过 fetch(check_api_json) .then(res => res.json()) .then(res => { let json_publish_page = JSON.parse(res.publish_page); let span = ''; if (json_publish_page.total_count > 0) { span = get_pub_tip(true, title); } else { span = get_pub_tip(false, title); } tip.innerHTML = span; item.appendChild(tip); }) }) } get_time_send_list() .then(res => { time_send_list = res; fetch_pub_tip(); }) })(); (function() { 'use strict'; // 从存储中获取配置 let CONFIG = { buttonText: '生成草稿', formTitle: '提交视频url资源', apiUrl: GM_getValue('apiUrl', 'https://app.lfeet.asia/preGenArticle'), cookie: GM_getValue('cookie', ''), token: window.wx ? window.wx.commonData.data.t : '' }; // 创建按钮 function createButton() { const container = document.querySelectorAll(".weui-desktop-global__extra")[1]; if (!container) { console.error('未找到指定的DOM容器:'); return; } const button = document.createElement('button'); button.className = 'custom-run-button weui-desktop-btn weui-desktop-btn_primary'; button.textContent = CONFIG.buttonText; button.addEventListener('click', toggleForm); container.appendChild(button); } // 创建表单 function createForm() { const overlay = document.createElement('div'); overlay.className = 'custom-form-overlay'; overlay.innerHTML = ` <div class="custom-form-container"> <div class="custom-form-header"> <div class="custom-form-title">${CONFIG.formTitle}</div> <div class="custom-form-close">×</div> </div> <div class="custom-form-body"> <div class="custom-form-field"> <label class="custom-form-label" for="content">歌曲地址</label> <textarea class="custom-form-textarea" id="content" placeholder="请输入歌曲url链接, 多条按回车分割!"></textarea> </div> <div class="custom-form-message custom-form-message-content"></div> <div class="custom-form-field"> <label class="custom-form-label" for="comic">小品地址</label> <textarea class="custom-form-textarea" id="comic" placeholder="请输入小品url链接, 多条按回车分割!"></textarea> </div> <div class="custom-form-message custom-form-message-comic"></div> </div> <div class="custom-form-footer"> <button class="custom-form-button cancel">取消</button> <button class="custom-form-button submit">提交</button> </div> </div> `; document.body.appendChild(overlay); // 添加事件监听 const closeBtn = overlay.querySelector('.custom-form-close'); const cancelBtn = overlay.querySelector('.custom-form-button.cancel'); const submitBtn = overlay.querySelector('.custom-form-button.submit'); const textarea = overlay.querySelector('#content'); const comicTextarea = overlay.querySelector('#comic'); const messageBox = overlay.querySelector('.custom-form-message'); // 关闭表单 - 改进版 function closeForm() { overlay.classList.remove('active'); setTimeout(() => { if (overlay.parentNode) { overlay.parentNode.removeChild(overlay); } }, 300); } closeBtn.addEventListener('click', closeForm); cancelBtn.addEventListener('click', closeForm); overlay.addEventListener('click', (e) => { if (e.target === overlay) closeForm(); }); // 提交表单 submitBtn.addEventListener('click', () => { const content = textarea.value.trim(); const comicContent = comicTextarea.value.trim(); if (!content && !comicContent) { showMessage('至少填写一项内容', 'error'); return; } submitForm({"content": content, "comic": comicContent}); }); return overlay; } // 显示消息 function showMessage(text, type = 'success') { const messageBox = document.querySelector('.custom-form-message'); if (!messageBox) return; messageBox.innerHTML = text; messageBox.className = 'custom-form-message ' + (type === 'success' ? 'success' : 'error'); } // 切换表单显示状态 function toggleForm() { let overlay = document.querySelector('.custom-form-overlay'); if (!overlay) { overlay = createForm(); } overlay.classList.toggle('active'); } // 提交表单数据到API function submitForm(contentObj) { showMessage('文章模板生成中✨ 保持天天输出~😋', 'success'); const u = window.wx.commonData.data.user_name; let api = "https://mp.weixin.qq.com/cgi-bin/appmsgpublish?sub=list&begin=0&count=10&token=" + CONFIG.token + "&lang=zh_CN&f=json"; const content = contentObj.content const comicContent = contentObj.comic fetch(api) .then(s => s.json()) .then(s => { if (s.base_resp.ret === 200040) { throw new Error(s.base_resp.err_msg); } let json_publish_page = JSON.parse(s.publish_page); if (json_publish_page.total_count <= 0) { throw new Error('没有找到最近发布的文章'); } let list = []; json_publish_page.publish_list.forEach(item => { let itemObj = JSON.parse(item.publish_info); itemObj.appmsg_info.forEach(val => { list.push({ cover: val.pic_cdn_url_235_1, title: val.title, link: val.content_url }); }); }); // 生成草稿 GM_xmlhttpRequest({ url: CONFIG.apiUrl, method: 'POST', headers: {'Content-Type': 'application/json; charset=UTF-8', 'Referer': 'mp.weixin.qq.com'}, data: JSON.stringify({ 'c_list': comicContent, 'v_list': content, 'h_list': list, 'u': u, 'ck': CONFIG.cookie, 'tk': CONFIG.token }), responseType: "json", onload: obj => { var data = obj.response; console.log('remote-resp', data); if (data.status == 0) { let msgTips = ''; try { var errDataList = JSON.parse(data.msg); if (Array.isArray(errDataList)) { errDataList.forEach((item, key) => { msgTips += 'url: ' + item.url + "<br> msg: " + item.msg + '<br><br>'; }); } else { msgTips = errDataList; } } catch (e) { msgTips = data.msg; } showMessage('生成草稿文章失败👻: <br>' + msgTips, 'error'); } else { showMessage('生成草稿文章成功👌 保持天天输出~😋', 'success'); setTimeout(() => { const closeBtn = document.querySelector('.custom-form-close'); if (closeBtn) { closeBtn.click(); location.reload(); } }, 1500); } }, onerror: err => { showMessage('提交失败: ' + JSON.stringify(err), 'error'); console.error('send-err', err) } }); }).catch(err => { showMessage('Error: ' + err.message, 'error'); }); // .finally(() => { // showMessage('提交成功! 等待服务端生成草稿...', 'success'); // }) } // 注册菜单命令 function registerMenuCommands() { GM_registerMenuCommand("设置API URL", setApiUrl); GM_registerMenuCommand("设置Cookie", setCookie); } // 设置Cookie function setCookie() { const currentValue = CONFIG.cookie; const newValue = prompt("设置Cookie:", currentValue); if (newValue !== null) { CONFIG.cookie = newValue; GM_setValue('cookie', newValue); alert("Cookie已更新"); } } // 设置API URL function setApiUrl() { const currentValue = CONFIG.apiUrl; const newValue = prompt("设置API URL:", currentValue); if (newValue !== null) { CONFIG.apiUrl = newValue; GM_setValue('apiUrl', newValue); alert("API URL已更新"); } } // 添加样式 GM_addStyle(` .custom-form-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; z-index: 9999; transition: opacity 0.3s ease; } .custom-form-container { background-color: white; border-radius: 8px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); width: 90%; max-width: 500px; transform: scale(0.9); transition: transform 0.3s ease; } .custom-form-overlay.active { opacity: 1; pointer-events: auto; } .custom-form-overlay.active .custom-form-container { transform: scale(1); } .custom-form-header { padding: 16px 24px; border-bottom: 1px solid #e5e5e5; display: flex; justify-content: space-between; align-items: center; } .custom-form-title { font-size: 18px; font-weight: 600; } .custom-form-close { font-size: 24px; cursor: pointer; color: #888; transition: color 0.2s; } .custom-form-close:hover { color: #333; } .custom-form-body { padding: 24px; } .custom-form-field { margin-bottom: 16px; } .custom-form-label { display: block; margin-bottom: 8px; //font-weight: 500; } .custom-form-textarea { width: 95%; min-height: 80px; padding: 10px; border: 1px solid #ddd; border-radius: 4px; resize: vertical; font-family: inherit; font-size: 14px; transition: border-color 0.2s; } .custom-form-textarea:focus { outline: none; border-color: #4a90e2; } .custom-form-footer { padding: 16px 24px; border-top: 1px solid #e5e5e5; display: flex; justify-content: flex-end; } .custom-form-button { padding: 8px 16px; border: none; border-radius: 4px; background-color: #4a90e2; color: white; font-size: 14px; cursor: pointer; transition: background-color 0.2s; margin-left: 8px; } .custom-form-button:hover { background-color: #3a80d2; } .custom-form-button.cancel { background-color: #f5f5f5; color: #333; } .custom-form-button.cancel:hover { background-color: #e5e5e5; } .custom-run-button { padding: 8px 16px; border: none; border-radius: 4px; background-color: #4a90e2; color: white; font-size: 14px; cursor: pointer; transition: background-color 0.2s; margin: 10px; } .custom-run-button:hover { background-color: #3a80d2; } .custom-form-message { margin-top: 12px; padding: 8px 12px; border-radius: 4px; font-size: 14px; display: none; word-break: break-word; overflow-wrap: break-word; } .custom-form-message.success { background-color: #e8f5e9; color: #2e7d32; display: block; } .custom-form-message.error { background-color: #ffebee; color: #c62828; display: block; } `); // 初始化 registerMenuCommands(); createButton(); })();