Skip to content

Commit

Permalink
update readme and add remove product command
Browse files Browse the repository at this point in the history
  • Loading branch information
radekm2000 committed May 27, 2024
1 parent c9bd5eb commit a834ab3
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 7 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,18 @@ This app is a simplified version of **Vinted**, following a similar layout. Belo
- **Frontend:**
- React using Vite.

## Integration with discord
**Discord commands**
![DiscordCommands](/readmeImages/Discord%20commands%20(2).png)

- Profile
![Profile Command](/readmeImages/Profile%20command.png)
- Inventory + removing product ![Inventory command](/readmeImages/Inventory%20command.png)
- Reviews ![Review command](/readmeImages/Reviews%20command.png)
## Images



Add feedback
![Add feedback](/readmeImages/addFeedback.png)

Expand Down Expand Up @@ -85,3 +95,5 @@ Notifications + main page

Editing roles
![Editing roles](/readmeImages/EditRole.png)


Binary file added readmeImages/Inventory command.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added readmeImages/Profile command.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added readmeImages/Reviews command.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions server/ecommerce/src/discord-bot/discord-bot.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { UsersService } from 'src/users/users.service';
import { InventoryCommand } from './src/commands/inventory';
import { ProductsService } from 'src/products/products.service';
import { ReviewsCommand } from './src/commands/reviews';
import { RemoveProduct } from './src/commands/remove-product';

@Injectable()
export class DiscordBotService implements OnModuleInit {
Expand Down Expand Up @@ -44,6 +45,10 @@ export class DiscordBotService implements OnModuleInit {
usersService: this.userService,
}),
new ReviewsCommand({ usersService: this.userService }),
new RemoveProduct({
productService: productsService,
usersService: userService,
}),
],
});
}
Expand Down
4 changes: 4 additions & 0 deletions server/ecommerce/src/discord-bot/src/commands/inventory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {
AutocompleteInteraction,
CacheType,
ChatInputCommandInteraction,
EmbedBuilder,
SlashCommandBuilder,
Expand Down Expand Up @@ -41,6 +43,8 @@ export class InventoryCommand implements SlashCommand {
await interaction.editReply({ embeds: embed });
};

public autocomplete = async (interaction: AutocompleteInteraction) => {};

private createEmbeds = async (userProducts: Product[]) => {
const headerEmbed = new EmbedBuilder()
.setTitle('Your items')
Expand Down
8 changes: 7 additions & 1 deletion server/ecommerce/src/discord-bot/src/commands/ping.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js';
import {
AutocompleteInteraction,
ChatInputCommandInteraction,
SlashCommandBuilder,
} from 'discord.js';
import { SlashCommand } from './slash-command';

export class Ping implements SlashCommand {
Expand All @@ -11,4 +15,6 @@ export class Ping implements SlashCommand {
public execute = async (interaction: ChatInputCommandInteraction) => {
await interaction.reply('pong');
};

public autocomplete = async (interaction: AutocompleteInteraction) => {};
}
3 changes: 3 additions & 0 deletions server/ecommerce/src/discord-bot/src/commands/profile.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
AutocompleteInteraction,
ChatInputCommandInteraction,
EmbedBuilder,
SlashCommandBuilder,
Expand Down Expand Up @@ -43,6 +44,8 @@ export class ProfileCommand implements SlashCommand {
await interaction.editReply({ embeds: [embed] });
};

public autocomplete = async (interaction: AutocompleteInteraction) => {};

private createEmbed = async (
userAvatar: string | null,
displayName: string,
Expand Down
93 changes: 93 additions & 0 deletions server/ecommerce/src/discord-bot/src/commands/remove-product.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {
AutocompleteInteraction,
ChatInputCommandInteraction,
SlashCommandBuilder,
} from 'discord.js';
import { SlashCommand } from './slash-command';
import { UsersService } from 'src/users/users.service';
import { ProductsService } from 'src/products/products.service';

const PRODUCT_OPTION_NAME = 'product';

type Config = {
usersService: UsersService;
productService: ProductsService;
};

export class RemoveProduct implements SlashCommand {
readonly config: any = new SlashCommandBuilder()
.setName('remove-product')
.setDescription('Removes one of your listed products')
.addStringOption((option) =>
option
.setName(PRODUCT_OPTION_NAME)
.setDescription('Product to remove')
.setRequired(true)
.setAutocomplete(true),
);

private readonly usersService: UsersService;
private readonly productService: ProductsService;

constructor(config: Config) {
this.usersService = config.usersService;
this.productService = config.productService;
}

public autocomplete = async (interaction: AutocompleteInteraction) => {
const userId = interaction.user.id;
const user = await this.getUserWithProducts(userId);
const value = interaction.options.getFocused().toLowerCase();
const userProducts = user.products;

const filteredProducts = userProducts
.filter((product) => product.title.toLowerCase().includes(value))
.slice(0, 25);

await interaction.respond(
filteredProducts.map((choice) => ({
name: choice.title,
value: choice.id.toString(),
})),
);
};

public execute = async (interaction: ChatInputCommandInteraction) => {
const productArg = interaction.options.getString(PRODUCT_OPTION_NAME);
if (!productArg) {
await interaction.reply({
content: `Missing "${productArg} option"`,
ephemeral: true,
});
}

const productId = parseInt(productArg);

if (!this.isValidProduct(productId)) {
await interaction.reply({
content:
'Invalid product ID. Please select a valid product from the autocomplete options.',
ephemeral: true,
});
return;
}

await this.deleteProductById(productId);
await interaction.reply({
content: 'Product removed successfully',
ephemeral: true,
});
};

private getUserWithProducts = async (userDiscordId: string) => {
return await this.usersService.findUserByDiscordId(userDiscordId);
};

private deleteProductById = async (productId: number) => {
return await this.productService.deleteProduct(productId);
};

private isValidProduct = (productArg: number) => {
return !isNaN(productArg);
};
}
5 changes: 4 additions & 1 deletion server/ecommerce/src/discord-bot/src/commands/reviews.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
AutocompleteInteraction,
ChatInputCommandInteraction,
EmbedBuilder,
SlashCommandBuilder,
Expand Down Expand Up @@ -56,7 +57,7 @@ export class ReviewsCommand implements SlashCommand {
) => {
const embed = new EmbedBuilder()
.setTitle(
`You have a total of ${totalReviews} reviews with an average rating of ${averageRating.toFixed(
`You have a total of ${totalReviews} reviews with an average rating of ${averageRating.toFixed(
2,
)}`,
)
Expand All @@ -82,6 +83,8 @@ export class ReviewsCommand implements SlashCommand {
return embed;
};

public autocomplete = async (interaction: AutocompleteInteraction) => {};

private calculateTotalReviews = (reviews: Review[]) => {
return reviews.length;
};
Expand Down
13 changes: 11 additions & 2 deletions server/ecommerce/src/discord-bot/src/commands/slash-command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js';
import {
AutocompleteInteraction,
ChatInputCommandInteraction,
SlashCommandBuilder,
} from 'discord.js';

export interface SlashCommand {
readonly config: SlashCommandBuilder;
readonly config: Omit<
SlashCommandBuilder,
'addSubcommand' | 'addSubcommandGroup'
>;

execute(interaction: ChatInputCommandInteraction): Promise<void>;
autocomplete(interaction: AutocompleteInteraction): Promise<void>;
}
23 changes: 20 additions & 3 deletions server/ecommerce/src/discord-bot/src/discordbot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Logger } from '@nestjs/common';
import {
AutocompleteInteraction,
ChatInputCommandInteraction,
Client,
Events,
Expand Down Expand Up @@ -86,9 +87,25 @@ export class DiscordBot {

private listenToInteractions = () => {
this.bot.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isChatInputCommand()) return;

await this.handleCommand(interaction);
if (interaction.isChatInputCommand()) {
await this.handleCommand(interaction);
} else if (interaction.isAutocomplete()) {
await this.handleAutocomplete(interaction);
}
});
};

private handleAutocomplete = async (interaction: AutocompleteInteraction) => {
const command = this.commands.get(interaction.commandName);
if (!command) return;

try {
await command.autocomplete(interaction);
} catch (error) {
this.logger.error(
{ error },
`Error when executing the ${interaction.commandName} autocomplete`,
);
}
};
}

0 comments on commit a834ab3

Please sign in to comment.