mirror of
https://github.com/lencx/Noi.git
synced 2025-12-15 17:40:48 +01:00
294 lines
7.5 KiB
JavaScript
294 lines
7.5 KiB
JavaScript
/**
|
|
* NoiAsk: Batch send messages to AI Chat.
|
|
*
|
|
* This file is a modified version of the GodMode.
|
|
* ref: https://github.com/smol-ai/GodMode/tree/main/src/providers
|
|
*/
|
|
|
|
class NoiAsk {
|
|
static sync(message) {
|
|
const inputElement = document.querySelector('textarea');
|
|
if (inputElement) {
|
|
const nativeTextareaSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value').set;
|
|
nativeTextareaSetter.call(inputElement, message);
|
|
const inputEvent = new InputEvent('input', {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
});
|
|
inputElement.dispatchEvent(inputEvent);
|
|
}
|
|
}
|
|
|
|
static simulateUserInput(element, text) {
|
|
const inputEvent = new InputEvent('input', {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
});
|
|
element.focus();
|
|
element.value = text;
|
|
element.dispatchEvent(inputEvent);
|
|
}
|
|
|
|
static autoClick(btn) {
|
|
btn.focus();
|
|
btn.disabled = false;
|
|
btn.click();
|
|
}
|
|
}
|
|
|
|
class OpenAIAsk extends NoiAsk {
|
|
static name = 'ChatGPT';
|
|
static url = 'https://chat.openai.com';
|
|
|
|
static submit() {
|
|
const btn = document.querySelector('button[data-testid="send-button"]');
|
|
if (btn) this.autoClick(btn);
|
|
}
|
|
}
|
|
|
|
class PoeAsk extends NoiAsk {
|
|
static name = 'Poe';
|
|
static url = 'https://poe.com';
|
|
|
|
static submit() {
|
|
const btn = document.querySelectorAll('button[class*="ChatMessageSendButton_sendButton"]')[0];
|
|
if (btn) this.autoClick(btn);
|
|
}
|
|
}
|
|
|
|
class ClaudeAsk extends NoiAsk {
|
|
static name = 'Claude';
|
|
static url = 'https://claude.ai';
|
|
|
|
static sync(message) {
|
|
const inputElement = document.querySelector('div.ProseMirror');
|
|
if (inputElement) {
|
|
inputElement.focus();
|
|
inputElement.innerHTML = '';
|
|
document.execCommand('insertText', false, message);
|
|
}
|
|
}
|
|
|
|
static submit() {
|
|
// subsequent screens use this
|
|
let btn = document.querySelector('button[aria-label*="Send Message"]');
|
|
if (!btn) { // new chats use this
|
|
btn = document.querySelector('button:has(div svg)');
|
|
}
|
|
if (!btn) { // last ditch attempt
|
|
btn = document.querySelector('button:has(svg)');
|
|
}
|
|
if (btn) this.autoClick(btn);
|
|
}
|
|
}
|
|
|
|
class GeminiAsk extends NoiAsk {
|
|
static name = 'Gemini';
|
|
static url = 'https://gemini.google.com';
|
|
|
|
static sync(message) {
|
|
const inputElement = document.querySelector('.ql-editor.textarea');
|
|
if (inputElement) {
|
|
const inputEvent = new Event('input', { bubbles: true });
|
|
inputElement.value = message;
|
|
inputElement.dispatchEvent(inputEvent);
|
|
// bard is weird
|
|
inputElement.querySelector('p').textContent = message;
|
|
}
|
|
}
|
|
|
|
static submit() {
|
|
const btn = document.querySelector('button[aria-label*="Send message"]');
|
|
if (btn) {
|
|
btn.setAttribute('aria-disabled', 'false'); // doesn't work alone
|
|
btn.focus();
|
|
btn.click();
|
|
}
|
|
}
|
|
}
|
|
|
|
class HuggingChatAsk extends NoiAsk {
|
|
static name = 'HuggingChat';
|
|
static url = 'https://huggingface.co/chat';
|
|
|
|
static sync(message) {
|
|
var inputElement = document.querySelector('textarea[placeholder*="Ask anything"]');
|
|
if (inputElement) {
|
|
const inputEvent = new Event('input', { bubbles: true });
|
|
inputElement.value = message;
|
|
inputElement.dispatchEvent(inputEvent);
|
|
}
|
|
}
|
|
|
|
static submit() {
|
|
var btn = document.querySelector('form.relative > div > button[type="submit"]');
|
|
if (btn) this.autoClick(btn);
|
|
}
|
|
}
|
|
|
|
class PerplexityAsk extends NoiAsk {
|
|
static name = 'Perplexity';
|
|
static url = 'https://www.perplexity.ai';
|
|
|
|
static submit() {
|
|
const btns = Array.from(document.querySelectorAll('button.bg-super'));
|
|
if (btns[0]) {
|
|
const btnsWithSvgPath = btns.filter(button => button.querySelector('svg path'));
|
|
const btn = btnsWithSvgPath[btnsWithSvgPath.length - 1];
|
|
btn.click();
|
|
}
|
|
}
|
|
}
|
|
|
|
class CopilotAsk extends NoiAsk {
|
|
static name = 'Copilot';
|
|
static url = 'https://copilot.microsoft.com';
|
|
|
|
static sync(message) {
|
|
// SERP Shadow DOM
|
|
const serpDOM = document.querySelector('.cib-serp-main');
|
|
// Action Bar Shadow DOM
|
|
const inputDOM = serpDOM.shadowRoot.querySelector('#cib-action-bar-main');
|
|
// Text Input Shadow DOM
|
|
const textInputDOM = inputDOM.shadowRoot.querySelector('cib-text-input');
|
|
// This inner cib-text-input Shadow DOM is not always present
|
|
const inputElement = textInputDOM ? textInputDOM.shadowRoot.querySelector('#searchbox') : inputDOM.shadowRoot.querySelector('#searchbox');
|
|
if (inputElement) {
|
|
this.simulateUserInput(inputElement, message);
|
|
}
|
|
}
|
|
|
|
static submit() {
|
|
try {
|
|
// Access SERP Shadow DOM
|
|
const serpDOM = document.querySelector('.cib-serp-main');
|
|
// Action Bar Shadow DOM
|
|
const actionDOM = serpDOM.shadowRoot.querySelector('#cib-action-bar-main');
|
|
// Submit Button
|
|
const submitButton = actionDOM.shadowRoot.querySelector('div.submit button');
|
|
|
|
if (submitButton) {
|
|
submitButton.click();
|
|
submitButton.focus();
|
|
setTimeout(() => {
|
|
submitButton.click();
|
|
}, 100)
|
|
}
|
|
} catch (e) {
|
|
console.error('Copilot submit error', e);
|
|
}
|
|
}
|
|
}
|
|
|
|
class PiAsk extends NoiAsk {
|
|
static name = 'Pi';
|
|
static url = 'https://pi.ai/talk';
|
|
|
|
static submit() {
|
|
const inputElement = document.querySelector('textarea[placeholder="Talk with Pi"]');
|
|
if (inputElement) {
|
|
const event = new KeyboardEvent('keydown', {
|
|
key: 'Enter',
|
|
view: window,
|
|
bubbles: true
|
|
});
|
|
inputElement.dispatchEvent(event);
|
|
}
|
|
}
|
|
}
|
|
|
|
class CozeAsk extends NoiAsk {
|
|
static name = 'Coze';
|
|
static url = 'https://www.coze.com/home';
|
|
|
|
static submit() {
|
|
const inputElement = document.querySelector('textarea');
|
|
if (inputElement) {
|
|
const nextElement = inputElement.nextElementSibling;
|
|
if (nextElement) {
|
|
const btn = nextElement.querySelector('button');
|
|
if (btn) btn.click();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class YouAsk extends NoiAsk {
|
|
static name = 'YOU';
|
|
static url = 'https://you.com';
|
|
|
|
static submit() {
|
|
const btn = document.querySelector('button[data-eventactionname="click_send"]');
|
|
if (btn) btn.click();
|
|
}
|
|
}
|
|
|
|
class CozeCNAsk extends NoiAsk {
|
|
static name = 'Coze';
|
|
static url = 'https://www.coze.cn/home';
|
|
|
|
static submit() {
|
|
const inputElement = document.querySelector('textarea');
|
|
if (inputElement) {
|
|
const nextElement = inputElement.nextElementSibling;
|
|
if (nextElement) {
|
|
const btn = nextElement.querySelector('button');
|
|
if (btn) btn.click();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class ChatGMLAsk extends NoiAsk {
|
|
static name = 'ChatGLM'; // 智谱清言
|
|
static url = 'https://chatglm.cn';
|
|
|
|
static submit() {
|
|
const btn = document.querySelector('#search-input-box .enter img');
|
|
if (btn) btn.click();
|
|
}
|
|
}
|
|
|
|
class DoubaoAsk extends NoiAsk {
|
|
static name = 'Doubao'; // 豆包
|
|
static url = 'https://www.doubao.com';
|
|
|
|
static submit() {
|
|
const btn = document.querySelector('#flow-end-msg-send');
|
|
if (btn) btn.click();
|
|
}
|
|
}
|
|
|
|
class TongyiAsk extends NoiAsk {
|
|
static name = 'TongYi'; // 通义千问
|
|
static url = 'https://tongyi.aliyun.com/qianwen';
|
|
|
|
static submit() {
|
|
const inputElement = document.querySelector('textarea');
|
|
if (inputElement) {
|
|
const nextElement = inputElement.nextElementSibling;
|
|
if (nextElement) {
|
|
const btn = nextElement.querySelector('div[class^="chatBtn"]');
|
|
if (btn) btn.click();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
window.NoiAsk = {
|
|
OpenAIAsk,
|
|
PoeAsk,
|
|
ClaudeAsk,
|
|
GeminiAsk,
|
|
HuggingChatAsk,
|
|
PerplexityAsk,
|
|
CopilotAsk,
|
|
PiAsk,
|
|
CozeAsk,
|
|
YouAsk,
|
|
CozeCNAsk,
|
|
DoubaoAsk,
|
|
ChatGMLAsk,
|
|
TongyiAsk,
|
|
};
|