您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automatically tag everyone in a group chat on WhatsApp Web
// ==UserScript== // @name WhatsApp Web Mention Everyone // @namespace AlejandroAkbal // @version 0.1.2 // @description Automatically tag everyone in a group chat on WhatsApp Web // @author Alejandro Akbal // @license AGPL-3.0 // @icon https://www.google.com/s2/favicons?sz=64&domain=whatsapp.com // @homepage https://github.com/AlejandroAkbal/WhatsApp-Web-Mention-Everyone-Userscript // @match https://web.whatsapp.com/* // @grant none // @run-at document-idle // ==/UserScript== /** @param {number} ms * @returns {Promise<void>} */ function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)) } /** * Wait for an element matching the given selector to appear in the DOM * @param {string} selector - The CSS selector to match * @param {Object} [options={}] - Additional options * @param {number} [options.timeout=10000] - The number of milliseconds to wait before timing out * @param {boolean} [options.subtree=true] - Whether to observe the entire subtree or just the target node * @param {boolean} [options.childList=true] - Whether to observe added and removed nodes * @returns {Promise<Element>} - A promise that resolves with the matched element */ async function waitForElement(selector, options = {}) { const { timeout = 10000, subtree = true, childList = true } = options return new Promise((resolve, reject) => { let element let timeoutId const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (node.matches && node.matches(selector)) { element = node observer.disconnect() clearTimeout(timeoutId) resolve(node) return } } } }) observer.observe(document.documentElement, { subtree, childList }) timeoutId = setTimeout(() => { observer.disconnect() if (element) { resolve(element) } else { reject(new Error(`Element not found: ${selector}`)) } }, timeout) }) } ;(async function () { 'use strict' console.info('WhatsApp Web Mention Everyone loaded.') let buffer = '' document.addEventListener('keyup', async (event) => { buffer += event.key // Keep the last 2 characters buffer = buffer.slice(-2) if (buffer === '@@') { buffer = '' // TODO: Delete the last 2 written characters (the "@@") try { await tagEveryone() } catch (error) { alert(error.message) } } }) async function tagEveryone() { const groupSubtitle = document.querySelector("[data-testid='chat-subtitle'] > span") if (!groupSubtitle) { throw new Error('No chat subtitle found. Please open a group chat.') } let groupUsers = groupSubtitle.innerText.split(', ') if (groupUsers.length === 1) { throw new Error('No users found in the group chat. Please wait a second and try again.') } // Remove unnecessary text groupUsers = groupUsers.filter((user) => user !== 'You') // Normalize user's names without accents or special characters groupUsers = groupUsers.map((user) => user.normalize('NFD').replace(/[\u0300-\u036f]/g, '')) const chatInput = document.querySelector("[data-testid='conversation-compose-box-input'] > p") if (!chatInput) { throw new Error('No chat input found. Please type a letter in the chat input.') } for (const user of groupUsers) { document.execCommand('insertText', false, `@${user}`) // await waitForElement("[data-testid='contact-mention-list-item']") await sleep(300) // Send "tab" key to autocomplete the user const keyboardEvent = new KeyboardEvent('keydown', { key: 'Tab', code: 'Tab', keyCode: 9, which: 9, bubbles: true, cancelable: true, view: window }) chatInput.dispatchEvent(keyboardEvent) document.execCommand('insertText', false, ' ') } } })()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址