generated at
startTypingの簡易版を実装してみる
js
const Discord = require("discord.js"); const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES"] }); const map = new Map(); function get_or_set(map, k, default_v) { if (map.has(k)) { return map.get(k); } map.set(k, default_v); return default_v; } function create_aborted_event_handler(client_map, context) { const handler = () => { --context.count; if (context.count !== 0) { return; } const v = client_map.get(context.channel_id); if (v === context) { clearInterval(context.timeout); client_map.delete(context.channel_id); context.resolve(); } }; return handler; } /** * * @param {Discord.TextChannel|Discord.NewsChannel|Discord.DMChannel|Discord.ThreadChannel} channel * @param {AbortSignal} signal * @returns */ function startTyping(channel, signal) { const client_map = get_or_set(map, channel.client, new Map()); const channel_id = channel.id; const context = get_or_set(client_map, channel_id, { count: 0, channel_id, }); ++context.count; signal.addEventListener("abort", create_aborted_event_handler(client_map, context)); if (context.count !== 1) { return context.promise; } let reject; context.promise = new Promise((...args) => { [context.resolve, reject] = args; }); const exec = async () => { try { await channel.sendTyping(); } catch (err) { clearInterval(context.timeout); client_map.delete(channel.id); reject(err); } }; context.timeout = setInterval(exec, 9 * 1000); exec(); return context.promise; } client.on("messageCreate", (message) => { const controller = new AbortController(); startTyping(message.channel, controller.signal).then(() => console.log("resolved"),err => console.error(err)); setTimeout(() => controller.abort(), 20 * 1000); }); client.login();

関連