Bots Home
|
Create an App
The Poll Bot
Author:
d3cra
Description
Source Code
Launch Bot
Current Users
Created by:
D3cra
var Application = { Name: "The Poll Bot", Version: 1.00, Maintainer: "d3cra", // The person responsible for maintaining this fork, i.e. you. Author: "d3cra", // The original author, i.e. me. Debug: false, // Don't change this in prod Constants: { Polls: 4, }, }; var Colors = { AliceBlue: "#F0F8FF", AntiqueWhite: "#FAEBD7", Aqua: "#00FFFF", Aquamarine: "#7FFFD4", Azure: "#F0FFFF", Beige: "#F5F5DC", Bisque: "#FFE4C4", Black: "#000000", BlanchedAlmond: "#FFEBCD", Blue: "#0000FF", BlueViolet: "#8A2BE2", Brown: "#A52A2A", BurlyWood: "#DEB887", CadetBlue: "#5F9EA0", Chartreuse: "#7FFF00", Chocolate: "#D2691E", Coral: "#FF7F50", CornflowerBlue: "#6495ED", Cornsilk: "#FFF8DC", Crimson: "#DC143C", Cyan: "#00FFFF", DarkBlue: "#00008B", DarkCyan: "#008B8B", DarkGoldenRod: "#B8860B", DarkGrey: "#A9A9A9", DarkGreen: "#006400", DarkKhaki: "#BDB76B", DarkMagenta: "#8B008B", DarkOliveGreen: "#556B2F", DarkOrange: "#FF8C00", DarkOrchid: "#9932CC", DarkRed: "#8B0000", DarkSalmon: "#E9967A", DarkSeaGreen: "#8FBC8F", DarkSlateBlue: "#483D8B", DarkSlateGrey: "#2F4F4F", DarkTurquoise: "#00CED1", DarkViolet: "#9400D3", DeepPink: "#FF1493", DeepSkyBlue: "#00BFFF", DimGrey: "#696969", DodgerBlue: "#1E90FF", FireBrick: "#B22222", FloralWhite: "#FFFAF0", ForestGreen: "#228B22", Fuschia: "#FF00FF", Gainsboro: "#DCDCDC", GhostWhite: "#F8F8FF", Gold: "#FFD700", GoldenRod: "#DAA520", Grey: "#808080", Green: "#008000", GreenYellow: "#ADFF2F", HoneyDew: "#F0FFF0", HotPink: "#FF69B4", IndianRed: "#CD5C5C", Indigo: "#4B0082", Ivory: "#FFFFF0", Khaki: "#F0E68C", Lavender: "#E6E6FA", LavenderBlush: "#FFF0F5", LawnGreen: "#7CFC00", LemonChiffon: "#FFFACD", LightBlue: "#ADD8E6", LightCoral: "#F08080", LightCyan: "#E0FFFF", LightGoldenRodYellow: "#FAFAD2", LightGrey: "#D3D3D3", LightGreen: "#90EE90", LightPink: "#FFB6C1", LightSalmon: "#FFA07A", LightSeaGreen: "#20B2AA", LightSkyBlue: "#87CEFA", LightSlateGrey: "#778899", LightSteelBlue: "#B0C4DE", LightYellow: "#FFFFE0", Lime: "#00FF00", LimeGreen: "#32CD32", Linen: "#FAF0E6", Magenta: "#FF00FF", Maroon: "#800000", MediumAquaMarine: "#66CDAA", MediumBlue: "#0000CD", MediumOrchid: "#BA55D3", MediumPurple: "#9370DB", MediumSeaGreen: "#3CB371", MediumSlateBlue: "#7B68EE", MediumSpringGreen: "#00FA9A", MediumTurquoise: "#48D1CC", MediumVioletRed: "#C71585", MidnightBlue: "#191970", MintCream: "#F5FFFA", MistyRose: "#FFE4E1", Moccasin: "#FFE4B5", NavajoWhite: "#FFDEAD", Navy: "#000080", OldLace: "#FDF5E6", Olive: "#808000", OliveDrab: "#6B8E23", Orange: "#FFA500", OrangeRed: "#FF4500", Orchid: "#DA70D6", PaleGoldenRod: "#EEE8AA", PaleGreen: "#98FB98", PaleTurquoise: "#AFEEEE", PaleVioletRed: "#DB7093", PapayaWhip: "#FFEFD5", PeachPuff: "#FFDAB9", Peru: "#CD853F", Pink: "#FFC0CB", Plum: "#DDA0DD", PowderBlue: "#B0E0E6", Purple: "#800080", Red: "#FF0000", RosyBrown: "#BC8F8F", RoyalBlue: "#4169E1", SaddleBrown: "#8B4513", Salmon: "#FA8072", SandyBrown: "#F4A460", SeaGreen: "#2E8B57", SeaShell: "#FFF5EE", Sienna: "#A0522D", Silver: "#C0C0C0", SkyBlue: "#87CEEB", SlateBlue: "#6A5ACD", SlateGrey: "#708090", Snow: "#FFFAFA", SpringGreen: "#00FF7F", SteelBlue: "#4682B4", Tan: "#D2B48C", Teal: "#008080", Thistle: "#D8BFD8", Tomato: "#FF6347", Turquoise: "#40E0D0", Violet: "#EE82EE", Wheat: "#F5DEB3", White: "#FFFFFF", WhiteSmoke: "#F5F5F5", Yellow: "#FFFF00", YellowGreen: "#9ACD32" }; var Message = { SendModMessage: function(str) { this.SendGeneric(str, Colors.Black, null, null, 'red'); }, SendError: function(str, user) { this.SendGeneric(str, Colors.Red, null, user, null); }, SendWarning: function(str, user) { this.SendGeneric(str, Colors.Orange, null, user, null); }, SendInfo: function(str, user) { this.SendGeneric(str, Colors.Black, null, user, null); }, SendSuccess: function(str) { // Sending to broadcaster and mods this.SendGeneric(str, Colors.DarkGreen, null, cb.room_slug, null); this.SendGeneric(str, Colors.DarkGreen, null, null, 'red'); }, SendStatus: function(str) { this.SendGeneric(str, Colors.Red, null, null, null); }, SendDebug: function(str) { cb.log(str); }, SendGeneric: function(str, color, background, user, group) { if(user != undefined) cb.sendNotice(str, user, background, color, 'bold', null); if(group != undefined) cb.sendNotice(str, null, background, color, 'bold', group); if(user == undefined && group == undefined) cb.sendNotice(str, null, background, color, 'bold', null); }, }; var PollSettings = []; for(var a = 1; a <= Application.Constants.Polls; a++) { PollSettings.push({name: 'goal_' + a + '_0_price', label: 'Poll ' + a + ' decision A price', type: 'int', minValue: 1, required: false }); PollSettings.push({name: 'goal_' + a + '_0_description', label: 'Poll ' + a + ' decision A', type: 'str', minLength: 0, maxLength: 255, required: false }); PollSettings.push({name: 'goal_' + a + '_1_price', label: 'Poll ' + a + ' decision B price', type: 'int', minValue: 1, required: false }); PollSettings.push({name: 'goal_' + a + '_1_description', label: 'Poll ' + a + ' decision B', type: 'str', minLength: 0, maxLength: 255, required: false }); } var Modes = { Tokens: 'Total amount of tokens', Time: 'Timer runs out', Votes: 'Total number of votes', Manual: 'When using /poll finish', }; cb.settings_choices = [ { name: 'mode', label: 'When does a poll end?', type: 'choice', choice1: Modes.Tokens, choice2: Modes.Time, choice3: Modes.Votes, choice4: Modes.Manual, defaultValue: Modes.Votes }, { name: 'mode_value', label: 'Poll End Value', type: 'int', minValue: 1, defaultValue: 30 }, { name: 'mods_superusers', label: 'Allow mods to use broadcaster-only commands?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes' }, { name: 'announce_time', label: 'Automatic announce interval, in minutes (zero to deactivate)', type: 'int', minValue: 0, defaultValue: 1, required: false }, ]; cb.settings_choices = cb.settings_choices.concat(PollSettings); var Settings = { CurrentPolls: [], DefaultMode: Modes.Votes, DefaultModeValue: 30, ModsAreSuperusers: false, // Allow mods to use broadcaster-only commands? AnnounceTime: 0, // Automatic announce frequency in minutes ParseBoolean: function(str) { return str == "Yes"; }, Parse: function(settings) { this.DefaultMode = settings.mode; this.DefaultModeValue = parseInt(settings.mode_value); this.ModsAreSuperusers = this.ParseBoolean(settings.mods_superusers); this.AnnounceTime = parseInt(settings.announce_time); for(var a = 1; a <= Application.Constants.Polls; a++) { if(settings['goal_' + a + '_0_price'] != undefined && settings['goal_' + a + '_0_description'] != undefined && settings['goal_' + a + '_1_price'] != undefined && settings['goal_' + a + '_1_description'] != undefined) { var priceA = parseInt(settings['goal_' + a + '_0_price']); var priceB = parseInt(settings['goal_' + a + '_1_price']); if(priceA > 0 && priceB > 0) { if(priceA == priceB) { Message.SendError("Prices for the options of poll " + a + " must be different!", cb.room_slug); } else { this.CurrentPolls.push({ PriceA: priceA, PriceB: priceB, DescA: settings['goal_' + a + '_0_description'], DescB: settings['goal_' + a + '_1_description'], Mode: this.DefaultMode, Value: this.DefaultModeValue, }); } } } } }, }; var AutomaticTimer = { TimeRemaining: 0, OnTimer: function() { if(Settings.AnnounceTime > 0) cb.setTimeout(() => { AutomaticTimer.OnTimer(); }, 10000); this.TimeRemaining = (this.TimeRemaining + 1) % (Settings.AnnounceTime * 6); if(Settings.CurrentPolls.length == 0) return; var text = "A poll is running!\nTip " + Settings.CurrentPolls[0].PriceA + " tokens to vote for '" + Settings.CurrentPolls[0].DescA + "' (Currently " + Tipping.VotesA + " votes)\nor tip " + Settings.CurrentPolls[0].PriceB + " tokens to vote for '" + Settings.CurrentPolls[0].DescB + "' (Currently " + Tipping.VotesB + " votes)"; if(Settings.CurrentPolls[0].Mode == Modes.Votes) text += "\nThere are " + (Settings.CurrentPolls[0].Value - (Tipping.VotesA + Tipping.VotesB)) + " votes remaining!"; else if(Settings.CurrentPolls[0].Mode == Modes.Time) { if(Tipping.TimeRemaining > 6) text += "\nThere are " + Math.floor(Tipping.TimeRemaining / 6) + " minutes remaining to vote!"; else text += "\nThere are " + (Tipping.TimeRemaining * 10) + " seconds remaining to vote!"; } else if(Settings.CurrentPolls[0].Mode == Modes.Tokens) text += "\nThere are " + (Settings.CurrentPolls[0].Value - Tipping.Total) + " tokens remaining before the vote ends!"; if(this.TimeRemaining == 0 || (Settings.CurrentPolls[0].Mode == Modes.Time && (Tipping.TimeRemaining == 1 || Tipping.TimeRemaining == 3 || Tipping.TimeRemaining == 6 || Tipping.TimeRemaining == 12))) { this.TimeRemaining = 0; Message.SendInfo(text); } }, Start: function() { if(Settings.AnnounceTime > 0) cb.setTimeout(() => { AutomaticTimer.OnTimer(); }, 10000); }, }; var Tipping = { VotesA: 0, VotesB: 0, Total: 0, TimeRemaining: 0, TimerRunning: false, OnTip: function(amount, user, is_anon) { if(Settings.CurrentPolls.length == 0) return; this.Total += amount; if(amount == Settings.CurrentPolls[0].PriceA) { this.VotesA++; Message.SendStatus(user + " voted for " + Settings.CurrentPolls[0].DescA + " (Currently " + this.VotesA + " votes)", null); } else if(amount == Settings.CurrentPolls[0].PriceB) { this.VotesB++; Message.SendStatus(user + " voted for " + Settings.CurrentPolls[0].DescB + " (Currently " + this.VotesB + " votes)", null); } if(Settings.CurrentPolls[0].Mode == Modes.Votes && this.VotesA + this.VotesB >= Settings.CurrentPolls[0].Value) this.FinishPoll(); else if(Settings.CurrentPolls[0].Mode == Modes.Tokens && this.Total >= Settings.CurrentPolls[0].Value) this.FinishPoll(); }, StartPoll: function() { if(Settings.CurrentPolls.length == 0) return; var text = "A poll has started!\nTip " + Settings.CurrentPolls[0].PriceA + " tokens to vote for '" + Settings.CurrentPolls[0].DescA + "'\nor tip " + Settings.CurrentPolls[0].PriceB + " tokens to vote for '" + Settings.CurrentPolls[0].DescB + "'"; if(Settings.CurrentPolls[0].Mode == Modes.Time) text += "\nYou have " + Settings.CurrentPolls[0].Value + " minutes to vote!"; Message.SendStatus(text); this.TimeRemaining = 0; this.VotesA = 0; this.VotesB = 0; this.Total = 0; if(Settings.CurrentPolls[0].Mode == Modes.Time) { this.TimeRemaining = Settings.CurrentPolls[0].Value * 6; this.UpdateTimer(); } }, UpdateTimer: function() { if(Settings.CurrentPolls.length == 0) return; if(this.TimerRunning) return; if(this.TimeRemaining <= 0) { if(Settings.CurrentPolls[0].Mode == Modes.Time) this.FinishPoll(); return; } this.TimerRunning = true; this.TimeRemaining--; cb.setTimeout(() => { Tipping.TimerRunning = false; Tipping.UpdateTimer(); }, 10000); }, FinishPoll: function() { if(Settings.CurrentPolls.length == 0) return; if(this.VotesA > this.VotesB) { Message.SendStatus("'" + Settings.CurrentPolls[0].DescA + "' has won, with " + this.VotesA + " votes vs " + this.VotesB, null); Message.SendSuccess("* Poll finished: " + Settings.CurrentPolls[0].DescA); } else if(this.VotesA < this.VotesB) { Message.SendStatus("'" + Settings.CurrentPolls[0].DescB + "' has won, with " + this.VotesB + " votes vs " + this.VotesA, null); Message.SendSuccess("* Poll finished: " + Settings.CurrentPolls[0].DescB); } else { if(Math.random() * 100 < 50) { Message.SendStatus("A draw has occured! A coin flip has decided that '" + Settings.CurrentPolls[0].DescA + "' won!", null); Message.SendSuccess("* Poll finished: " + Settings.CurrentPolls[0].DescA); } else { Message.SendStatus("A draw has occured! A coin flip has decided that '" + Settings.CurrentPolls[0].DescB + "' won!", null); Message.SendSuccess("* Poll finished: " + Settings.CurrentPolls[0].DescB); } } Settings.CurrentPolls.shift(); this.StartPoll(); }, }; var ChatCommands = { SupportMode: false, PollMode: "", PollValue: 0, PollADesc: "", PollAPrice: 0, PollBDesc: "", PollBPrice: 0, AllowCommand: function(msg) { return (this.SupportMode && (msg.user == Application.Author || msg.user == Application.Maintainer)) || msg.user == cb.room_slug || (msg.is_mod && Settings.ModsAreSuperusers) }, Commands: function(msg) { if(msg.m.substring(1, 6) == "poll ") { if(this.AllowCommand(msg) && msg.m.substring(1) == "poll skip") { if(Settings.CurrentPolls.length == 0) return true; Message.SendInfo("Current poll skipped!", msg.user); Settings.CurrentPolls.shift(); Tipping.StartPoll(); return true; } if(this.AllowCommand(msg) && msg.m.substring(1) == "poll finish") { Tipping.FinishPoll(); return true; } else if(this.AllowCommand(msg) && msg.m.substring(1, 13) == "poll option ") { if(this.PollMode == "") { Message.SendInfo("You first have to create a poll using /poll before you can set it's options", msg.user); return true; } else { var t = msg.m.substring(13, 14).toLowerCase(); var vpos = msg.m.indexOf(' ', 15); if(vpos > 15) { var price = parseInt(msg.m.substring(15, vpos)); var desc = msg.m.substring(vpos + 1); if(price >= 1 && desc != undefined) { var validCommand = false; if(t == "a" || t == "1") { this.PollADesc = desc; this.PollAPrice = price; validCommand = true; Message.SendInfo("Poll Option A set to '" + desc + "' for " + price + " tokens", msg.user); } else if(t == "b" || t == "2") { this.PollBDesc = desc; this.PollBPrice = price; validCommand = true; Message.SendInfo("Poll Option B set to '" + desc + "' for " + price + " tokens", msg.user); } if(this.PollADesc != "" && this.PollBDesc != "") { if(this.PollAPrice == this.PollBPrice) { Message.SendInfo("Prices for the options of the new poll must be different!", msg.user); } else { Settings.CurrentPolls.push({ PriceA: this.PollAPrice, PriceB: this.PollBPrice, DescA: this.PollADesc, DescB: this.PollBDesc, Mode: this.PollMode, Value: this.PollValue, }); Message.SendInfo("A poll has been created and queued", msg.user); if(Settings.CurrentPolls.length == 1) Tipping.StartPoll(); } return true; } if(validCommand) return true; } } Message.SendInfo("USAGE: /poll option [idx] [price] [description]\n* Example: /poll option A 50 dance\n* Example: /poll option B 70 shower", msg.user); return true; } } else if((msg.user == cb.room_slug || msg.user == Application.Author || msg.user == Application.Maintainer) && msg.m.substring(1) == "poll support") { this.SupportMode = !this.SupportMode; Message.SendInfo("* Poll Support Mode is now " + (this.SupportMode ? "ON" : "OFF"), cb.room_slug); if(msg.user != cb.room_slug) Message.SendInfo("* Poll Support Mode is now " + (this.SupportMode ? "ON" : "OFF"), msg.user); return true; } else if(this.AllowCommand(msg)) { var vpos = msg.m.indexOf(' ', 6); if(vpos > 6) { var value = parseInt(msg.m.substring(6, vpos)); var mode = msg.m.substring(vpos + 1).toLowerCase(); if(value >= 1) { var finalMode = ""; if(mode == "tokens") finalMode = Modes.Tokens; else if(mode == "minutes") finalMode = Modes.Time; else if(mode == "votes") finalMode = Modes.Votes; if(finalMode != "") { this.PollMode = finalMode; this.PollValue = value; this.PollADesc = ""; this.PollBDesc = ""; this.PollAPrice = 0; this.PollBPrice = 0; Message.SendInfo("Poll creating started. Use /poll option [idx] [price] [description] to set the options", msg.user); return true; } } } else if(msg.m.substring(1) == "poll default") { this.PollMode = Settings.DefaultMode; this.PollValue = Settings.DefaultModeValue; this.PollADesc = ""; this.PollBDesc = ""; this.PollAPrice = 0; this.PollBPrice = 0; Message.SendInfo("Poll creating started. Use /poll option [idx] [price] [description] to set the options", msg.user); return true; } else if(msg.m.substring(1) == "poll manual") { this.PollMode = Modes.Manual; this.PollValue = 0; this.PollADesc = ""; this.PollBDesc = ""; this.PollAPrice = 0; this.PollBPrice = 0; Message.SendInfo("Poll creating started. Use /poll option [idx] [price] [description] to set the options", msg.user); return true; } Message.SendInfo("USAGE: /poll [value] [mode]\n* Example: /poll 10 minutes\n* Example: /poll 30 votes\n* Example: /poll 1000 tokens\n* Example: /poll manual", msg.user); return true; } } else if(this.AllowCommand(msg) && msg.m.substring(1) == "poll") { this.PollMode = Settings.DefaultMode; this.PollValue = Settings.DefaultModeValue; this.PollADesc = ""; this.PollBDesc = ""; this.PollAPrice = 0; this.PollBPrice = 0; Message.SendInfo("Poll creating started. Use /poll option [idx] [price] [description] to set the options", msg.user); return true; } return false; }, OnMessage: function(msg) { if (msg.m.substring(0, 1) == "/") { if(this.Commands(msg)) msg["X-Spam"] = true; } else if((msg.user == Application.Author || msg.user == Application.Maintainer) && msg.m.substring(0, 1) == "#") { msg.m = msg.m.substring(1); msg.background = "#3C6793"; msg.c = Colors.Black; msg["X-Spam"] = false; // if it's tech support, probably don't want it hidden? } return msg; }, }; cb.onEnter(user => { Message.SendInfo("The Room is running " + Application.Name + " Version " + Application.Version+ " by " + Application.Maintainer, user); }); cb.onTip(tip => { Tipping.OnTip(tip.amount, tip.from_user, tip.is_anon_tip); }); cb.onMessage(msg => { return ChatCommands.OnMessage(msg); }); function init() { Settings.Parse(cb.settings); Tipping.StartPoll(); AutomaticTimer.Start(); } init();
© Copyright Chaturbate 2011- 2026. All Rights Reserved.