Я видел этот пост на Reddit (Скрипт автоответа в другом потоке) и считаю решение @puerdon очень полезным, но мне интересно, можно ли добавить время восстановления автоответа в скрипт/html-код (Вы можете проверить исходный HTML-код в сообщении Reddit выше).
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<meta http-equiv = "X-UA-Compatible" content = "IE=edge">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<script src = "https://github.com/tmijs/tmi.js/releases/download/v1.8.5/tmi.min.js"></script>
<script>
const client = new tmi.Client({
options: {
debug: false,
skipMembership: true, // 不接收 JOIN/PART 訊息
skipUpdatingEmotesets: true,
},
connection: {
reconnect: true,
secure: true
},
identity: {
username: 'your_twitch_username', // [TODO]: input your Twitch username
password: 'genereated_oath_password' // [TODO]: input the genereated oath password
// 1. go to https://twitchapps.com/tmi/
// 2. click "Connect"
// 3. You will get a password beginning with "oath..."
// 4. Copy the whole password and paste inside the 'genereated_oath_password'
},
channels: [ 'type_the_channel_you_want_to_listen_to' ] // [TODO]: input the channel name you want to listen to
});
let lastSchedule = undefined;
function F(client, channel, message) {
let currentMoment = new Date();
function f() {
client.say(channel, message);
}
if ((!lastSchedule) || (lastSchedule < new Date(lastSchedule - 120000))) {
lastSchedule = currentMoment;
f();
} else {
lastSchedule.setMinutes(lastSchedule.getMinutes() + 2);
setTimeout(f, lastSchedule - currentMoment);
}
}
client.connect().catch(console.error);
client.on('message', (channel, tags, message, self) => {
// this part is to skip the message sent by you,
// or it will be prone to cause infinite loop
if (self) {
console.info(self);
return;
}
// Here is the example of detecting a "hello" in a message
// I first turn message to lower case and then check if the message includes "hello" in it
// This can then detect "Hello", "hELLO", "HELLO" ... etc. variation of capitalization in the message
if (message.toLowerCase().includes("hello")) {
// if the condition above is met, then send "Hi" in the chat
F(channel, client, "Hi!");
}
});
</script>
</body>
</html>
Скажем, после отправки первого «привет» в болтовне я хочу создать сценарий, который будет отправлять автоматический ответ «привет» один раз и отвечать снова только в течение следующих 2 или 3 минут. Таким образом, он не будет рассылать одно и то же сообщение, если за такой короткий период времени будет слишком много приветов.
ПС. Я отправил @puerdon личное сообщение, чтобы помочь мне с моим запросом, так как я не программист, но он долгое время мне не отвечал (возможно, уже заброшенный аккаунт), поэтому я подумал поделиться этим здесь, если кто-нибудь знает, как чтобы добавить эту функцию.
Любые полезные идеи будут высоко оценены. Большое спасибо!
Добавьте несколько строк кода, которые позволят мне добавить время восстановления или буферизации между автоматическими сообщениями.
Одна из концепций, реализующих эффект «перезарядки», называется «устранение дребезга».
Вот простая функция устранения дребезга:
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
В вашем случае вы бы инкапсулировали свою функциональность в метод типа maybeSayHello()
и передали ее этой функции устранения дребезга вместе с временем восстановления в миллисекундах.
Если автоответчик представляет собой отправленное в ответ «привет», вы можете отложить его следующим образом:
if (message.toLowerCase().includes("hello")) {
// if the condition above is met, then send "hello" in the chat
setTimeout(function() {client.say(channel, "Hi!")}, 1000 * 2 * 60);
}
Или, если вы хотите убедиться, что функция, назовем ее f
, не может быть выполнена дважды за 2 минуты, и отложить ее вызов, то вы можете сделать что-то вроде этого:
let lastSchedule = undefined;
function F(message) {
let currentMoment = new Date();
function f() {
console.info(message);
}
if ((!lastSchedule) || (lastSchedule < new Date(lastSchedule - 120000))) {
lastSchedule = currentMoment;
f();
} else {
lastSchedule.setMinutes(lastSchedule.getMinutes() + 2);
setTimeout(f, lastSchedule - currentMoment);
}
}
F("a");F("b");F("c");F("d");
Добавляем код к вашему:
let lastSchedule = undefined;
function F(channel, client, message) {
let currentMoment = new Date();
function f() {
client.say(channel, message);
}
if ((!lastSchedule) || (lastSchedule < new Date(lastSchedule - 120000))) {
lastSchedule = currentMoment;
f();
} else {
lastSchedule.setMinutes(lastSchedule.getMinutes() + 2);
setTimeout(f, lastSchedule - currentMoment);
}
}
вы можете определить F непосредственно перед
client.connect().catch(console.error);
например.
Вы можете вызвать F, заменив:
client.say(channel, "Hi!");
с
F(channel, client, "Hi!");
Спасибо за ваш ответ! Могу ли я спросить, что это за значения здесь, в частности «1000*2*60»? И ваш второй ответ - именно то, что я хотел! Я не хочу, чтобы ответ «Привет» был отправлен несколько раз в течение 2 минут, чтобы предотвратить рассылку одного и того же сообщения спамом. Но куда мне вставить предоставленный вами код. Мне очень жаль, я не программист, извините за мои нубские вопросы.
@user26604864 user26604864 1000 означает количество миллисекунд в секунде, 2 означает количество минут, которые мы хотели, а 60 означает количество секунд в минуте. В вашем случае f
будет функцией, состоящей из client.say(channel, "Hi!");
, поэтому вы можете заменить строку console.info(message);
на строку client.say(channel, message);
.
Спасибо за разъяснения по первой части! Помимо времени восстановления (ваш второй код), мне нравится добавление задержки (ваш первый код). Но я действительно не понимаю, как их соединить. Если вы не против, можете ли вы показать, как их следует интегрировать вместе в исходном коде, как вы показали в своем первом коде?
@user26604864 добавил дополнительную информацию. Пожалуйста, дайте мне знать, если возникнут дополнительные вопросы.
Огромное спасибо за то, что помогли мне до сих пор!! Я попытался скопировать предоставленный вами код (см. изменения в коде в исходном сообщении). Не могли бы вы проверить, правильно ли это? Я не совсем уверен, куда это добавить. 😅 Я также отправил ссылку GDoc на html-файл на случай, если вы захотите внести свои изменения (docs.google.com/document/d/…)
@user26604864 user26604864 Я отредактировал ваш вопрос и скорректировал код, поместил функцию в более подходящее место, скорректировал ее табуляцию и гарантировал, что мы вызываем F вместо client.say, чтобы применить время восстановления. Вам нужно будет протестировать этот код, чтобы увидеть, работает ли он, поскольку на данный момент это всего лишь код, который хорошо выглядит, но нам нужны эмпирические результаты, то есть результаты тестирования.
Спасибо за обновления, которые вы сделали! Теперь мне стало немного яснее. У меня просто вопрос: где находится задержка и кулдаун? Могу ли я также настроить время, если захочу изменить его в будущем?
@user26604864 user26604864 все это внутри функции F
. if ((!lastSchedule) || (lastSchedule < new Date(lastSchedule - 120000)))
проверяет, вызываем ли мы эту функцию в первый раз или истек период восстановления (120000 означает 2 минуты * 60 секунд * 1000 миллисекунд), а lastSchedule.setMinutes(lastSchedule.getMinutes() + 2);
увеличивает предыдущий последний график на 2 минуты (он находится в ветке else, поэтому мы знаем, что в этом случае нам нужно подождать). setTimeout(f, lastSchedule - currentMoment);
графики f
будут выполняться в то время, когда нам это нужно.
Я попытался протестировать обновленный код из исходного сообщения, но, к сожалению, он не работает. Однако когда я попробовал использовать только ваш первый код, код задержки, он сработал! Я не знаю, почему код перезарядки не работает.
@user26604864 user26604864, вероятно, это не работает из-за какой-то ошибки, допущенной вами или мной. Видите ли вы ошибки в консоли браузера во время тестирования другого кода?
Вот скриншот консоли браузера: drive.google.com/file/d/1YBk-HeHz532gnqnUNN6hJx7XoOw_Wu0Z/…
@ user26604864 ошибка говорит нам, что client.say не является функцией, и это правильно, потому что я передал параметры в неправильном порядке.
@ user26604864 Я изменил function F(client, channel, message) {
на function F(channel, client, message) {
, пожалуйста, измените эту строку соответствующим образом в вашей попытке.
Я обновил его, и он наконец-то работает! Больше никаких ошибок в консоли браузера. Огромное спасибо за вашу огромную помощь. Очень ценю это! 🙏
Спасибо за ваш ответ! но где мне вставить в код функцию устранения дребезга? Спасибо за Ваше понимание!