diff --git a/changelog.md b/changelog.md index 15eee16..120a2fd 100644 --- a/changelog.md +++ b/changelog.md @@ -12,3 +12,8 @@ - Fix various search result issues - Only DM help if list - Other discord.js updates + +### 2.2.0: March 24, 2020 +- Add #number references for pull requests and issues +- Add ~pr command for searching pull requests +- Add ~issue command for searching issues \ No newline at end of file diff --git a/commands/issue.js b/commands/issue.js new file mode 100644 index 0000000..36012e2 --- /dev/null +++ b/commands/issue.js @@ -0,0 +1,7 @@ +const {gitHubSearchCommand} = require("../common.js"); +module.exports = gitHubSearchCommand({ + name: "issue", + aliases: ["bug", "problem", "request"], + usage: "", + description: "Search Minetest issues on GitHub", +}, "issue"); diff --git a/commands/pull.js b/commands/pull.js new file mode 100644 index 0000000..04644a6 --- /dev/null +++ b/commands/pull.js @@ -0,0 +1,7 @@ +const {gitHubSearchCommand} = require("../common.js"); +module.exports = gitHubSearchCommand({ + name: "pull", + aliases: ["pr"], + usage: "", + description: "Search Minetest pull requests on GitHub" +}, "pr"); diff --git a/common.js b/common.js new file mode 100644 index 0000000..5ec0125 --- /dev/null +++ b/common.js @@ -0,0 +1,45 @@ +const {color} = require("./config.js"); +const max_length = 256; +const {MessageEmbed} = require("discord.js"); +const request = require("request"); + +function sendGitHubEmbedReply(message, issue) { + let embed = new MessageEmbed(); + embed.setURL(issue.html_url); + embed.setTitle(`**${issue.title.trim()}**`); + embed.setAuthor(issue.user.login, issue.user.avatar_url, issue.user.html_url); + embed.setDescription((issue.body.length > max_length) ? issue.body.substring(0, 256 - 3).trim() + "..." : issue.body); + embed.setColor(color); + const matches = issue.body.match(/!\[.*\]\((http.*)\)/); + if (matches) { + embed.setImage(matches[1]); + } + embed.setFooter((issue.pull_request ? "Pull Request" : "Issue") + " #" + issue.number, "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png") + message.channel.send({ + embed: embed + }); +} + +function gitHubSearchCommand(def, type) { + def.execute = function(message, args) { + if (args.length === 0) { + message.channel.send({embed: {color: color, title: "Empty search term."}}) + } else { + request({ + url: `https://api.github.com/search/issues?q=is:${type}+repo:minetest/minetest+${encodeURI(args.join(" "))}`, + json: true, + headers: { + "User-Agent": "Minetest Bot" + } + }, function(err, res, pkg) { + sendGitHubEmbedReply(message, pkg.items[0]); + }); + } + } + return def; +} + +module.exports = { + sendGitHubEmbedReply, + gitHubSearchCommand +}; diff --git a/minetestbot.js b/minetestbot.js index 6959993..6df0a93 100644 --- a/minetestbot.js +++ b/minetestbot.js @@ -1,6 +1,8 @@ const fs = require("fs"); const Discord = require("discord.js"); const {prefix, token} = require('./config.json'); +const request = require("request"); +const {sendGitHubEmbedReply} = require("./common.js"); // Error if missing configuration if (!token || !prefix) { @@ -58,24 +60,35 @@ client.on("message", async message => { if (message.author.bot) return; - // Try prefix first, then mentionString (could probably be done better) - let p = prefix; - if (!message.content.startsWith(p)) { - p = `${mentionString} `; - if (!message.content.startsWith(p)) return; - } - - const args = message.content.slice(p.length).trim().split(/ +/g); - const commandName = args.shift().toLowerCase(); - - const command = client.commands.get(commandName) - || client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName)); - - if (!command) return; - try { - command.execute(message, args, client); - } catch(error) { + let p; + if (message.content.startsWith(p = prefix) || message.content.startsWith(p = mentionString)) { + const args = message.content.slice(p.length).trim().split(/ +/g); + const commandName = args.shift().toLowerCase(); + + const command = client.commands.get(commandName) || + client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName)); + if (command) { + command.execute(message, args, client); + return; + } + } + // No valid command, look for #d+, referencing pulls or issues + for (const match of message.content.matchAll(/#(\d+)/g)) { + const number = match[1]; + request({ + url: "https://api.github.com/repos/minetest/minetest/issues/" + number, + json: true, + headers: { + "User-Agent": "Minetest Bot" + } + }, function(err, res, pkg) { + if (pkg.url) { + sendGitHubEmbedReply(message, pkg); + } + }); + } + } catch (error) { console.error(error); message.channel.send(":warning: Yikes, something broke."); } @@ -102,8 +115,8 @@ client.on("messageReactionAdd", (reaction, user) => { if (event === "") return; if (event === "exit") { if (!embed.footer || - embed.footer.iconURL().match(/avatars\/(\d+)/)[1] == user.id || - message.guild.member(user).hasPermission("MANAGE_MESSAGES")) + embed.footer.iconURL().match(/avatars\/(\d+)/)[1] == user.id || + message.guild.member(user).hasPermission("MANAGE_MESSAGES")) message.delete(); return; } else { @@ -118,7 +131,7 @@ client.on("messageReactionAdd", (reaction, user) => { let page = parseInt(matches[1]); const total = parseInt(matches[2]); - switch(event) { + switch (event) { case "next": page++; if (page > total) page = 1; diff --git a/package-lock.json b/package-lock.json index 9468a02..ae62102 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "minetestbot", - "version": "2.0.0", + "version": "2.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3508214..1e807f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "minetestbot", - "version": "2.1.0", + "version": "2.2.0", "description": "Discord bot with useful Minetest commands.", "main": "minetestbot.js", "dependencies": { diff --git a/pages.js b/pages.js index f8646ba..eb2d39c 100644 --- a/pages.js +++ b/pages.js @@ -18,7 +18,7 @@ module.exports = { }; }, getPage: function(command, message, config, term, func) { - request(`${config.url.search}`, async function (err, res, body) { + request(`${config.url.search}`, async function(err, res, body) { if (err || res.statusCode != 200) { message.channel.send(":warning: Something went wrong."); return;