Greasy Fork is available in English.
View the interaction count of unlisted characters
// ==UserScript==
// @name CAI Unlisted Interactions
// @namespace Violentmonkey Scripts
// @match https://beta.character.ai/chat*
// @grant none
// @license MIT
// @version 1.0
// @author A. Nonymous
// @description View the interaction count of unlisted characters
// ==/UserScript==
'use strict';
const CHARACTER_INFO_ENDPOINT = 'https://beta.character.ai/chat/character/info';
const INTERACTION_ICON = ' <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 512 512" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg" style="margin-left: 0px; --darkreader-inline-fill:currentColor; --darkreader-inline-stroke:currentColor;" data-darkreader-inline-fill="" data-darkreader-inline-stroke=""><path fill="none" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M431 320.6c-1-3.6 1.2-8.6 3.3-12.2a33.68 33.68 0 012.1-3.1A162 162 0 00464 215c.3-92.2-77.5-167-173.7-167-83.9 0-153.9 57.1-170.3 132.9a160.7 160.7 0 00-3.7 34.2c0 92.3 74.8 169.1 171 169.1 15.3 0 35.9-4.6 47.2-7.7s22.5-7.2 25.4-8.3a26.44 26.44 0 019.3-1.7 26 26 0 0110.1 2l56.7 20.1a13.52 13.52 0 003.9 1 8 8 0 008-8 12.85 12.85 0 00-.5-2.7z"></path><path fill="none" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M66.46 232a146.23 146.23 0 006.39 152.67c2.31 3.49 3.61 6.19 3.21 8s-11.93 61.87-11.93 61.87a8 8 0 002.71 7.68A8.17 8.17 0 0072 464a7.26 7.26 0 002.91-.6l56.21-22a15.7 15.7 0 0112 .2c18.94 7.38 39.88 12 60.83 12A159.21 159.21 0 00284 432.11"></path></svg> '
// Format the interaction count
const formatInteractions = (count) => {
if (count < 1000) {
return count;
} else if (count < 1000000) {
return (count / 1000).toFixed(1).toString() + ' k';
}
return (count / 1000000).toFixed(1).toString() + ' m';
};
// Display the interaction count at the top of the chat
const displayInteractions = (count) => {
let interactions = formatInteractions(count);
let titleElements = document.getElementsByClassName('chattitle');
const tryAppend = () => {
let titleElement = titleElements[0];
if (!titleElement) {
// Probably should use mutation observers
setTimeout(tryAppend, 500);
return;
}
// Assemble the interaction counter
let countSpan = document.createElement('span');
countSpan.className = 'text-secondary';
countSpan.innerHTML = INTERACTION_ICON;
countSpan.appendChild(document.createTextNode(interactions));
countSpan.style.cssText = 'font-weight:400;font-size:12px;';
// Append it
titleElement.appendChild(countSpan);
};
tryAppend();
};
(() => {
let originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async) {
// Intercept requests to the character info endpoint
if (url.startsWith(CHARACTER_INFO_ENDPOINT)) {
this.addEventListener('load', () => {
// Parse the character info and display an interaction counter if
// the character is unlisted.
let info = JSON.parse(this.responseText);
if (info.character.visibility === 'UNLISTED') {
displayInteractions(info.character.participant__num_interactions);
}
});
}
originalOpen.apply(this, [method, url, async]);
};
})();