mirror of
https://github.com/LBRYFoundation/lbry-wunderbot.git
synced 2025-08-23 09:37:27 +00:00
Uploaded the main code!
Uploaded the main sourcecode and some unfinished commands!
This commit is contained in:
parent
6d68fc6657
commit
288e166f20
14 changed files with 2263 additions and 1 deletions
3
.babelrc
Normal file
3
.babelrc
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"presets": ["node8"]
|
||||
}
|
63
.gitignore
vendored
Normal file
63
.gitignore
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# dist
|
||||
dist/*
|
||||
#configuration
|
||||
config/default.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
26
README.md
26
README.md
|
@ -1 +1,25 @@
|
|||
Will be updated with the new wunderbot when changes have been reviewed.
|
||||
# Bot for [LBRY's Discord](https://discord.gg/tgnNHf5)
|
||||
(This README will be updated along with bot updates)
|
||||
Features:
|
||||
|
||||
- Tipbot for LBC. Responds to `!tip`.
|
||||
- Dynamic plugin loading with permission support.
|
||||
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
- node > 8.0.0
|
||||
- npm > 0.12.x
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
Create a bot and get the bot's API Token: https://discordapp.com/developers/applications/me
|
||||
|
||||
Edit and rename default.json.example in /config, then run:
|
||||
|
||||
```
|
||||
npm install
|
||||
node bot.js
|
||||
```
|
193
bot/bot.js
Normal file
193
bot/bot.js
Normal file
|
@ -0,0 +1,193 @@
|
|||
'use strict';
|
||||
|
||||
// Load up libraries
|
||||
const Discord = require("discord.js");
|
||||
// Load config!
|
||||
let config = require('config');
|
||||
config = config.get('bot');
|
||||
|
||||
var aliases;
|
||||
try {
|
||||
aliases = require("./alias.json");
|
||||
} catch (e) {
|
||||
//No aliases defined
|
||||
aliases = {
|
||||
"test": {
|
||||
process: function(bot,msg){
|
||||
msg.channel.send('test');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var commands = {
|
||||
ping: {
|
||||
description: "responds pong, useful for checking if bot is alive",
|
||||
process: async function(bot, msg, suffix) {
|
||||
let m = await msg.channel.send(msg.author + " Ping?");
|
||||
m.edit(
|
||||
`Pong! Latency is ${m.createdTimestamp -
|
||||
msg.createdTimestamp}ms. API Latency is ${Math.round(bot.ping)}ms`
|
||||
);
|
||||
if (suffix) {
|
||||
msg.channel.send("note that !ping takes no arguments!");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var bot = new Discord.Client();
|
||||
|
||||
bot.on("ready", function() {
|
||||
console.log(
|
||||
"Logged in! Serving in " + bot.guilds.array().length + " servers"
|
||||
);
|
||||
require("./plugins.js").init();
|
||||
console.log("type " + config.prefix + "help in Discord for a commands list.");
|
||||
bot.user.setGame(
|
||||
config.prefix + "help | Tipping not available"
|
||||
);
|
||||
});
|
||||
|
||||
bot.on("disconnected", function() {
|
||||
console.log("Disconnected!");
|
||||
process.exit(1); //exit node.js with an error
|
||||
});
|
||||
|
||||
function checkMessageForCommand(msg, isEdit) {
|
||||
//check if message is a command
|
||||
if (msg.author.id != bot.user.id && msg.content.startsWith(config.prefix)) {
|
||||
console.log(
|
||||
"treating " + msg.content + " from " + msg.author + " as command"
|
||||
);
|
||||
var cmdTxt = msg.content.split(" ")[0].substring(config.prefix.length);
|
||||
var suffix = msg.content.substring(
|
||||
cmdTxt.length + config.prefix.length + 1
|
||||
); //add one for the ! and one for the space
|
||||
if (msg.isMentioned(bot.user)) {
|
||||
try {
|
||||
cmdTxt = msg.content.split(" ")[1];
|
||||
suffix = msg.content.substring(
|
||||
bot.user.mention().length + cmdTxt.length + config.prefix.length + 1
|
||||
);
|
||||
} catch (e) {
|
||||
//no command
|
||||
msg.channel.send("Yes?");
|
||||
return;
|
||||
}
|
||||
}
|
||||
let alias = aliases[cmdTxt];
|
||||
if (alias) {
|
||||
var cmd = alias;
|
||||
} else {
|
||||
var cmd = commands[cmdTxt];
|
||||
}
|
||||
if (cmdTxt === "help") {
|
||||
//help is special since it iterates over the other commands
|
||||
if (suffix) {
|
||||
var cmds = suffix.split(" ").filter(function(cmd) {
|
||||
return commands[cmd];
|
||||
});
|
||||
var info = "";
|
||||
for (var i = 0; i < cmds.length; i++) {
|
||||
var cmd = cmds[i];
|
||||
info += "**" + config.prefix + cmd + "**";
|
||||
var usage = commands[cmd].usage;
|
||||
if (usage) {
|
||||
info += " " + usage;
|
||||
}
|
||||
var description = commands[cmd].description;
|
||||
if (description instanceof Function) {
|
||||
description = description();
|
||||
}
|
||||
if (description) {
|
||||
info += "\n\t" + description;
|
||||
}
|
||||
info += "\n";
|
||||
}
|
||||
msg.channel.send(info);
|
||||
} else {
|
||||
msg.author.send("**Available Commands:**").then(function() {
|
||||
var batch = "";
|
||||
var sortedCommands = Object.keys(commands).sort();
|
||||
for (var i in sortedCommands) {
|
||||
var cmd = sortedCommands[i];
|
||||
var info = "**" + config.prefix + cmd + "**";
|
||||
var usage = commands[cmd].usage;
|
||||
if (usage) {
|
||||
info += " " + usage;
|
||||
}
|
||||
var description = commands[cmd].description;
|
||||
if (description instanceof Function) {
|
||||
description = description();
|
||||
}
|
||||
if (description) {
|
||||
info += "\n\t" + description;
|
||||
}
|
||||
var newBatch = batch + "\n" + info;
|
||||
if (newBatch.length > 1024 - 8) {
|
||||
//limit message length
|
||||
msg.author.send(batch);
|
||||
batch = info;
|
||||
} else {
|
||||
batch = newBatch;
|
||||
}
|
||||
}
|
||||
if (batch.length > 0) {
|
||||
msg.author.send(batch);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (cmd) {
|
||||
// Add permission check here later on ;)
|
||||
try {
|
||||
cmd.process(bot, msg, suffix, isEdit);
|
||||
} catch (e) {
|
||||
var msgTxt = "command " + cmdTxt + " failed :(";
|
||||
if (config.debug) {
|
||||
msgTxt += "\n" + e.stack;
|
||||
}
|
||||
msg.channel.send(msgTxt);
|
||||
}
|
||||
} else {
|
||||
msg.channel
|
||||
.send(cmdTxt + " not recognized as a command!")
|
||||
.then(message => message.delete(5000));
|
||||
}
|
||||
} else {
|
||||
//message isn't a command or is from us
|
||||
//drop our own messages to prevent feedback loops
|
||||
if (msg.author == bot.user) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.author != bot.user && msg.isMentioned(bot.user)) {
|
||||
msg.channel.send("yes?"); //using a mention here can lead to looping
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot.on("message", msg => checkMessageForCommand(msg, false));
|
||||
bot.on("messageUpdate", (oldMessage, newMessage) => {
|
||||
checkMessageForCommand(newMessage, true);
|
||||
});
|
||||
|
||||
exports.addCommand = function(commandName, commandObject) {
|
||||
try {
|
||||
commands[commandName] = commandObject;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
};
|
||||
exports.addCustomFunc = function(customFunc) {
|
||||
try {
|
||||
customFunc(bot);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
exports.commandCount = function() {
|
||||
return Object.keys(commands).length;
|
||||
};
|
||||
|
||||
bot.login(config.token);
|
11
bot/helpers.js
Normal file
11
bot/helpers.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
let config = require('config');
|
||||
let permRanks = config.get('moderation');
|
||||
|
||||
// Checks if user is allowed to use a command only for mods/team members
|
||||
exports.hasPerms = function(msg){
|
||||
if(message.member.roles.some(r=>permRanks.perms.includes(r.name)) ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
22
bot/modules/example.js
Normal file
22
bot/modules/example.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
exports.commands = [
|
||||
"demo" // command that is in this file, every command needs it own export as shown below
|
||||
]
|
||||
|
||||
exports.custom = [
|
||||
"initFunction"
|
||||
]
|
||||
|
||||
exports.demo = {
|
||||
usage: "<subcommand>",
|
||||
description: 'description of command',
|
||||
process: function(bot,msg,suffix){
|
||||
// Here the bot,msg and suffix is avaible, this function can be async if needed.
|
||||
}
|
||||
}
|
||||
|
||||
exports.initFunction = function(bot) {
|
||||
// Other functions that needs to be ran once on bootup!
|
||||
// For example a timed function and or some init stuff..
|
||||
}
|
||||
*/
|
15
bot/modules/moderation.js
Normal file
15
bot/modules/moderation.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*'use strict';
|
||||
// Moderation module, handles banning and kicking and more...
|
||||
let hasPerms = require('../helpers.js').hasPerms;
|
||||
|
||||
exports.commands = [
|
||||
"m"
|
||||
]
|
||||
|
||||
exports.m = {
|
||||
usage: "<subcommand> <reason>",
|
||||
description: 'ban: bans the user with the reason\n kick: get adress for your deposits\n',
|
||||
process: function(bot,msg,suffix){
|
||||
console.log(msg.member.user);
|
||||
}
|
||||
}*/
|
21
bot/modules/reminder.js
Normal file
21
bot/modules/reminder.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*exports.commands = [
|
||||
"remind" // command that is in this file, every command needs it own export as shown below
|
||||
]
|
||||
|
||||
exports.custom = [
|
||||
"checkReminders"
|
||||
]
|
||||
|
||||
exports.remind = {
|
||||
usage: "<time> <message>",
|
||||
description: 'description of command',
|
||||
process: async function(bot,msg,suffix){
|
||||
console.log(suffix);
|
||||
// Here the bot,msg and suffix is avaible, this function can be async if needed.
|
||||
}
|
||||
}
|
||||
|
||||
exports.checkReminders = function(bot) {
|
||||
// Other functions that needs to be ran once on bootup!
|
||||
// For example a timed function and or some init stuff..
|
||||
}*/
|
18
bot/modules/speech.js
Normal file
18
bot/modules/speech.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*'use strict';
|
||||
|
||||
exports.commands = [
|
||||
"speech"
|
||||
]
|
||||
|
||||
exports.init = function(bot){
|
||||
console.log(bot);
|
||||
}
|
||||
|
||||
exports.speech = {
|
||||
usage: "<claim>",
|
||||
description: 'Speech coming soon...',
|
||||
process: function(bot,msg,suffix){
|
||||
console.log(msg.member.user);
|
||||
}
|
||||
}
|
||||
*/
|
17
bot/modules/tipbot.js
Normal file
17
bot/modules/tipbot.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
'use strict';
|
||||
|
||||
const bitcoin = require('bitcoin');
|
||||
let config = require('config');
|
||||
config = config.get('lbrycrd');
|
||||
const lbry = new bitcoin.Client(config);
|
||||
|
||||
exports.commands = [
|
||||
"tip"
|
||||
]
|
||||
exports.tip = {
|
||||
usage: "<subcommand>",
|
||||
description: 'balance: get your balance\n deposit: get adress for your deposits\n withdraw ADDRESS AMOUNT: withdraw AMOUNT credits to ADDRESS\n <user> <amount>: mention a user with @ and then the amount to tip them',
|
||||
process: async function(bot,msg,suffix){
|
||||
return; // Tipping is now handled by the separate tipbot(in branch tipbot_dc), no need to to anything here...
|
||||
}
|
||||
}
|
47
bot/plugins.js
Normal file
47
bot/plugins.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
const fs = require("fs"),
|
||||
path = require("path");
|
||||
|
||||
function getPlugins(srcpath) {
|
||||
return fs.readdirSync(srcpath);
|
||||
}
|
||||
let plugin_directory = path.join(__dirname, "modules");
|
||||
let plugins = getPlugins(plugin_directory);
|
||||
|
||||
exports.init = function init() {
|
||||
load_plugins();
|
||||
};
|
||||
|
||||
function load_plugins() {
|
||||
const dbot = require("./bot.js");
|
||||
let commandCount = 0;
|
||||
let otherFunc = 0;
|
||||
for (let i = 0; i < plugins.length; i++) {
|
||||
let plugin;
|
||||
try {
|
||||
plugin = require(`${plugin_directory}/${plugins[i]}`);
|
||||
} catch (err) {
|
||||
console.log(`Improper setup of the '${plugins[i]}' plugin. : ${err}`);
|
||||
}
|
||||
if (plugin) {
|
||||
if ("commands" in plugin) {
|
||||
for (let j = 0; j < plugin.commands.length; j++) {
|
||||
if (plugin.commands[j] in plugin) {
|
||||
dbot.addCommand(plugin.commands[j], plugin[plugin.commands[j]]);
|
||||
commandCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if("custom" in plugin){
|
||||
for (let j = 0; j < plugin.custom.length; j++) {
|
||||
if (plugin.custom[j] in plugin) {
|
||||
dbot.addCustomFunc(plugin[plugin.custom[j]]);
|
||||
otherFunc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(`Loaded ${dbot.commandCount()} chat commands and ${otherFunc} custom functions.`);
|
||||
}
|
20
config/default.json.example
Normal file
20
config/default.json.example
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
// Bot configuration
|
||||
"bot": {
|
||||
"token":"discordbottoken",
|
||||
"prefix": "!",
|
||||
"debug": false
|
||||
},
|
||||
"lbrycrd": {
|
||||
"port": 9245,
|
||||
"user": "lbry",
|
||||
"pass": "lbry"
|
||||
},
|
||||
"mongodb": {
|
||||
"url":"mongodb://localhost:27017/wunderbot"
|
||||
},
|
||||
"moderation":{
|
||||
"perms": ["LBRY MODS","LBRY TEAM"], // Roles that have access to all commands.
|
||||
"logchannel": "371620338263523328" // Channel to log the bots moderation..
|
||||
}
|
||||
}
|
32
package.json
Normal file
32
package.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-preset-node8": "^1.2.0",
|
||||
"bitcoin": "^3.0.1",
|
||||
"chrono-node": "^1.3.5",
|
||||
"config": "^1.27.0",
|
||||
"discord.js": "^11.2.1",
|
||||
"embed-creator": "^1.1.4",
|
||||
"jsonpath": "^0.2.12",
|
||||
"moment": "^2.19.1",
|
||||
"mongoose": "^4.12.3",
|
||||
"node-config": "^0.0.2",
|
||||
"numeral": "^2.0.6",
|
||||
"request": "^2.83.0"
|
||||
},
|
||||
"scripts": {
|
||||
"prettier": "prettier * --write",
|
||||
"build": "babel bot -d dist",
|
||||
"prod": "babel bot -d dist & node dist/bot.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "1.7.4"
|
||||
},
|
||||
"name": "wunderbot-discord",
|
||||
"version": "0.0.1",
|
||||
"description": "LBRYs bot for Discord",
|
||||
"main": "app.js",
|
||||
"repository": "https://github.com/filipnyquist/wunderbot-disc",
|
||||
"author": "filipnyquist <filip@lbry.io>",
|
||||
"license": "MIT"
|
||||
}
|
Loading…
Add table
Reference in a new issue