Last active
February 2, 2022 08:23
-
-
Save nicholastay/097ea9d54425dba474bf78747d976d56 to your computer and use it in GitHub Desktop.
Twitch Chat History FFZ addon utilising robotty's service (known issue(s): 'chat history ends here' doesnt show properly always, slow loading where new chat messages are above old ones loaded in)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name ChatHistory4FFZ | |
// @namespace nexerqdev | |
// @homepage https://gist.github.com/nicholastay/097ea9d54425dba474bf78747d976d56 | |
// @version 0.1.2 | |
// @description Chat history for FFZ with robotty's service | |
// @author Nexerq <[email protected]> | |
// @license Zlib/libpng | |
// @match *://twitch.tv/* | |
// @match *://www.twitch.tv/* | |
// @grant none | |
// @updateURL https://gist.github.com/nicholastay/097ea9d54425dba474bf78747d976d56/raw/nexerq-message-history-ffz.user.js | |
// ==/UserScript== | |
function waitForFFZ() { | |
console.log("[ChatHistory4FFZ] Looking for FFZ."); | |
let attempts = 0; | |
let interv = setInterval(findFFZ, 750); | |
findFFZ(); | |
function findFFZ() { | |
if (unsafeWindow.FrankerFaceZ) { | |
clearInterval(interv); | |
console.log("[ChatHistory4FFZ] Found FFZ, injecting."); | |
inject(); | |
return; | |
} | |
if (attempts > 10) { | |
clearInterval(interv); | |
console.log("[ChatHistory4FFZ] Could not find FFZ."); | |
return; | |
} | |
++attempts; | |
} | |
} | |
const defaultColours = ["#FF0000", "#0000FF", "#008000", "#B22222", "#FF7F50", "#9ACD32", "#FF4500", "#2E8B57", "#DAA520", "#D2691E", "#5F9EA0", "#1E90FF", "#FF69B4", "#8A2BE2", "#00FF7F"]; | |
function getDefaultUserColour(name) { | |
// users who never set a colour | |
let tname = name.charCodeAt(0) + name.charCodeAt(name.length-1); | |
return defaultColours[tname % defaultColours.length]; | |
} | |
function inject() { | |
let addon = class MsgHistory extends unsafeWindow.FrankerFaceZ.utilities.addon.Addon { | |
constructor(...args) { | |
super(...args); | |
this.inject('chat'); | |
this.settings.add('nexerq.message-history.load_limit', { | |
default: 15, | |
ui: { | |
path: 'Add-Ons > Message History >> Behaviour', | |
title: 'Message Load Limit', | |
description: 'Limit of messages to load from the history API.', | |
component: 'setting-text-box' | |
} | |
}); | |
} | |
onEnable() { | |
this.log.info('Loaded message history FFZ addon.'); | |
this.on('chat:room-add', this.roomAdd); | |
for (const room of this.chat.iterateRooms()) { | |
if (room) | |
this.roomAdd(room); | |
} | |
} | |
roomAdd(room) { | |
this.log.info('Joined room id ' + room.id); | |
this.loadHistory(room); | |
} | |
async loadHistory(room) { | |
this.log.info('Getting chat history: ' + room.login); | |
const sitechat = this.resolve('site.chat'); | |
const chatsvc = sitechat.ChatService.first; | |
const response = await fetch(`https://recent-messages.robotty.de/api/v2/recent-messages/${room.login}?hide_moderation_messages=true&hide_moderated_messages=true&limit=${this.settings.get('nexerq.message-history.load_limit')}`); | |
if (response.ok) { | |
const data = await response.json(); | |
if (data.error !== null) { | |
this.log.info("robotty history error: " + data.error); | |
return; | |
} | |
// parse irc style messages | |
let count = 0; | |
for (const msgdata of data.messages) { | |
const splitmsg = msgdata.split(' '); | |
if (splitmsg[2] !== 'PRIVMSG') | |
continue; | |
let metadata = {}; | |
splitmsg[0].split(';').forEach(data => { | |
const d = data.split('='); | |
metadata[d[0]] = d[1]; | |
}); | |
let msg = { | |
type: sitechat.chat_types.Message, | |
user: { | |
login: splitmsg[1].split('!')[0].substr(1) | |
}, | |
timestamp: Number(metadata['tmi-sent-ts']) | |
}; | |
// add message | |
let messagetext = splitmsg.slice(4).join(' '); | |
if (messagetext[0] === ':') | |
messagetext = messagetext.substr(1); | |
msg.message = messagetext; | |
// add in all the other data | |
msg.user.color = metadata['color'] || getDefaultUserColour(msg.user.login); | |
let dn = metadata['display-name']; | |
if (dn) | |
msg.user.displayName = dn; | |
let badges = metadata['badges']; | |
if (badges) { | |
msg.badges = {} | |
for (let b of badges.split(',')) { | |
let bd = b.split('/'); | |
msg.badges[bd[0]] = bd[1] | |
} | |
} | |
let emotes = metadata['emotes']; | |
if (emotes) { | |
msg.emotes = {} | |
for (let e of emotes.split('/')) { | |
// id:start-end,start-end,.../id:start-end,.../... | |
let eSplit = e.split(':'); | |
for (let idx of eSplit[1].split(',')) { | |
let startIdx = Number(idx.split('-')[0]); | |
msg.emotes[startIdx] = { | |
startIndex: startIdx, | |
id: eSplit[0] // emote id as string is fine | |
}; | |
} | |
} | |
} | |
// parse the emoted msg with ffz | |
sitechat.chat.standardizeEmotes(msg); // inplace standardize | |
msg.messageParts = sitechat.chat.tokenizeMessage(msg); // generate messageparts | |
chatsvc.addMessage(msg); | |
++count; | |
} | |
if (count > 0) { | |
chatsvc.addMessage({ | |
type: sitechat.chat_types.Notice, | |
message: 'Chat history ends here.' | |
}); | |
this.log.info('Loaded ' + count + ' chat history messages.'); | |
} else { | |
this.log.info('No chat history messages to load.') | |
} | |
} else { | |
this.log.info('robotty chat history get failed: ' + response); | |
} | |
} | |
}; | |
let ffz = unsafeWindow.FrankerFaceZ.get(); | |
addon.register('nexerq-message-history', { | |
author: 'Nexerq', | |
description: 'Loads message history using robotty\'s service.', | |
icon: 'https://cdn.frankerfacez.com/badge/2/4/solid', | |
short_name: 'Message History', | |
name: 'Load Message History', | |
website: 'https://recent-messages.robotty.de/', | |
version: '0.1.0' | |
}); | |
ffz.addons._enableAddon('nexerq-message-history'); | |
} | |
waitForFFZ(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment