UNPKG

@twurple/chat

Version:

Interact with the Twitch Messaging Interface (aka Twitch chat).

88 lines (87 loc) 3.63 kB
import { decodeCtcp, MessageTypes, parseMessage } from 'ircv3'; import { ClearChat } from '../caps/twitchCommands/messageTypes/ClearChat.js'; import { Reconnect } from '../caps/twitchCommands/messageTypes/Reconnect.js'; import { RoomState } from '../caps/twitchCommands/messageTypes/RoomState.js'; import { UserNotice } from '../caps/twitchCommands/messageTypes/UserNotice.js'; import { UserState } from '../caps/twitchCommands/messageTypes/UserState.js'; import { Whisper } from '../caps/twitchCommands/messageTypes/Whisper.js'; import { ClearMsg } from '../caps/twitchTags/messageTypes/ClearMsg.js'; import { GlobalUserState } from '../caps/twitchTags/messageTypes/GlobalUserState.js'; import { ChatMessage } from '../commands/ChatMessage.js'; let twitchMessageTypesCache = null; function getTwitchMessageTypes() { return (twitchMessageTypesCache ??= new Map([ // standard types used by Twitch ['PRIVMSG', ChatMessage], ['NOTICE', MessageTypes.Commands.Notice], ['PING', MessageTypes.Commands.Ping], ['PONG', MessageTypes.Commands.Pong], ['JOIN', MessageTypes.Commands.ChannelJoin], ['PART', MessageTypes.Commands.ChannelPart], ['NICK', MessageTypes.Commands.NickChange], ['PASS', MessageTypes.Commands.Password], ['CAP', MessageTypes.Commands.CapabilityNegotiation], ['001', MessageTypes.Numerics.Reply001Welcome], ['002', MessageTypes.Numerics.Reply002YourHost], ['003', MessageTypes.Numerics.Reply003Created], // 004 intentionally left out because not standards-conforming ['353', MessageTypes.Numerics.Reply353NamesReply], ['366', MessageTypes.Numerics.Reply366EndOfNames], ['372', MessageTypes.Numerics.Reply372Motd], ['375', MessageTypes.Numerics.Reply375MotdStart], ['376', MessageTypes.Numerics.Reply376EndOfMotd], // Twitch extensions ['CLEARCHAT', ClearChat], ['USERSTATE', UserState], ['GLOBALUSERSTATE', GlobalUserState], ['WHISPER', Whisper], ['ROOMSTATE', RoomState], ['RECONNECT', Reconnect], ['USERNOTICE', UserNotice], ['CLEARMSG', ClearMsg], ])); } /** * Parses a raw message from Twitch into a message object. * * @param rawLine The raw message line. */ export function parseTwitchMessage(rawLine) { return parseMessage(rawLine, undefined, getTwitchMessageTypes(), true); } export function splitOnSpaces(text, maxMsgLength) { if (text.length <= maxMsgLength) { return [text]; } text = text.trim(); const res = []; let startIndex = 0; let endIndex = maxMsgLength; while (startIndex < text.length) { let spaceIndex = text.lastIndexOf(' ', endIndex); if (spaceIndex === -1 || spaceIndex <= startIndex || text.length - startIndex + 1 <= maxMsgLength) { spaceIndex = startIndex + maxMsgLength; } const textSlice = text.slice(startIndex, spaceIndex).trim(); if (textSlice.length) { res.push(textSlice); } startIndex = spaceIndex + (text[spaceIndex] === ' ' ? 1 : 0); // to skip the space endIndex = startIndex + maxMsgLength; } return res; } /** * Extracts the text to show from a message parameter. * * @param message The message parameter to extract the text from. * * You would usually get this using `msg.params.message` on a message object. */ export function extractMessageText(message) { const ctcp = decodeCtcp(message); if (ctcp && ctcp.command === 'ACTION') { return ctcp.params; } return message; }