nmisko / monkalot Goto Github PK
View Code? Open in Web Editor NEWA Twitch Bot for maximum user interaction and chat spam induction.
License: MIT License
A Twitch Bot for maximum user interaction and chat spam induction.
License: MIT License
Emphasize usage as generic twitch bot. Add quick start at the very top, with detailed walk through. Mention Docker option.
Storytime: FeelsBirthdayMan and his brother PogChamp are going to ReykjavÃ�Â�Ã�Â�Ã�Â�Ã�Âk by bus.
ReykjavÃ�Â�Ã�Â�Ã�Â�Ã�Âk is supposed to be Reykjavík (That i is not normal ASCII 'i')
Even after clearing cache.
Today we have a small issue of emote per minute only returns 0
After a brief investigation, it seems that swapDummy stop calling itself ... for unknown reason. (bot/emotecounter.py, in line 78, self.callID = reactor.callLater(1, self.swapDummy, )
)
After restarting, the problem is fixed. However, we should take a note on this.
After installing .NET framework >4.5.1 and C++ v14 and Windows 8.1 SDK on my machine, I can finally install twisted.
After that, I tried to run monaklot.py and I found there more packages are needed.
pip install pyparsing
pip install cleverwrap
pip install colorlog
I think it can be helpful If you can add a small text file suggesting all these packages and those Microsoft things are needed (if you are on Windows).
Now I can try to figure out how to make monkalot works locally ... (Keep seeing "Lose connection, reconnecting" in red now) monkaS
Twitch gets 'unprocessable entity'. Maybe due to user id no longer existing? In that case there are three options:
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/twisted/python/log.py", line 103, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "/usr/local/lib/python3.4/dist-packages/twisted/python/log.py", line 86, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/usr/local/lib/python3.4/dist-packages/twisted/python/context.py", line 122, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/local/lib/python3.4/dist-packages/twisted/python/context.py", line 85, in callWithContext
return func(*args,**kw)
--- ---
File "/usr/local/lib/python3.4/dist-packages/twisted/internet/posixbase.py", line 597, in _doReadOrWrite
why = selectable.doRead()
File "/usr/local/lib/python3.4/dist-packages/twisted/internet/tcp.py", line 208, in doRead
return self._dataReceived(data)
File "/usr/local/lib/python3.4/dist-packages/twisted/internet/tcp.py", line 214, in _dataReceived
rval = self.protocol.dataReceived(data)
File "/usr/local/lib/python3.4/dist-packages/twisted/words/protocols/irc.py", line 2631, in dataReceived
basic.LineReceiver.dataReceived(self, data)
File "/usr/local/lib/python3.4/dist-packages/twisted/protocols/basic.py", line 571, in dataReceived
why = self.lineReceived(line)
File "/home/monkalot/monkalot/bot/multibot_irc_client.py", line 170, in lineReceived
self.twitch_privmsg(user, channel, message, tags)
File "/home/monkalot/monkalot/bot/multibot_irc_client.py", line 77, in twitch_privmsg
b.process_command(name, msg, tag_info)
File "/home/monkalot/monkalot/bot/bot.py", line 325, in process_command
cmd.run(self, user, msg, tag_info)
File "/home/monkalot/monkalot/bot/commands/topspammers.py", line 27, in run
result = ", ".join(["{}: Rank {}".format(bot.getDisplayNameFromID(viewer_id), bot.ranking.getHSRank(point)) for (viewer_id, point) in ranking])
File "/home/monkalot/monkalot/bot/commands/topspammers.py", line 27, in
result = ", ".join(["{}: Rank {}".format(bot.getDisplayNameFromID(viewer_id), bot.ranking.getHSRank(point)) for (viewer_id, point) in ranking])
File "/home/monkalot/monkalot/bot/bot.py", line 607, in getDisplayNameFromID
data = self.getUserDataFromID(user_id)
File "/home/monkalot/monkalot/bot/bot.py", line 509, in getUserDataFromID
data = self.getJSONObjectFromTwitchAPI(url)
File "/home/monkalot/monkalot/bot/bot.py", line 498, in getJSONObjectFromTwitchAPI
raise e
File "/home/monkalot/monkalot/bot/bot.py", line 490, in getJSONObjectFromTwitchAPI
r.raise_for_status()
File "/usr/lib/python3/dist-packages/requests/models.py", line 825, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 422 Client Error: Unprocessable Entity
Move current version to 1.0
So while looking through the code in commands.py
I noticed we are using almost the exact same commands to check the conditions in match()
. It starts with msg.startswith("!cmd ")
and then sometimes have additional conditions like "The second word has to be an emote." / "The line can only contain 3 words.", etc. Some of these condition checks can get a little messy and we are basicly repeating code with different values.
My idea is to use a standardized 'condition - line' method. First we use a function that parses the written line and extracts all the information available (number of words, text for each word, is the word a number/emote?, etc). Then we define specific condition for each class/function ("First word has to be '!', second word has to be an emote, etc.). And finaly have a function that returns wether the line matches the condition for the class or not.
Write functions that can give you information about a written line.
!<cmd>
)line = {
"n": "n-words",
"length": "length-line",
"words": [["text": text1, "type": type1, "length": length1], ["text": text2, …], …]
}
2.) Then we can define condition for the command. E.g.:
(Should probably have a better structure)
condition = [
[0, {"text": "!call"}], -> "First word is '!call'."
[1, {"type": ["emote", "emoji"]}, <- Should be able to handle multiple conditions
[3, {"length": "< 10"}, -> "Third word is shorter than 10 letters."
[n, "< 10"]
]
3.) Then in match()
we can go like:
if check_match(line, cond):
return True
Instead of making the check for each condition in the match function. It would make the transition from the wording "The second word needs to be a number." into actual conditions easier/more standardized.
Unhandled Error
Traceback (most recent call last):
File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
self.run()
File "/usr/lib/python3.4/threading.py", line 868, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.4/dist-packages/twisted/_threads/_threadworker.py", line 46, in work
task()
File "/usr/local/lib/python3.4/dist-packages/twisted/_threads/_team.py", line 190, in doWork
task()
--- ---
File "/usr/local/lib/python3.4/dist-packages/twisted/python/threadpool.py", line 250, in inContext
result = inContext.theWork()
File "/usr/local/lib/python3.4/dist-packages/twisted/python/threadpool.py", line 266, in
inContext.theWork = lambda: context.call(ctx, func, *args, **kw)
File "/usr/local/lib/python3.4/dist-packages/twisted/python/context.py", line 122, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/local/lib/python3.4/dist-packages/twisted/python/context.py", line 85, in callWithContext
return func(*args,**kw)
File "/home/monkalot/monkalot/bot/commands/speech.py", line 27, in getReply
bot.write("@" + user + " " + output)
builtins.TypeError: Can't convert 'NoneType' object to str implicitly
Check whether it's necessary.
Since I have no Cleverbot API Key, output in command.py:1173 will be None and crash afterwards.
Should I just get one API Key to continue testing, or are there any workaround?
I just think that if we are using more API keys, the setup of testing environment will be much more difficult too...
One smaller issue: def setResponses() in bot.py:62 seems never executed (only 1 line can be found by git grep setRes), no need to comment that out?
Lastly ... this is my first coding project in github. I am not sure if I am doing it right or not. Hope that I have not been very annoying or very noobish.
Currently counted emotes are written to a file. Instead, they should be written to a database. Make the database connection shared between all commands, so new commands can use it as well.
"alexander_of_greece got 1st place with 3 points and get 50 extra spampoints! PogChamp Clap"
should be gets instead of get
I have that error when I try to start monkalot. I can't see anywhere to give the port parameter to TwitchBot.
I have to manually add
self.port = None
before
if self.port is not None:
to prevent the error. Any ideas? Or do I setup anything wrong?
I start without inputting a port since I don't plan to use web service in my test run, not sure if related or not.
Fix floating point calculations
When a port is already in use, the bot starts anyway. It should not.
The !rank command doesn't work on its own, typing !rank doesn't give your rank, but if you type !rank username it does work
Wed Dec 27 17:00:01 CET 2017 Unhandled Error Traceback (most recent call last): File "/usr/local/lib/python3.4/dist-packages/twisted/words/protocols/irc.py", line 2631, in dataReceived basic.LineReceiver.dataReceived(self, data) File "/usr/local/lib/python3.4/dist-packages/twisted/protocols/basic.py", line 571, in dataReceived why = self.lineReceived(line) File "/home/monkalot/monkalot/bot/multibot_irc_client.py", line 169, in lineReceived super().lineReceived(line) File "/usr/local/lib/python3.4/dist-packages/twisted/words/protocols/irc.py", line 2644, in lineReceived self.handleCommand(command, prefix, params) --- <exception caught here> --- File "/usr/local/lib/python3.4/dist-packages/twisted/words/protocols/irc.py", line 2699, in handleCommand method(prefix, params) File "/usr/local/lib/python3.4/dist-packages/twisted/words/protocols/irc.py", line 2056, in irc_PRIVMSG self.privmsg(user, channel, message) File "/home/monkalot/monkalot/bot/multibot_irc_client.py", line 67, in privmsg b.process_command(name, msg) File "/home/monkalot/monkalot/bot/bot.py", line 287, in process_command cmd.run(self, user, msg) File "/home/monkalot/monkalot/bot/commands/pyramid.py", line 48, in run if msg == self.pyramidLevel(self.currentEmote, self.count) and (self.currentEmote in self.emotes or self.currentEmote in self.emojis or bot.accessToEmote(user, self.currentEmote)): File "/home/monkalot/monkalot/bot/bot.py", line 501, in accessToEmote emotelist = self.getuserEmotes(userID) File "/home/monkalot/monkalot/bot/bot.py", line 486, in getuserEmotes data = self.getJSONObjectFromTwitchAPI(url) File "/home/monkalot/monkalot/bot/bot.py", line 432, in getJSONObjectFromTwitchAPI raise e File "/home/monkalot/monkalot/bot/bot.py", line 424, in getJSONObjectFromTwitchAPI r.raise_for_status() File "/usr/lib/python3/dist-packages/requests/models.py", line 825, in raise_for_status raise HTTPError(http_error_msg, response=self) requests.exceptions.HTTPError: 401 Client Error: Unauthorized
Create tickets instead.
I just put Monkalot to sleep using !sleep. Now !wakeup isn't working, and she isn't responding to me.
That happened yesterday too, Zetalot was able to wake the bot this morning but mods couldn't
Traceback (most recent call last):
File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
self.run()
File "/usr/lib/python3.4/threading.py", line 868, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.4/dist-packages/twisted/_threads/_threadworker.py", line 46, in work
task()
File "/usr/local/lib/python3.4/dist-packages/twisted/_threads/_team.py", line 190, in doWork
task()
--- <exception caught here> ---
File "/usr/local/lib/python3.4/dist-packages/twisted/python/threadpool.py", line 250, in inContext
result = inContext.theWork()
File "/usr/local/lib/python3.4/dist-packages/twisted/python/threadpool.py", line 266, in <lambda>
inContext.theWork = lambda: context.call(ctx, func, *args, **kw)
File "/usr/local/lib/python3.4/dist-packages/twisted/python/context.py", line 122, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/usr/local/lib/python3.4/dist-packages/twisted/python/context.py", line 85, in callWithContext
return func(*args,**kw)
File "/home/monkalot/monkalot/bot/commands/speech.py", line 51, in answer
output = output + " monkaS"
builtins.TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Use different string formatting that allows concatenation of None
and str
.
And maybe look for reason why None was returned.
Currently there's a separate Thread for the webserver. Shutting down the bot (via ctrl-c), doesn't kill this seperate thread.
Should probably moved into utility folder.
When a new (bttv) emote gets added, it doesn't get counted, meaning its counter is always 0.
Expected behaviour: In regular intervals, new emotes should be added to the count list.
Right now we use: he, him, his as default
And for females we have set: she, her, hers
in pronouns.json
But that's not correct, for example in: "/me holds in <u_pronoun2> arms. They are finally happy."
For male it is: "/me Aenduil holds Zetalot in his arms. They are finally happy."
For female: "/me Igetnokick holds Zetalot in hers arms. They are finally happy."
The pronouns should be:
He, him, his, his, himself
She, her, her, hers, herself
First:
i'm testing it right now since my streamer is live these hours and i triggered !pstart
The party started and there was a riddle which answer was OSkomodo but:
i mean isn't it updating for actual twitch emotes everytime i start it up?
Also would it be possible to rename all "Monkalot" word and put our bot name in batch? (this has low priority)
About quotes: if i type !quote all the quotes are from Zetalot as this bot was born for him. So is there a way to overwrite this quotes or just add more?for ex cmd like !addquote or !quoteadd would be good as well as !editquote or !quoteedit...
Second:
also !active command doesn't output anything:
Third:
Is there a chance to have a !hint command for every !*start ? like for ex !pstart it output like a capital of some country and almost nobody as a clue so a !hint might be very useful like outputting the number of letters in _____ and like a letter in it like i_ . Might be more letters if another !hint command is triggered for like 2 or more suggested letters for the full answer.
Forth:
just found this:
Thanks in advance!
!pstart isn't working today, the game starts, but not questions are posted, pstop works to stop the game
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.