Skip to content

Commit

Permalink
Merge pull request #66 from Jesmaster/60-application-commands
Browse files Browse the repository at this point in the history
60 application commands
  • Loading branch information
Jesmaster authored May 8, 2022
2 parents aae99c4 + 8d08ac9 commit ef017a3
Show file tree
Hide file tree
Showing 13 changed files with 519 additions and 392 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,8 @@ dist
.idea

#Bot cache files
.bgg_bot_cache
.bgg_bot_cache

#config
config.json
config.prod.json
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,32 @@ Leave a review on my **[top.gg listing](https://top.gg/bot/696045552625778810)**

## **Commands**

>`!bgg`
>`/help`
>
>List bot commands
---
>`!bgg collection <username>`
>`/collection <username>`
>
>Search for a collection by a username and displays a discord embed with collection details.
>
>_Example:_ `!bgg collection jesmaster`
>_Example:_ `/collection jesmaster`
>
> ![bgg-collection screenshot](https://i.imgur.com/6h6zChY.png)
---
>`!bgg search <game_name>`
>`/search <game_name>`
>
>Searches for a board game or expansion on BGG and displays a discord embed with the game information upon success.
>
>_Example:_ `!bgg search coup`
>_Example:_ `/search coup`
>
> ![bgg-search screenshot](https://i.imgur.com/lTiHV0D.png)
---
>`!bgg suggest <game_name>`
>`/search <game_name>` and choose optional suggest option
>
>Searches for a board game or expansion on BGG and displays a discord embed with the game information
> and participation emoji reactions upon success. Use to suggest playing a game and see if anyone is interested and who can teach.
> Thank you [pocc](https://github.com/pocc) for the idea and the initial code
>
>_Example:_ `!bgg suggest a feast for odin`
>_Example:_ `/search a feast for odin` then tab to and fill in extra suggest option
>
> ![bgg-suggest screenshot](https://i.imgur.com/DUkcce2.png)
46 changes: 21 additions & 25 deletions commands/bgg-collection.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
const {SlashCommandBuilder} = require("@discordjs/builders");
const xml2js = require("xml2js");

module.exports = {
name: 'bgg-collection',
description: 'Search Boardgamegeek for collection info. Args: <username>',
usage: '<username>',
args: true,
data: new SlashCommandBuilder()
.setName('collection')
.setDescription('Search Boardgamegeek for collection info. Args: <username>')
.addStringOption(option =>
option.setName('username')
.setDescription('The username for the BGG collection')
.setRequired(true)
),
cache_ttl: 1000 * 60 * 60,
/**
* Pull from BGG Bot Cache
Expand Down Expand Up @@ -85,12 +91,9 @@ module.exports = {
},
/**
* Create Discord Embed from BGG collection
*
* @param {Object} result
* @param {string} username
* @return {module:"discord.js".MessageEmbed}
*/
collectionToEmbed: function(result, username) {
collectionToEmbed: function(result, username, user) {
const Discord = require('discord.js');

let collection_url = `https://boardgamegeek.com/collection/user/${username}`;
Expand Down Expand Up @@ -125,6 +128,7 @@ module.exports = {
.setTitle(username + '\'s collection')
.setURL(collection_url)
.setDescription(collection_url)
.setAuthor({ name: user.username, url: user.avatarURL(), iconURL: user.displayAvatarURL() })
.addFields(
{
name: 'Total',
Expand Down Expand Up @@ -155,36 +159,28 @@ module.exports = {
},
/**
* Send collection embed to channel
*
* @param {Object} result
* @param {module:"discord.js".Message} message
* @param {String} username
*/
collectionPrintEmbed: function(result, message, username) {
collectionPrintEmbed: function(result, interaction, username) {
const { user } = interaction.member;
if(typeof result === 'object' && result.items['$'].totalitems > 0) {
message.channel.send({ embeds: [this.collectionToEmbed(result, username)] });
interaction.reply({ embeds: [this.collectionToEmbed(result, username, user)] });
}
else {
message.channel.send(`No results found for "${username}".`);
interaction.reply(`No results found for "${username}".`);
}
},
/**
* Execute Discord Command
*
* @param {module:"discord.js".Message} message
* @param {Array} args
* @param {Object} commandOptions
* @return {Promise<void>}
*/
execute: async function (message, args, commandOptions) {
let current = this;
let username = args[0].toLowerCase();
execute: async function (interaction) {
const current = this;
const username = interaction.options.getString('username');

current.bggCollection(username)
.then(result => {
console.log(`Collection results found for ${username}`);
message.delete();
current.collectionPrintEmbed(result, message, username)
current.collectionPrintEmbed(result, interaction, username)
})
.catch(async function(err) {
if(err === 'Building results') {
Expand All @@ -195,7 +191,7 @@ module.exports = {
current.bggCollection(username)
.then(result => {
console.log(`Collection results found for ${username}`);
current.collectionPrintEmbed(result, message, username)
current.collectionPrintEmbed(result, interaction, username)
});
}
else {
Expand Down
32 changes: 16 additions & 16 deletions commands/bgg-help.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
const {SlashCommandBuilder} = require("@discordjs/builders");

module.exports = {
name: 'bgg-help',
description: 'Get help for bgg bot commands',
usage: '',
args: false,
data: new SlashCommandBuilder()
.setName('help')
.setDescription('Get help for bgg bot commands'),
/**
* Create Discord Embed for help
*
* @return {module:"discord.js".MessageEmbed}
*/
helpEmbed: async function(message) {
helpEmbed: (client) => {
const Discord = require('discord.js');

return new Discord.MessageEmbed()
Expand All @@ -17,32 +18,31 @@ module.exports = {
.addFields(
{
name: 'Stats',
value: 'BGG Bot is on '+message.client.guilds.cache.size+' servers'
value: 'BGG Bot is on '+client.guilds.cache.size+' servers'
},
{
name: 'Collection',
value: 'Get collection information for a bgg user.\nUsage: `!bgg collection <username>`.\nExample: `!bgg collection jesmaster`'
value: 'Get collection information for a bgg user.\nUsage: `/collection <bgg_username>`.'
}, {
name: 'Search',
value: 'Get information for a board game from bgg.\nUsage: `!bgg search <game_name>`.\nExample: `!bgg search the resistance`'
value: 'Get information for a board game from bgg.\nUsage: `/search <game_name>` and leave the extra option blank'
},
{
name: 'Suggest',
value: 'Get information for a board game from bgg and allow emjoi reactions for people looking to play.\nUsage: `!bgg suggest <game_name>`.\nExample: `!bgg suggest the resistance`'
value: 'Get information for a board game from bgg and allow emjoi reactions for people looking to play.\nUsage: type `/search <game_name>` and tab to option "Suggest to play a game.".'
}
);
},
/**
* Execute Discord Command
*
* @param {module:"discord.js".Message} message
* @param {Array} args
* @param {module:"discord.js".Interaction} interaction
* @return {Promise<void>}
*/
execute: async function(message, args) {
this.helpEmbed(message).then(embed => {
message.delete();
message.channel.send({ embeds: [embed] });
});
execute: async function(interaction) {
console.log(interaction.message);
const { client } = interaction;

await interaction.reply({ embeds: [this.helpEmbed(client)] });
}
}
97 changes: 46 additions & 51 deletions commands/bgg-search.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
const {SlashCommandBuilder} = require("@discordjs/builders");
const he = require("he");

module.exports = {
name: 'bgg-search',
description: 'Search Boardgamegeek for game info. Args: <game_name>',
usage: '<game_name>',
args: true,
data: new SlashCommandBuilder()
.setName('search')
.setDescription('Search Boardgamegeek for game info. Args: <game_name>')
.addStringOption(option =>
option.setName('name')
.setDescription('The name of the game you want to search for.')
.setRequired(true)
)
.addStringOption(option =>
option.setName('suggest')
.setDescription('Suggest to play this game?')
.addChoices({
name: 'Suggest to play a game.',
value: 'suggest',
})
),
cache_ttl: 1000 * 60 * 60 * 24,
/**
* Preforms BGG API search call.
*
* @param {Array} args
*
* @return {Promise<JSON>}
*/
bggSearch: async function(args) {
bggSearch: async function(name) {
const
search_query = args.join(' '),
searchParams = new URLSearchParams(JSON.stringify({query: search_query})),
searchParams = new URLSearchParams(JSON.stringify({query: name})),
query = searchParams.toString(),
cache_type = 'bgg_search',
cache = await this.cacheGet(cache_type, query),
Expand All @@ -25,7 +35,7 @@ module.exports = {
return Promise.resolve(cache);
}

return fetch('https://boardgamegeek.com/search/boardgame?q='+search_query, {
return fetch('https://boardgamegeek.com/search/boardgame?q='+name, {
headers: {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'en-US,en;q=0.9'
Expand Down Expand Up @@ -150,7 +160,7 @@ module.exports = {
.setURL(`https://boardgamegeek.com/${item['$'].type}/${item['$'].id}`)
.setThumbnail(item.thumbnail[0])
.setDescription(he.decode(item.description[0]).substr(0, 200)+'...')
.setAuthor(user.username, user.avatarURL())
.setAuthor({ name: user.username, url: user.avatarURL(), iconURL: user.displayAvatarURL() })
.addFields(
{
name: ':hash: Number of Players',
Expand All @@ -166,23 +176,16 @@ module.exports = {
},
/**
* Send game embed to channel given thing_id
*
* @param {Object} bggSearchResult
* @param {module:"discord.js".Message} message
* @param {Array} args
*/
thingIdToSearchEmbed: async function(bggSearchResult, message, args) {
thingIdToSearchEmbed: async function(bggSearchResult, interaction) {
if(bggSearchResult.found) {
this.bggThing(bggSearchResult.thing_id)
.then(result => {
message.delete();
message.channel.send({
embeds: [this.itemToSearchEmbed(result.items.item[0], message.author)]
});
});
const result = await this.bggThing(bggSearchResult.thing_id);
await interaction.reply({
embeds: [this.itemToSearchEmbed(result.items.item[0], interaction.member.user)]
});
}
else {
await message.channel.send(`No results found for "${args.join(' ')}".`);
await interaction.reply(`No results found for "${interaction.options.getString('name')}".`);
}
},
/**
Expand All @@ -202,8 +205,8 @@ module.exports = {
.setURL(`https://boardgamegeek.com/${item['$'].type}/${item['$'].id}`)
.setThumbnail(item.thumbnail[0])
.setDescription(he.decode(item.description[0]).substr(0, 200)+'...')
.setFooter("( 👍 Interested | 📖 Can Teach | ❌ End Suggestion )")
.setAuthor(user.username, user.avatarURL())
.setFooter({ text: '( 👍 Interested | 📖 Can Teach | ❌ End Suggestion )'})
.setAuthor({ name: user.username, url: user.avatarURL(), iconURL: user.displayAvatarURL() })
.addFields(
{
name: ':hash: Number of Players',
Expand Down Expand Up @@ -234,19 +237,15 @@ module.exports = {
},
/**
* Send game embed to channel given thing_id
*
* @param {Object} bggSearchResult
* @param {module:"discord.js".Message} message
* @param {Array} args
*/
thingIdToSuggestEmbed: async function(bggSearchResult, message, args) {
thingIdToSuggestEmbed: async function(bggSearchResult, interaction) {
const Discord = require('discord.js');

if(bggSearchResult.found) {
this.bggThing(bggSearchResult.thing_id)
.then(result => {
let embed = this.itemToSuggestEmbed(result.items.item[0], message.author);
message.channel.send({ embeds: [embed] }).then(embedMessage => {
let embed = this.itemToSuggestEmbed(result.items.item[0], interaction.member.user);
interaction.reply({ embeds: [embed], fetchReply: true }).then(embedMessage => {
embedMessage.react("👍");
embedMessage.react("📖");
embedMessage.react("❌");
Expand Down Expand Up @@ -301,12 +300,12 @@ module.exports = {
deleteCollector.stop();
embedMessage.reactions.removeAll();
let changedEmbed = new Discord.MessageEmbed(embed);
embed.setFooter('Reactions have been closed off for this suggestion.');
embed.setFooter({ text: 'Reactions have been closed off for this suggestion.' });
embedMessage.edit({ embeds: [embed] });
});

const deleteFilter = (reaction, user) => {
return reaction.emoji.name == '❌' && user.id === message.author.id;
return reaction.emoji.name == '❌' && user.id === interaction.member.user.id;
};
const deleteCollector = embedMessage.createReactionCollector({ filter: deleteFilter });
deleteCollector.on('collect', () => {
Expand All @@ -315,32 +314,28 @@ module.exports = {
});

}).catch(err => console.error(err));
message.delete();
});
}
else {
await message.channel.send(`No results found for "${args.join(' ')}".`);
await interaction.reply(`No results found for "${interaction.options.getString('name')}".`);
}
},
/**
* Execute Discord Command
*
* @param {module:"discord.js".Message} message
* @param {Array} args
* @param {Object} commandOptions
* @return {Promise<void>}
*/
execute: async function(message, args, commandOptions) {
this.bggSearch(args)
execute: async function(interaction) {
const name = interaction.options.getString('name');
const suggest = interaction.options.getString('suggest');

this.bggSearch(name)
.then(result => this.thingIdFromBggSearchCall(result))
.then(bggSearchResult => {
switch (commandOptions.type) {
case 'search':
this.thingIdToSearchEmbed(bggSearchResult, message, args);
break;
case 'suggest':
this.thingIdToSuggestEmbed(bggSearchResult, message, args);
break;
if (suggest === 'suggest') {
this.thingIdToSuggestEmbed(bggSearchResult, interaction);
}
else {
this.thingIdToSearchEmbed(bggSearchResult, interaction);
}
})
},
Expand Down
Loading

0 comments on commit ef017a3

Please sign in to comment.