Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c08046a
feat: add discord-events plugin for comprehensive event management
DevArqf Oct 14, 2025
2bc7a41
refactor: rename plugin to events-manager
DevArqf Oct 14, 2025
c255945
\chore: remove unnecessary CHANGELOG.md and DEVELOPMENT.md files\
DevArqf Oct 14, 2025
083c54c
feat(plugin-events-manager): implement Flashcore persistence and fix โ€ฆ
DevArqf Oct 27, 2025
39f0c95
fix(plugin-events-manager): use valid ManageGuild permission instead โ€ฆ
DevArqf Oct 27, 2025
1855b49
refactor(plugin-events-manager): remove custom NLP date parsing
DevArqf Oct 27, 2025
f2e51e0
refactor(plugin-events-manager): use crypto-based ID generation
DevArqf Oct 27, 2025
9fb6dfb
refactor(plugin-events-manager): consolidate duplicate embed and buttโ€ฆ
DevArqf Oct 27, 2025
ad60179
feat(plugin-events-manager): implement functional reminder processing
DevArqf Oct 27, 2025
7b20fe0
fix(plugin-events-manager): add null check for regex match in button โ€ฆ
DevArqf Oct 27, 2025
29b7258
fix(plugin-events-manager): remove non-functional pagination buttons
DevArqf Oct 27, 2025
8d54c70
refactor(plugin-events-manager): check event capacity before RSVP update
DevArqf Oct 27, 2025
dc4172d
refactor(plugin-events-manager): remove personal branding from plugin
DevArqf Oct 27, 2025
bbf83e3
refactor(plugin-events-manager): remove unused saveEvent import
DevArqf Oct 27, 2025
0527c21
fix(plugin-events-manager): store dates as timestamps for JSON serialโ€ฆ
DevArqf Oct 27, 2025
f9cc173
fix(plugin-events-manager): handle null/undefined location in remindeโ€ฆ
DevArqf Oct 27, 2025
a3ed6a6
fix: enhance date validation to properly catch invalid dates like Feb 31
DevArqf Oct 27, 2025
2a7eadc
fix: remove incorrect length check on ActionRowBuilder in event-list
DevArqf Oct 27, 2025
640e371
fix: ensure currentAttendees is always initialized when loading events
DevArqf Oct 27, 2025
e6f7ef2
fix: handle deserialized event dates defensively in event-remind
DevArqf Oct 27, 2025
0ea8e87
fix: add defensive handling for reminderTime in confirmation embed
DevArqf Oct 27, 2025
516de6c
fix: normalize dateTime in getEvent to prevent runtime errors
DevArqf Oct 27, 2025
43b8785
fix: handle reminder backlog up to 7 days and validate dates
DevArqf Oct 27, 2025
b3850a2
fix: add defensive date handling and description truncation in remindโ€ฆ
DevArqf Oct 27, 2025
86ac528
fix: prevent overlapping reminder runs and duplicate intervals on hotโ€ฆ
DevArqf Oct 27, 2025
015462f
fix: strengthen customId parsing in view attendees button handler
DevArqf Oct 27, 2025
026f02c
fix: remove non-functional refresh button from event list
DevArqf Oct 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/plugin-events-manager/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules/
dist/
.robo/build/
*.log
.env*
.DS_Store
coverage/
.nyc_output/
21 changes: 21 additions & 0 deletions packages/plugin-events-manager/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 Discord Events Manager Plugin Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
213 changes: 213 additions & 0 deletions packages/plugin-events-manager/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
<p align="center">โœจ <strong>Generated with <a href="https://robojs.dev/create-robo">create-robo</a> magic!</strong> โœจ</p>

---

# ๐Ÿ“… Discord Events Manager

**A comprehensive Discord events management plugin for Robo.js** that helps communities organize events with RSVP tracking, automated reminders, and seamless Discord integration.

![Version](https://img.shields.io/badge/version-1.0.0-blue)
![License](https://img.shields.io/badge/license-MIT-green)
![Robo.js](https://img.shields.io/badge/robo.js-plugin-purple)

## โœจ Features

- **๐ŸŽฏ Event Creation**: Create detailed events with dates, descriptions, locations, and attendance limits
- **๐Ÿ“ RSVP System**: Track who's going, maybe attending, or can't attend (persisted in Flashcore)
- **โฐ Smart Reminders**: Automated event reminders (1 hour to 1 week before, stored in Flashcore)
- **๐Ÿ“Š Attendee Management**: View and manage event participants
- **๐Ÿ” Event Discovery**: List and filter events by date, creator, or status
- **๐Ÿ‘ฅ Interactive UI**: Easy event creation through Discord modals
- **๐ŸŽจ Rich Embeds**: Beautiful Discord embeds with interactive buttons
- **๐Ÿ”’ Permissions**: Role-based event management with proper permissions

## ๐Ÿ“ฆ Installation

To add this plugin to your **Robo.js** project:

```bash
npx robo add events-manager
```

New to **Robo.js**? Start your project with this plugin pre-installed:

```bash
npx create-robo <project-name> -p events-manager
```

## ๐ŸŽฎ Commands

### `/event-create` - Create New Events

Create detailed events with full customization:

```bash
/event-create
```

This opens a modal where you can specify:
- Event title
- Description
- Date & Time (format: `YYYY-MM-DD HH:MM`)
- Location (optional)
- Max attendees (optional)

### `/event-list` - Browse Events

View and filter community events:

```bash
/event-list # Show upcoming events
/event-list filter:past # Show past events
/event-list filter:all # Show all events
/event-list user:@SomeUser # Show events by specific user
```

### `/event-remind` - Set Reminders

Schedule automatic event reminders:

```bash
/event-remind event:"Gaming Night" time:"1 day before" channel:#events
```

**Reminder Options:**
- 1 hour before
- 6 hours before
- 1 day before
- 3 days before
- 1 week before

## ๐ŸŽฏ Usage Examples

### Creating a Gaming Event

```bash
/event-create
```

Then fill in the modal with:
- **Title**: "Weekly Gaming Session"
- **Description**: "Join us for multiplayer fun!"
- **Date & Time**: "2025-12-01 20:00"
- **Location**: "Gaming Voice Channel"
- **Max Attendees**: "12"

### Setting Up a Community Meeting

1. Use `/event-create` (without quick-event parameter)
2. Fill in the modal:
- **Title**: "Monthly Community Meeting"
- **Description**: "Discuss server updates, new features, and community feedback"
- **Date & Time**: "2025-10-20 19:00"
- **Location**: "General Voice Channel"
- **Max Attendees**: "50"

### Managing RSVPs

Users can interact with event posts using buttons:
- **โœ… Going** - Confirm attendance (automatically tracked in Flashcore)
- **โ“ Maybe** - Tentative attendance (with capacity overflow protection)
- **โŒ Can't Go** - Decline attendance
- **๐Ÿ‘ฅ View Attendees** - See actual user names and attendance counts

### Setting Reminders

```bash
/event-remind event:"Community Meeting" time:"1 day before" channel:#announcements
```

**Note:** Reminders are scheduled and stored in Flashcore, persisting across bot restarts.

## ๐Ÿ”ง Configuration

### Required Permissions

**For Event Creators:**
- `Manage Guild` permission OR `Administrator`

**For All Users:**
- `Use Application Commands`
- `Read Message History`
- `Send Messages`

### Channel Setup

Recommended channel setup:
- **#events** - For event announcements
- **#event-reminders** - For automated reminders
- Voice channels for event locations

## ๐ŸŽจ Customization

### Event Embed Colors
- **Upcoming Events**: Blue (`#5865F2`)
- **Past Events**: Gray (`#99AAB5`)
- **Reminders**: Orange (`#FFAA00`)
- **Confirmations**: Green (`#00FF00`)

### Date/Time Format

Events use ISO 8601 date format:
- Format: `YYYY-MM-DD HH:MM`
- Example: `2025-12-25 14:30`
- Uses 24-hour time format

## ๐Ÿ’พ Data Storage

This plugin uses **Flashcore**, Robo.js's built-in key-value storage system, to persist:
- Event details (title, description, date/time, location, attendees)
- RSVP responses (going, maybe, not going)
- Event reminders with scheduling information

All data is automatically saved and persists across bot restarts. No additional database setup required!

## ๐Ÿ› ๏ธ Development

To contribute to this plugin:

```bash
git clone https://github.com/Wave-Play/robo.js
cd robo.js/packages/plugin-events-manager
pnpm install
pnpm dev
```

## ๐Ÿค Contributing

Contributions are welcome! This plugin was created for **Hacktoberfest 2025**. Please:

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request

## ๐Ÿ“‹ Roadmap

- [x] **Database Integration** - Persistent event storage using Flashcore
- [x] **RSVP Tracking** - Full Yes/Maybe/No response tracking with user data
- [x] **Event Reminders** - Scheduled reminders with Flashcore persistence
- [x] **Event Listing** - Filter events by date, creator, or status
- [ ] **Recurring Events** - Weekly/monthly event templates
- [ ] **Event Categories** - Gaming, Social, Educational, etc.
- [ ] **Calendar Integration** - Export to Google Calendar/Outlook
- [ ] **Event Analytics** - Attendance statistics and insights
- [ ] **Custom RSVP Options** - More than just Yes/No/Maybe
- [ ] **Event Templates** - Quick event creation from templates
- [ ] **Advanced Time Zone Support** - Automatic time zone conversion
- [ ] **Advanced Natural Language Processing** - Enhanced date parsing

## ๐Ÿ“ž Support

- **Documentation**: [Robo.js Documentation](https://robojs.dev)
- **Discord**: [Robo.js Community](https://robojs.dev/discord)
- **Issues**: Create an issue in this repository

## ๐Ÿ“„ License

MIT License - see [LICENSE](LICENSE) for details.

---

**Made with โค๏ธ by DevArqf for the Discord community and Hacktoberfest 2025**
12 changes: 12 additions & 0 deletions packages/plugin-events-manager/config/robo.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// @ts-check

/**
* @type {import('robo.js').Config}
**/
export default {
clientOptions: {
intents: ['Guilds', 'GuildMessages']
},
plugins: [],
type: 'plugin'
}
57 changes: 57 additions & 0 deletions packages/plugin-events-manager/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "@robojs/events-manager",
"description": "A comprehensive Discord events management plugin for Robo.js that helps communities organize events with RSVP tracking, automated reminders, and seamless Discord integration.",
"version": "0.0.0",
"private": false,
"type": "module",
"main": ".robo/build/index.js",
"license": "MIT",
"author": "DevArqf",
"contributors": [
"DevArqf"
],
"files": [
".robo/",
"src/",
"config/",
"LICENSE",
"README.md"
],
"repository": {
"type": "git",
"url": "https://github.com/Wave-Play/robo.git",
"directory": "packages/plugin-events-manager"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"scripts": {
"build": "robo build plugin",
"dev": "NODE_OPTIONS=--enable-source-maps robo build plugin --watch",
"lint": "pnpm lint:eslint && pnpm lint:style",
"lint:eslint": "eslint . --ext js,jsx,ts,tsx",
"lint:style": "prettier --write ."
},
"devDependencies": {
"@swc/core": "^1.11.29",
"@types/node": "^20.16.5",
"@typescript-eslint/eslint-plugin": "^5.56.0",
"@typescript-eslint/parser": "^5.56.0",
"discord.js": "^14.7.1",
"eslint": "^8.36.0",
"prettier": "^2.8.5",
"robo.js": "workspace:*",
"typescript": "^5.0.0"
},
"keywords": [
"discord",
"events",
"rsvp",
"bot",
"robo",
"plugin",
"community",
"management"
]
}
73 changes: 73 additions & 0 deletions packages/plugin-events-manager/src/commands/event-create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { createCommandConfig, logger } from 'robo.js'
import { ModalBuilder, TextInputBuilder, TextInputStyle, ActionRowBuilder } from 'discord.js'

export const config = createCommandConfig({
description: 'Create a new community event'
})

export default async (interaction) => {
logger.info(`Event create command used by ${interaction.user.tag}`)

if (!interaction.member.permissions.has('ManageGuild') && !interaction.member.permissions.has('Administrator')) {
return interaction.reply({
content: 'โŒ You need the "Manage Guild" permission to create events.',
ephemeral: true
})
}

const modal = createEventModal()
await interaction.showModal(modal)
}


function createEventModal() {
const modal = new ModalBuilder()
.setCustomId('event-create-modal')
.setTitle('Create New Event')

const titleInput = new TextInputBuilder()
.setCustomId('event-title')
.setLabel('Event Title')
.setStyle(TextInputStyle.Short)
.setRequired(true)
.setMaxLength(100)

const descriptionInput = new TextInputBuilder()
.setCustomId('event-description')
.setLabel('Event Description')
.setStyle(TextInputStyle.Paragraph)
.setRequired(true)
.setMaxLength(1000)

const dateTimeInput = new TextInputBuilder()
.setCustomId('event-datetime')
.setLabel('Date & Time (format: YYYY-MM-DD HH:MM)')
.setStyle(TextInputStyle.Short)
.setRequired(true)

const locationInput = new TextInputBuilder()
.setCustomId('event-location')
.setLabel('Location (optional)')
.setStyle(TextInputStyle.Short)
.setRequired(false)
.setMaxLength(100)
.setPlaceholder('Discord Voice Channel, Online, etc.')

const maxAttendeesInput = new TextInputBuilder()
.setCustomId('event-max-attendees')
.setLabel('Max Attendees (optional)')
.setStyle(TextInputStyle.Short)
.setRequired(false)
.setPlaceholder('Leave empty for unlimited')

const rows = [
new ActionRowBuilder().addComponents(titleInput),
new ActionRowBuilder().addComponents(descriptionInput),
new ActionRowBuilder().addComponents(dateTimeInput),
new ActionRowBuilder().addComponents(locationInput),
new ActionRowBuilder().addComponents(maxAttendeesInput)
]

modal.addComponents(...rows)
return modal
}
Loading
Loading