diff --git a/CHANGELOG.md b/CHANGELOG.md index bb8f023..f5e0e34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Muse will now allow the member who invited Muse to set config options. For this to work, the View Audit Logs permission must be given when inviting Muse. If it isn't given, Muse still works and will contact the owner instead for initial setup. ## [1.4.1] - 2022-03-12 ### Changed diff --git a/migrations/20220312230720_add_invited_by_user_id/migration.sql b/migrations/20220312230720_add_invited_by_user_id/migration.sql new file mode 100644 index 0000000..4795706 --- /dev/null +++ b/migrations/20220312230720_add_invited_by_user_id/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Setting" ADD COLUMN "invitedByUserId" TEXT; diff --git a/schema.prisma b/schema.prisma index 5b4e898..a77e34b 100644 --- a/schema.prisma +++ b/schema.prisma @@ -25,6 +25,7 @@ model KeyValueCache { model Setting { guildId String @id + invitedByUserId String? playlistLimit Int @default(50) secondsToWaitAfterQueueEmpties Int @default(30) leaveIfNoListeners Boolean @default(true) diff --git a/src/bot.ts b/src/bot.ts index 0a041ec..5803a64 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -152,7 +152,7 @@ export default class { spinner.text = '📡 updating permissions...'; await Promise.all(this.client.guilds.cache.map(async guild => updatePermissionsForGuild(guild))); - spinner.succeed(`Ready! Invite the bot with https://discordapp.com/oauth2/authorize?client_id=${this.client.user?.id ?? ''}&scope=bot%20applications.commands&permissions=36700160`); + spinner.succeed(`Ready! Invite the bot with https://discordapp.com/oauth2/authorize?client_id=${this.client.user?.id ?? ''}&scope=bot%20applications.commands&permissions=36700288`); }); this.client.on('error', console.error); diff --git a/src/events/guild-create.ts b/src/events/guild-create.ts index 630d6cb..d71acda 100644 --- a/src/events/guild-create.ts +++ b/src/events/guild-create.ts @@ -6,16 +6,30 @@ import Config from '../services/config.js'; import {prisma} from '../utils/db.js'; import {REST} from '@discordjs/rest'; import {Routes} from 'discord-api-types/v9'; +import updatePermissionsForGuild from '../utils/update-permissions-for-guild.js'; export default async (guild: Guild): Promise => { + let invitedBy; + try { + const logs = await guild.fetchAuditLogs({type: 'BOT_ADD'}); + invitedBy = logs.entries.find(entry => entry.target?.id === guild.client.user?.id)?.executor; + } catch {} + + if (!invitedBy) { + console.warn(`Could not find user who invited Muse to ${guild.name} from the audit logs.`); + } + await prisma.setting.upsert({ where: { guildId: guild.id, }, create: { guildId: guild.id, + invitedByUserId: invitedBy?.id, + }, + update: { + invitedByUserId: invitedBy?.id, }, - update: {}, }); const config = container.get(TYPES.Config); @@ -33,7 +47,12 @@ export default async (guild: Guild): Promise => { ); } - const owner = await guild.fetchOwner(); + await updatePermissionsForGuild(guild); - await owner.send('👋 Hi! Someone (probably you) just invited me to a server you own. I can\'t be used by your server members until you complete setup by running /config set-role in your server.'); + if (invitedBy) { + await invitedBy.send('👋 Hi! You just invited me to a server. I can\'t be used by your server members until you complete setup by running /config set-role in your server.'); + } else { + const owner = await guild.fetchOwner(); + await owner.send('👋 Hi! Someone (probably you) just invited me to a server you own. I can\'t be used by your server members until you complete setup by running /config set-role in your server.'); + } }; diff --git a/src/utils/update-permissions-for-guild.ts b/src/utils/update-permissions-for-guild.ts index ca7c427..64110a7 100644 --- a/src/utils/update-permissions-for-guild.ts +++ b/src/utils/update-permissions-for-guild.ts @@ -26,6 +26,15 @@ const updatePermissionsForGuild = async (guild: Guild) => { permission: false, }, ]; + + if (settings.invitedByUserId) { + permissions.push({ + id: settings.invitedByUserId, + type: 'USER', + permission: true, + }); + } + const commands = await guild.commands.fetch(); await guild.commands.permissions.set({fullPermissions: commands.map(command => ({