Skip to content

Instantly share code, notes, and snippets.

@mapoman
Forked from michaelowens/README.md
Last active June 15, 2021 14:29
Show Gist options
  • Save mapoman/428f05a5f8d3d4164f2e58f0ad0f8b7d to your computer and use it in GitHub Desktop.
Save mapoman/428f05a5f8d3d4164f2e58f0ad0f8b7d to your computer and use it in GitHub Desktop.
Channel Points + Twitch Commands : Pyramid generator and more, channel points monitor

NOTE (2.13.20) - Planning to investigate why commands don't work and fix that, the channel points are functional however

Twitch Commands

Chat commands for Twitch, with a Channel Points auto clicker.

Install

Current commands

/tccommands
Lists all available commands

/brainpower
> O-oooooooooo AAAAE-A-A-I-A-U- JO-oooooooooooo AAE-O-A-A-U-U-A- E-eee-ee-eee AAAAE-A-E-I-E-A-JO-ooo-oo-oo-oo EEEEO-A-AAA-AAAA

/rainbow <message>
e.g. /rainbow Hello
Will change your username color and send the message 6 times

/pyramid <size> <emoticon>
e.g. /pyramid 3 Kappa
> Kappa
> Kappa Kappa
> Kappa Kappa Kappa
> Kappa Kappa
> Kappa

Changelog

0.6

  • Add support for FFZ autocomplete info

0.5

  • Fixed issue with slow pyramids & rainbow for mods

0.4

  • Refactored to only work with FFZ, which gives the best stability
  • Renamed /commands to /tccommands

0.3

  • Fixed an issue where script would not work, because it couldn't find chat textarea at start

0.2

  • Added server messages when incorrect usage of command
  • New command: /commands

0.1

  • Initial version with /brainpower, /rainbow and /pyramid
// ==UserScript==
// @name Twitch Commands
// @homepage https://gist.github.com/mapoman/428f05a5f8d3d4164f2e58f0ad0f8b7d/
// @version 0.7
// @description Adds commands to twitch chat! Install FFZ & TamperMonkey first, then install script.
// @author Xikeon (Michael Owens)
// @match *://twitch.tv/*
// @match *://www.twitch.tv/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @updateURL https://gist.githubusercontent.com/michaelowens/2eb554f8eba0e89d2ea24e67ebc7ae96/raw/twitchcommands.user.js
// ==/UserScript==
/* jshint esnext:true, asi:true, -W097 */
/* globals $ */
var interval;
var cp_rcount = 0;
var sech_start = 0;
var cp_namelength = 0;
var lasttime = 0;
'use strict';
$(document).ready(function() {
// registers function to poll for interactive channel points elements
setTimeout(function() {
// runs 10 seconds after page load so that chat and html elements have time to load in
var d1 = new Date();
var time1 = d1.toLocaleTimeString().toLowerCase();
console.log('[mmp]loading...' + time1);
try {
var mmpobj = $('.community-points-summary .tw-tooltip');
var mmpstr = '';
if (mmpobj[0]) {
mmpstr = mmpobj[0].innerText;
} else {
mmpstr = mmpobj.innerText;
}
//console.log(mmpstr);
for (var i = 0; i < mmpstr.length; i++) {
if (mmpstr.charAt(i) >= '0' && mmpstr.charAt(i) <= '9') {} else {
if (mmpstr.charAt(i) !== ',') {
cp_namelength = mmpstr.length - i;
break;
}
}
}
sech_start = parseInt(mmpstr.substring(0, cp_namelength).replace(/,/g, ''));
console.log('[mmp]session start:' + sech_start);
} catch (e) {}
var ele = $('.community-points-summary');
if (ele && ele.is(":visible")) {
if (!interval) {
console.log('[mmp]set interval');
interval = setInterval(function() {
var ele2 = $('.tw-button--success');
if (ele2 && ele2.is(":visible")) {
var d = new Date();
if (d.getTime() - lasttime > 60000) {
cp_rcount++;
//var variance = ((d.getTime() - lasttime)/900000).toPrecision(6);
var currecho = 0;
try {
//var str = $('.community-points-summary .tw-tooltip')[0].innerText;
var strobj = $('.community-points-summary .tw-tooltip');
var str = '';
if (strobj[0]) {
str = strobj[0].innerText;
} else {
str = strobj.innerText;
}
currecho = parseInt(str.substring(0, str.length - cp_namelength).replace(/,/g, ''));
} catch (e) {}
var time = d.toLocaleTimeString().toLowerCase();
lasttime = d.getTime();
console.log(`[mmp]redeemed at ${time} (count ${cp_rcount} - gain ${currecho-sech_start})`);
ele2.click();
}
}
}, 1312);
}
}
}, 10000);
});
class TwitchCommands {
constructor () {
this.loaded = false
this.$chat = $('.chat_text_input')
this.timeStarted = +new Date()
this.forceStart = false
this.FFZ = false
this.log('Injected')
this.waitForFFZ()
}
log (...params) {
console.log('[mmp]', ...params)
}
waitForFFZ () {
let secondsSinceStart = ((+new Date()) - this.timeStarted) / 1000
if (typeof unsafeWindow.FrankerFaceZ === 'function') {
this.FFZ = true
this.log('FFZ detected')
this.bindToChatFFZ()
this.setAutocompleteInfo()
return
} else if (secondsSinceStart > 10 && this.$chat.length) {
this.log('Could not detect FFZ.')
return
}
setTimeout(_ => this.waitForFFZ(), 500)
}
bindToChatFFZ () {
this.getCommands()
.forEach(command => {
let name = command.replace('command_', '')
unsafeWindow.FrankerFaceZ.chat_commands[name] = this[command].bind(this)
})
}
setAutocompleteInfo() {
let cc = unsafeWindow.FrankerFaceZ.chat_commands
cc.tccommands.label = '/tccommands'
cc.tccommands.info = 'Show commands added by Twitch Commands'
cc.pyramid.label = '/pyramid &lt;size&gt; &lt;emote&gt;'
cc.pyramid.info = 'Make a pyramid of the given size and emote'
cc.rainbow.label = '/rainbow &lt;message&gt;'
cc.rainbow.info = 'Spam given message in rainbow colors'
cc.brainpower.label = '/brainpower'
cc.brainpower.info = 'Sends the brainpower meme'
}
getCommands () {
return Object.getOwnPropertyNames(Object.getPrototypeOf(this)).filter(name => name.indexOf('command_') === 0)
}
getTimeBetweenMessages (e) {
return this.isModeratorOrHigher(e) ? 100 : 1500
}
isModeratorOrHigher (e) {
return e && e.room.get('isModeratorOrHigher')
}
command_tccommands () {
let commands = this.getCommands().map(name => '/' + name.replace('command_', ''))
return `Twitch Commands: ${commands.join(', ')}`
}
command_pyramid (e, params) {
var size = 0
var emote = ''
if (!params || params.length < 2) {
return 'Example usage: /pyramid 3 FrankerZ'
}
[size, emote] = params
if (size < 2) {
return 'Pyramid can\'t be smaller than 2 emoticons'
}
for (let i = 1; i < (size * 2); i++) {
setTimeout(_ => {
let n = (i > size) ? (size * 2) - i : i
e.room.send((emote + ' ').repeat(n))
}, ((i - 1) * this.getTimeBetweenMessages(e)))
}
}
command_rainbow (e, params) {
if (!params || !params.length) {
return 'Example usage: /rainbow SUB HYPE'
}
const colors = ['#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#0000FF', '#4B0082'],
originalColor = e.room.chatColor,
timeBetween = this.isModeratorOrHigher(e) ? 300 : 1500
let i = 0
for (let color of colors) {
setTimeout(_ => {
e.room.send(`/color ${color}`)
setTimeout(_ => {
e.room.send(`/me ${params.join(' ')}`)
}, this.isModeratorOrHigher(e) ? 150 : 500)
}, i * timeBetween)
i++
}
setTimeout(_ => {
e.room.send(`/color ${originalColor}`)
}, (i * timeBetween) + 1000)
}
command_brainpower (e) {
e.room.send('O-oooooooooo AAAAE-A-A-I-A-U- JO-oooooooooooo AAE-O-A-A-U-U-A- E-eee-ee-eee AAAAE-A-E-I-E-A-JO-ooo-oo-oo-oo EEEEO-A-AAA-AAAA')
}
}
new TwitchCommands()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment