southclaws / cj Goto Github PK
View Code? Open in Web Editor NEWCJ is a Discord bot that hangs around in the open.mp/burgershot.gg community discord.
License: GNU General Public License v3.0
CJ is a Discord bot that hangs around in the open.mp/burgershot.gg community discord.
License: GNU General Public License v3.0
From @Crayder: When a news item is posted, CJ can echo it to @everyone
in the primary channel.
This is an easy one:
Commands should be rate limited in:
This can either be per-user or global but generally follows this structure:
map[string]int
value for the command authorint
for the botWe should organize all commands on classes and handle them dynamically in a function when a message is received. For example every command class should be like this
type CommandName struct {}
func (c *CommandName) Name() string {
return "command_name"
}
func (c *CommandName) Description() string {
return "description"
}
func (c *CommandName) Usage() string {
return "usage"
}
func (c *PollCommand) Process() {
}
When someone type a command without parameters CJ won't return the commands usage.
For some reason, requests to the forum are timing out:
{
"level": "error",
"ts": "2018-12-05T07:33:18.640Z",
"caller": "bot/discord.go:119",
"msg": "unhandled error from OnMessage",
"error": "failed to get HTML root for user page: failed to perform request for https://forum.sa-mp.com/member.php?u=140150: Get https://forum.sa-mp.com/member.php?u=140150: failed to create new roundtrip from given transport: dial tcp 54.39.167.47:443: i/o timeout",
"errorVerbose": "Get https://forum.sa-mp.com/member.php?u=140150: failed to create new roundtrip from given transport: dial tcp 54.39.167.47:443: i/o timeout\nfailed to perform request for https://forum.sa-mp.com/member.php?u=140150\ngithub.com/Southclaws/cj/forum.(*ForumClient).GetHTMLRoot\n\t/cj/forum/html.go:19\ngithub.com/Southclaws/cj/forum.(*ForumClient).GetUserProfilePage\n\t/cj/forum/forum.go:53\ngithub.com/Southclaws/cj/bot/commands.(*CommandManager).UserConfirmsProfile\n\t/cj/bot/commands/cmd_verify.go:212\ngithub.com/Southclaws/cj/bot/commands.(*CommandManager).commandVerify\n\t/cj/bot/commands/cmd_verify.go:61\ngithub.com/Southclaws/cj/bot/commands.(*CommandManager).commandVerify-fm\n\t/cj/bot/commands/all_commands.go:22\ngithub.com/Southclaws/cj/bot/commands.(*CommandManager).OnMessage\n\t/cj/bot/commands/command_manager.go:135\ngithub.com/Southclaws/cj/bot.(*App).onMessage\n\t/cj/bot/discord.go:117\ngithub.com/Southclaws/cj/bot.(*App).onMessage-fm\n\t/cj/bot/discord.go:33\ngithub.com/bwmarrin/discordgo.messageCreateEventHandler.Handle\n\t/go/pkg/mod/github.com/bwmarrin/[email protected]/eventhandlers.go:497\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1333\nfailed to get HTML root for user page\ngithub.com/Southclaws/cj/forum.(*ForumClient).GetUserProfilePage\n\t/cj/forum/forum.go:55\ngithub.com/Southclaws/cj/bot/commands.(*CommandManager).UserConfirmsProfile\n\t/cj/bot/commands/cmd_verify.go:212\ngithub.com/Southclaws/cj/bot/commands.(*CommandManager).commandVerify\n\t/cj/bot/commands/cmd_verify.go:61\ngithub.com/Southclaws/cj/bot/commands.(*CommandManager).commandVerify-fm\n\t/cj/bot/commands/all_commands.go:22\ngithub.com/Southclaws/cj/bot/commands.(*CommandManager).OnMessage\n\t/cj/bot/commands/command_manager.go:135\ngithub.com/Southclaws/cj/bot.(*App).onMessage\n\t/cj/bot/discord.go:117\ngithub.com/Southclaws/cj/bot.(*App).onMessage-fm\n\t/cj/bot/discord.go:33\ngithub.com/bwmarrin/discordgo.messageCreateEventHandler.Handle\n\t/go/pkg/mod/github.com/bwmarrin/[email protected]/eventhandlers.go:497\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1333",
"stacktrace": "github.com/Southclaws/cj/bot.(*App).onMessage\n\t/cj/bot/discord.go:119\ngithub.com/Southclaws/cj/bot.(*App).onMessage-fm\n\t/cj/bot/discord.go:33\ngithub.com/bwmarrin/discordgo.messageCreateEventHandler.Handle\n\t/go/pkg/mod/github.com/bwmarrin/[email protected]/eventhandlers.go:497"
}
failed to get HTML root for user page:
failed to perform request for https://forum.sa-mp.com/member.php?u=140150:
Get https://forum.sa-mp.com/member.php?u=140150:
failed to create new roundtrip from given transport:
dial tcp 54.39.167.47:443: i/o timeout
Get https://forum.sa-mp.com/member.php?u=140150: failed to create new roundtrip from given transport: dial tcp 54.39.167.47:443: i/o timeout
failed to perform request for https://forum.sa-mp.com/member.php?u=140150
github.com/Southclaws/cj/forum.(*ForumClient).GetHTMLRoot
/cj/forum/html.go:19
github.com/Southclaws/cj/forum.(*ForumClient).GetUserProfilePage
/cj/forum/forum.go:53
github.com/Southclaws/cj/bot/commands.(*CommandManager).UserConfirmsProfile
/cj/bot/commands/cmd_verify.go:212
github.com/Southclaws/cj/bot/commands.(*CommandManager).commandVerify
/cj/bot/commands/cmd_verify.go:61
github.com/Southclaws/cj/bot/commands.(*CommandManager).commandVerify-fm
/cj/bot/commands/all_commands.go:22
github.com/Southclaws/cj/bot/commands.(*CommandManager).OnMessage
/cj/bot/commands/command_manager.go:135
github.com/Southclaws/cj/bot.(*App).onMessage
/cj/bot/discord.go:117
github.com/Southclaws/cj/bot.(*App).onMessage-fm
/cj/bot/discord.go:33
github.com/bwmarrin/discordgo.messageCreateEventHandler.Handle
/go/pkg/mod/github.com/bwmarrin/discordgo@v0.19.0/eventhandlers.go:497
runtime.goexit
/usr/local/go/src/runtime/asm_amd64.s:1333
failed to get HTML root for user page
github.com/Southclaws/cj/forum.(*ForumClient).GetUserProfilePage
/cj/forum/forum.go:55
github.com/Southclaws/cj/bot/commands.(*CommandManager).UserConfirmsProfile
/cj/bot/commands/cmd_verify.go:212
github.com/Southclaws/cj/bot/commands.(*CommandManager).commandVerify
/cj/bot/commands/cmd_verify.go:61
github.com/Southclaws/cj/bot/commands.(*CommandManager).commandVerify-fm
/cj/bot/commands/all_commands.go:22
github.com/Southclaws/cj/bot/commands.(*CommandManager).OnMessage
/cj/bot/commands/command_manager.go:135
github.com/Southclaws/cj/bot.(*App).onMessage
/cj/bot/discord.go:117
github.com/Southclaws/cj/bot.(*App).onMessage-fm
/cj/bot/discord.go:33
github.com/bwmarrin/discordgo.messageCreateEventHandler.Handle
/go/pkg/mod/github.com/bwmarrin/discordgo@v0.19.0/eventhandlers.go:497
runtime.goexit
/usr/local/go/src/runtime/asm_amd64.s:1333
github.com/Southclaws/cj/bot.(*App).onMessage
/cj/bot/discord.go:119
github.com/Southclaws/cj/bot.(*App).onMessage-fm
/cj/bot/discord.go:33
github.com/bwmarrin/discordgo.messageCreateEventHandler.Handle
/go/pkg/mod/github.com/bwmarrin/discordgo@v0.19.0/eventhandlers.go:497
From the administration channel, a command to speak on behalf of CJ would be fun.
Verify
was seen as an unknown command, it should be normalised to verify
internally.
This should be easy to implement inside bot_private.go
by just converting the first word of message.Content
to lowercase.
This would make parsing commands with arguments much easier!
I am not very sure about this but maybe u can try.
[19:00] coool: /whois @nigglypuff
[19:00] BOTCJ: You need to mention someone to use this command.%!(EXTRA string=%s)
What about u change line 75
to
ErrorMessage: app.locale.GetLangString("en", "CommandErrorNoMention"),
just like the others? As /userinfo
displays it without
[11:58] michaelbelgium: /userinfo bla
[11:58] BOTCJ: You need to mention someone to use this command.
Allow experienced users to register as "helpers".
If these users are in the "online" state (not "busy" or otherwise) and someone asks a question in the "scripting" channel, CJ should post a list of available "helper" users who may be able to help.
Otherwise, if everyone who is a registered helper is offline, CJ could let the user know that helpers are offline and their question may not be answered and, if no one does answer it, they should try again another time.
Question detection should be a simple matter of checking for question words, question marks or common words found in questions such as "anyone" or "can someone".
Cooldown on this feature is important, a good 10 minutes or so between.
The heartbeat is a function that fires every X minutes, my plan was to grab some context of the current conversation (if any) and try to generate a fun message related to that conversation - no crazy analytics, just a little keyword lookup with some contextual preset message types such as bringing up forum stats for a user if people are talking about the forum or stats or post count.
Another use for this would be to remind users of bot functionality, with a list of settable messages such as "If you are unverified, please verify your account by messaging 'verify' to me!" or "You can verify a user's SA-MP forum account by typing /verify @discord_username
" etc.
/userinfo DobbysGamertag
<@%!s(MISSING)>, you need to mention someone to use this command.
Seems like if there's no @ tag it errors out.
Dependabot can't resolve your Go dependency files.
As a result, Dependabot couldn't update your dependencies.
The error Dependabot encountered was:
go: golang.org/x/[email protected]: unknown revision 2491c5de3490
If you think the above is an error on Dependabot's side please don't hesitate to get in touch - we'll do whatever we can to fix it.
You can mention @dependabot in the comments below to contact the Dependabot team.
Since the bot is logging all chat, a common IRC feature will be easy to implement: random quote from a user from the past. These kinds of things should be on a cooldown or require some kind of currency to use however to prevent spam.
A fun and simple chat-bot feature often seen in IRC and Twitter bots:
Oh each chat message, run a stop-word removal and N-gram extractor over the contents of the text. Cache the result and flush the cache to an N-gram table every now and then.
Sentences can be generated from the N-gram table, either with a simple weighted selection with N words or with a more complex stop-word insertion method to build more legible sentences - probably out of the scope of this but the stop-word insertion could be trained on sentence samples very easily.
I actually plan to use Spacy for this task and delegate the actual sentence generation to an external app that will "top up" the database with new sentences every now and then (again, it doesn't need to be frequent and can depend on the usage rate). With Spacy, I'll run POS tagging over the N-grams to help build more legible sentences with basic logical structures.
Regression in df4a23c
We all know whoever posts the spiciest meme gets the most reactions. Let's count them.
Since there isn't a gateway event for reaction creation (as far as I can see) this one will need to be a polling function that grabs the last X messages and counts reactions for them and distributes the score to the relevant users.
Now users can spam '/whois' and similar mentioning commands for user info, then they can delete their messages, so CJ will look bugged/creepy if you forget that users can delete their posts. Solutions to this (I don't know if they are possible):
1 or 3 would be awesome if possible, 2 is pretty noobish and would look pretty bad.
P.S.: CJ you busta
In the future, I would like to add the ability to translate the bot via simple text files if the need arises.
Just to keep things super simple:
main
Since most messages don't include formatting or only a single format specifier, there won't be any issues with article ordering (like the "Spanish dog black" problem and associated issues with localisation!)
/whois @Southclaws
> "[HLF]Southclaw"
/whois @UnverifiedUser
> "That user is not verified"
This could probably be tied into #18 as an option for commands, /whois would be a "variadic" command that takes between 1 and n parameters whereas /say would take exactly 1 parameter.
Should be quite easy for anyone who has used RESTful APIs before:
http://api.samp.southcla.ws/v2/stats
(dependent on Southclaws/samp-servers-api#9)This feature depends on the v2 milestone being completed, merged and deployed: https://github.com/Southclaws/announce-backend/milestones/1
Line 238 in e160b22
Instead of checking the entire page for changes, it should only check the element that contains posts (XPath //*[@id="inlinemodform"]
) so it doesn't capture updates from other sources resulting in false positives.
And, if the page is being parsed, may as well add a link to the new post itself rather than just the post list.
For this, you'll need to parse the HTML in a similar way that the other forum features work. This is a useful function for starting off and you can read some of the code around here to get an idea of how it uses an XPath to identify a specific element. After that, it's simply a case of producing a hash of the contents, that's up to you!
[1:51 PM] Codeah: @Southclaws Add a command to make CJ construct stories using /impersonate with different users
[1:51 PM] Southclaws: ok
[1:52 PM] Codeah: Woah
[1:52 PM] Southclaws: move the existing /impersonate code into a function, then just make a /story command that calls it in a loop 10 times
[1:52 PM] Southclaws: with Username: message format
[1:52 PM] Southclaws: EZ PZ
Another fun feature to see how "salty" different people get!
Just like the Markov generator, using Spacy/Textacy/NLTK, an external app will calculate an average phrase sentiment for each user and expose a command to the primary channel where users can query other user's sentiment to see how much of what they say is perceived as positive or negative.
e.g. /whois Freaksken
, /whois @Freaksken
or /wiki whatever
.
This would reduce the CJ spam a bit.
Hey man, I did a suggestion for CJ bot but idk if you saw it.
The suggestion is create a /wiki command and make the bot return a link to http://wiki.sa-mp.com/wiki/Parameter
E.g.:
(user command)
/wiki onplayerd(bot messages, limit of matches is 3)
NPC:OnPlayerDeath http://wiki.sa-mp.com/wiki/NPC:OnPlayerDeath
OnPlayerDeath http://wiki.sa-mp.com/wiki/OnPlayerDeath
OnPlayerDisconnect http://wiki.sa-mp.com/wiki/OnPlayerDisconnectI did an example of how it should work (I know you can do it, I'm using it to learn Go by the first time!):
https://gist.github.com/Renato-Garcia/97c62f4b55db3d2bcfceddbda87710d1
Possible solution: https://github.com/cardigann/go-cloudflare-scraper
To any forum mods reading this: CJ is very low-impact, probably produces far less traffic than an average user so I believe circumventing Cloudflare is okay - if not, drop a message here. On Discord, we use CJ to validate that a given Discord user is who they say they are to avoid the drama of impersonation. It also provides a few neat features such as user lookups, reputation and post counts.
Suggested by justice96.
Use: https://github.com/urShadow/go-samp-query
fuck cooldowns
Hey,
Would be cool if one could link his own GitHub to CJ, so that others can instantly look up the work that someone has done (published os).
regards Marcel
Call to GuildMemberRoleAdd
results in: "unknown role", cause unknown.
The app can't seem to read it in the container so a full path would be useful.
When a user is kicked, they lose the verified
role and when they rejoin they can't join channels and they can't use the verify
command because they are still verified in the database.
Solution would be to either
verified
role to new users if they exist in the databaseverified
role when a user leaves the server (either through kick or voluntarily)We had a problem today with some toxic users, 'general' channel was set for only verified members (atm), but some of these users have new fresh accounts and got verified rank. The idea is block very new forum accounts, maybe 1 month be enough. It will prevent toxic users.
If the output of /impersonate produces another /impersonate command, then it looks like that command will execute too (operators exempt from cooldown?). This may get progressively worse as more and more people use the command.
Requires some xpath/web scraping knowledge:
When a user has more than 1000 posts it will fail to convert it to an integer because the comma.
@Southclaws's profile:
What CJ return when someone execute /userinfo:
Username: [HLF]Southclaw Member since: 22/04/2009 Total posts: 0 Reputation: 1204
How should already verified users be handled? @Southclaws
Specifically for stuff like /whois /userinfo
When a new thread is posted in the includes, filterscripts, or plugins section CJ can announce it in #releases
I think it'd be nice to have this but it should be restricted somehow... Perhaps only for people with a certain amount of rep (nothing big)? I just don't think it'd be right to announce ALL releases...
I want to move away from SQLite just so I have a bit more flexibility with the data.
I'm thinking either Postgres or MongoDB...
The whole "primary" and "admin" channel thing is really restrictive. I also don't want to hard-code channel IDs into the code.
A solution to this would be to create a collection with a single object that would be configuration for commands.
This would allow runtime modification of:
And probably more, maybe even per-command stuff.
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.