您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Автоматическая отправка сообщений с настройкой интервалов
当前为
- // ==UserScript==
- // @name Character.AI Auto-Requester
- // @namespace http://tampermonkey.net/
- // @version 2.95555
- // @license GNU GPLv3
- // @description Автоматическая отправка сообщений с настройкой интервалов
- // @match https://character.ai/chat*
- // @author xPress
- // @grant GM_addStyle
- // ==/UserScript==
- //TODO: Слайдер для .control-overlay scale
- (function() {
- 'use strict';
- // Начальные значения
- let delayVoice = 10000;
- let interval = 30000;
- let timer;
- // Стили для оверлея
- GM_addStyle(`
- .control-overlay {
- user-select: none;
- position: absolute;
- top: 50%; /* или любое другое фиксированное значение */
- left: 50%;
- background: rgba(255,255,255,0.8);
- padding: 15px;
- border-radius: 8px;
- color: black;
- z-index: 9999;
- min-width: 250px;
- width: 350px;
- max-height: 800px; /* Максимальная высота */
- transition: max-height 0.4s ease-in-out;
- transform: translate(-50%, -100px) scale(0.9);
- transform-origin: top left; /* или center, в зависимости от нужного эффекта */
- }
- .slider-container {
- margin: 10px 0;
- }
- input[type="range"] {
- width: 100%;
- margin: 5px 0;
- -webkit-appearance: none;
- background: transparent;
- }
- input[type="range"]::-webkit-slider-thumb {
- -webkit-appearance: none;
- height: 16px;
- width: 16px;
- border-radius: 50%;
- background: lime;
- cursor: pointer;
- margin-top: -6px;
- }
- input[type="range"]::-moz-range-thumb {
- height: 16px;
- width: 16px;
- border-radius: 50%;
- background: lime;
- cursor: pointer;
- }
- input[type="range"]::-webkit-slider-runnable-track {
- width: 100%;
- height: 4px;
- cursor: pointer;
- background: #c9c9c9;
- border-radius: 2px;
- }
- input[type="range"]::-moz-range-track {
- width: 100%;
- height: 4px;
- cursor: pointer;
- background: #c9c9c9;
- border-radius: 2px;
- }
- .value-display {
- font-size: 14px;
- margin-top: 5px;
- }
- .header {
- cursor: move;
- padding: 0 10px;
- background: rgba(255,255,255,0.5);
- border-bottom: 1px solid #333;
- }
- .minimized {
- max-height: 53px;
- overflow: hidden;
- }
- .control-overlay:not(.minimized) .content {
- opacity: 1;
- transition: opacity 0.4s ease-in-out;
- }
- .control-overlay.minimized .content {
- opacity: 0;
- transition: opacity 0.4s ease-in-out;
- }
- .switch-container {
- margin: 10px 0;
- }
- .switch {
- position: relative;
- display: inline-block;
- width: 60px;
- height: 34px;
- }
- .switch-container label {
- margin: 15px 35px;
- font-size: 24px;
- margin-top: 23px;
- }
- .switch input {
- opacity: 0;
- width: 0;
- height: 0;
- }
- .slider {
- position: absolute;
- cursor: pointer;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: #ccc;
- -webkit-transition: .4s;
- transition: .4s;
- }
- .slider:before {
- position: absolute;
- content: "";
- height: 26px;
- width: 26px;
- left: 4px;
- bottom: 4px;
- background-color: white;
- -webkit-transition: .4s;
- transition: .4s;
- }
- input:checked + .slider {
- background-color: lime;
- }
- input:focus + .slider {
- box-shadow: 0 0 1px lime;
- }
- input:checked + .slider:before {
- -webkit-transform: translateX(26px);
- -ms-transform: translateX(26px);
- transform: translateX(26px);
- }
- .slider.round {
- border-radius: 34px;
- }
- .slider.round:before {
- border-radius: 50%;
- }
- .description {
- font-size: 11px;
- text-indent: 25px;
- line-height: 5px;
- }
- .description p {
- margin-bottom: 50px; /* Отступ снизу */
- }
- `);
- const textFieldXPath = '//*[@id="chat-body"]/div[2]/div/div/div/div[1]/textarea';
- const sendButtonXPath = '//*[@id="chat-body"]/div[2]/div/div/div/div[2]/button';
- const voiceButtonXPath = '//*[@id="chat-messages"]/div[1]/div[1]/div/div/div[1]/div/div[1]/div[1]/div[2]/div[1]/div[2]/div[2]/div/button';
- // Создаем элементы управления
- const overlay = document.createElement('div');
- overlay.className = 'control-overlay';
- overlay.innerHTML = `
- <div class="header">
- <h3 style="margin:0; display:inline-block;">Character.AI Auto-Requester</h3>
- <button class="minimize" style="float:right;">▼</button>
- </div>
- <div class="content">
- <div class="slider-container">
- <label>Задержка голоса:</label>
- <input type="range" min="1" max="60" value="${delayVoice/1000}" class="voice-delay">
- <div class="value-display">${delayVoice/1000} сек</div>
- </div>
- <div class="slider-container">
- <label>Интервал сообщений:</label>
- <input type="range" min="3" max="120" value="${interval/1000}" class="send-interval">
- <div class="value-display">${interval/1000} сек</div>
- </div>
- <div class="switch-container">
- <label>Вкл/Выкл</label>
- <label class="switch">
- <input type="checkbox" class="toggle-auto-send">
- <span class="slider round"></span>
- </label>
- </div>
- <div class="description">
- Пользуйтесь аккуратно; не совсем понятно, за какие скорости могут забанить аккаунт. В любом случае даже простое использование стороннего софта типа этого, скорее всего, не приветствуется.
- <p>
- Осторожно, смартфон, например, может не отключать экран и не блокироваться из-за работающего скрипта. Даже в состоянии "Выкл".
- </div>
- </div>
- `;
- document.body.appendChild(overlay);
- // Обработчики ползунков
- overlay.querySelector('.voice-delay').addEventListener('input', function(e) {
- delayVoice = e.target.value * 1000;
- e.target.nextElementSibling.textContent = `${e.target.value} сек`;
- // Останавливаем таймер
- clearInterval(timer);
- overlay.querySelector('.toggle-auto-send').checked = false;
- });
- let currentUrl = window.location.href;
- overlay.querySelector('.send-interval').addEventListener('input', function(e) {
- interval = e.target.value * 1000;
- e.target.nextElementSibling.textContent = `${e.target.value} сек`;
- // Останавливаем таймер
- clearInterval(timer);
- overlay.querySelector('.toggle-auto-send').checked = false;
- });
- function clickVoiceButton() {
- const voiceButton = document.evaluate(
- voiceButtonXPath,
- document,
- null,
- XPathResult.FIRST_ORDERED_NODE_TYPE,
- null
- ).singleNodeValue;
- voiceButton?.click();
- }
- function simulateSend() {
- if (window.location.href !== currentUrl) {
- // Останавливаем таймер
- clearInterval(timer);
- overlay.querySelector('.toggle-auto-send').checked = false;
- currentUrl = window.location.href;
- return
- }
- const textField = document.evaluate(
- textFieldXPath,
- document,
- null,
- XPathResult.FIRST_ORDERED_NODE_TYPE,
- null
- ).singleNodeValue;
- const sendButton = document.evaluate(
- sendButtonXPath,
- document,
- null,
- XPathResult.FIRST_ORDERED_NODE_TYPE,
- null
- ).singleNodeValue;
- if (textField && sendButton && !sendButton.disabled) {
- const inputText = textField.value.trim();
- if (inputText === '') {
- sendButton.click();
- textField.value = '';
- setTimeout(clickVoiceButton, delayVoice);
- }
- }
- }
- // Вкл/Выкл
- overlay.querySelector('.toggle-auto-send').addEventListener('change', function(e) {
- if (e.target.checked) {
- // Включаем автоматическую отправку
- clearInterval(timer);
- timer = setInterval(simulateSend, interval);
- // Запоминаем страницу, на которой запустили автоотправку
- let currentUrl = window.location.href;
- } else {
- // Выключаем автоматическую отправку
- clearInterval(timer);
- }
- });
- // Перемещение оверлея
- let isDown = false;
- let offset = [0, 0];
- // Функция для обработки начала касания
- function handleTouchStart(event) {
- if (event.touches.length === 1) { // Только одно касание
- isDown = true;
- const touch = event.touches[0];
- offset = [
- overlay.offsetLeft - touch.clientX,
- overlay.offsetTop - touch.clientY
- ];
- event.preventDefault(); // Предотвратить выделение текста
- }
- }
- // Функция для обработки движения касания
- function handleTouchMove(event) {
- if (isDown) {
- const touch = event.touches[0];
- overlay.style.top = `${touch.clientY + offset[1]}px`;
- overlay.style.right = 'auto'; // Чтобы не было привязки к правому краю
- overlay.style.left = `${touch.clientX + offset[0]}px`;
- event.preventDefault(); // Предотвратить прокрутку страницы
- }
- }
- // Функция для обработки окончания касания
- function handleTouchEnd() {
- isDown = false;
- }
- // Добавление обработчиков событий для касаний
- overlay.querySelector('.header h3').addEventListener('touchstart', handleTouchStart);
- document.addEventListener('touchmove', handleTouchMove);
- document.addEventListener('touchend', handleTouchEnd);
- // Добавление обработчиков событий для мыши (чтобы не потерять функциональность на компьютере)
- overlay.querySelector('.header h3').addEventListener('mousedown', function(event) {
- if (event.button === 0) { // Левая кнопка мыши
- isDown = true;
- offset = [
- overlay.offsetLeft - event.clientX,
- overlay.offsetTop - event.clientY
- ];
- event.preventDefault(); // Предотвратить выделение текста
- }
- });
- document.addEventListener('mouseup', function() {
- isDown = false;
- });
- document.addEventListener('mousemove', function(event) {
- if (isDown) {
- overlay.style.top = `${event.clientY + offset[1]}px`;
- overlay.style.right = 'auto'; // Чтобы не было привязки к правому краю
- overlay.style.left = `${event.clientX + offset[0]}px`;
- }
- });
- // Минимизация/сворачивание
- overlay.querySelector('.minimize').addEventListener('click', function() {
- if (overlay.classList.contains('minimized')) {
- overlay.classList.remove('minimized');
- this.textContent = '▼'; // Используем Unicode для символа
- } else {
- overlay.classList.add('minimized');
- this.textContent = '▲'; // Используем Unicode для символа
- }
- });
- })();