feat: Add early access opt-in feature

This commit is contained in:
2024-03-05 14:17:53 +07:00
parent 93f5c96595
commit 3f9b23d9b1
7 changed files with 183 additions and 3 deletions
+7 -1
View File
@@ -6,7 +6,13 @@
"bot_no_permissions": "I don't have permission (O_O;)",
"bot_no_permissions_description": "I need ``{{PERMISSIONS}}`` permissions",
"processing": "Please wait a moment~",
"processing_description": "Getting it done right now! (งᓀ‸ᓂ)ง"
"processing_description": "Getting it done right now! (งᓀ‸ᓂ)ง",
"early_access_features": "Early access features",
"early_access_features_description": "Hey there! So, this new feature we've got is still in its early access phase. We're working hard to test and make it even better. But, just a heads up, early access means there might be some surprises like unexpected stuff, security things, or features that are still a work in progress.\n\nIf you're up for it, guild administrators can jump in and try it out by opting in through the settings"
},
"early_access_warning": {
"title": "Early access warning",
"description": "Experience the newest features first with early access! Things might not be perfect yet, but your feedback helps us make it amazing. Contact us with the support command if you find anything\n\n You can disable early access features anytime in the settings"
},
"stats": {
"title": "Stats",
+7 -1
View File
@@ -6,7 +6,13 @@
"bot_no_permissions": "許可がない (O_O;)",
"bot_no_permissions_description": "そのためには、あたしの``{{PERMISSIONS}}``の権限が必要です",
"processing": "アクションの実行",
"processing_description": "今これを成し遂げています (งᓀ‸ᓂ)ง"
"processing_description": "今これを成し遂げています (งᓀ‸ᓂ)ง",
"early_access_features": "早期アクセス機能",
"early_access_features_description": "こんにちは!新しいこの機能はまだ早期アクセスフェーズにあります。私たちはテストを進め、さらに良くしている最中です。ただし、早期アクセスということは、予期せぬこと、セキュリティの問題、または作業中の機能のような驚きがあるかもしれないことを意味します。\n\nお試しいただけるなら、ギルド管理者は設定からオプトインして試してみることができます。"
},
"early_access_warning": {
"title": "アーリーアクセス注意報",
"description": "アーリーアクセスで最新の機能を先取りしよう! まだ完璧じゃないかもしれないけど、あなたのフィードバックが素晴らしいものに変えてくれるんだよ。何か見つけたら、サポートコマンドで連絡してね\n\n設定でいつでもアーリーアクセス機能を無効にできるよ"
},
"stats": {
"title": "統計情報",
+7 -1
View File
@@ -6,7 +6,13 @@
"bot_no_permissions": "ฉันไม่มีสิทธิ์เข้าถึง (O_O;)",
"bot_no_permissions_description": "ฉันต้องการสิทธิ์เข้าถึง ``{{PERMISSIONS}}``",
"processing": "รอแปปนึงน้า",
"processing_description": "ฉันกำลังดำเนินการให้อยู่ (งᓀ‸ᓂ)ง"
"processing_description": "ฉันกำลังดำเนินการให้อยู่ (งᓀ‸ᓂ)ง",
"early_access_features": "คุณลักษณะการเข้าถึงล่วงหน้า",
"early_access_features_description": "สวัสดี! ฟีเจอร์ใหม่ที่เรามีนี้ยังอยู่ในช่วงการเข้าถึงก่อนใคร เรากำลังทำงานอย่างหนักเพื่อทดสอบและทำให้ดียิ่งขึ้น แต่ขอเตือนไว้ก่อน การเข้าถึงก่อนใครหมายความว่าอาจมีสิ่งที่ไม่คาดคิดเกิดขึ้นได้ เช่น ปัญหาด้านความปลอดภัย หรือคุณลักษณะที่ยังอยู่ระหว่างการพัฒนา\n\nหากคุณสนใจ ผู้ดูแลกิลด์สามารถเข้าร่วมทดลองใช้งานได้โดยเลือกใช้ผ่านการตั้งค่า"
},
"early_access_warning": {
"title": "แจ้งเตือน Early Access",
"description": "ลองสัมผัสคุณลักษณะใหม่ๆ ก่อนใครได้กับ Early Access นะคะ! บางอย่างอาจจะยังไม่สมบูรณ์ที่สุดนะ แต่คำติชมจากคุณจะช่วยทำให้มันน่านับถือมากขึ้นเลยนะคะ ติดต่อเราผ่านคำสั่ง support ถ้าคุณพบอะไรเจ๊งจะบอกเรานะคะ\n\nแล้วนะคะ, คุณสามารถปิดใช้คุณลักษณะ Early Access ได้ทุกเมื่อในเมนูตั้งค่าค่ะ"
},
"stats": {
"title": "สถิติ",
+2
View File
@@ -24,6 +24,8 @@ model Guild {
ServiceAnnouncement_Channel String?
Purge_Limit Int @default(300)
EarlyAccess_Enabled Boolean @default(false)
}
model User {
+11
View File
@@ -26,6 +26,8 @@ import {
checkMemberPermissionsInChannel,
checkMemberPermissionsInGuild
} from '../utils/DiscordPermission';
import Cache from '../providers/Cache';
import { COMMON_EMBEDS } from './Settings';
const EMBEDS = {
PURGE_INFO: (data: HybridInteractionMessage, locale: I18n) => {
@@ -155,8 +157,17 @@ export default class Purge extends DiscordModule {
const channel = data.getGuildChannel() as GuildTextBasedChannel;
if (!channel) return;
const cachedGuild = await Cache.getCachedGuild(guild.id);
if (!cachedGuild) return;
const locale = await Locale.getGuildLocale(guild.id);
// TODO: Remove this feature when ready from early access
if (!cachedGuild.EarlyAccess_Enabled)
return await sendHybridInteractionMessageResponse(data, {
embeds: [COMMON_EMBEDS.EARLY_ACCESS_WARNING(data, locale)]
});
let query;
if (data.isMessage()) {
+138
View File
@@ -0,0 +1,138 @@
import { Guild, GuildChannel, ThreadChannel, Message, PermissionsBitField } from 'discord.js';
import { I18n } from 'i18n';
import Prisma from '../../providers/Prisma';
import Cache from '../../providers/Cache';
import { HybridInteractionMessage } from '../../utils/DiscordModule';
import {
makeInfoEmbed,
makeErrorEmbed,
makeSuccessEmbed,
sendHybridInteractionMessageResponse,
makeWarningEmbed
} from '../../utils/DiscordMessage';
import { COMMON_EMBEDS } from '.';
import { checkMemberPermissionsInGuild } from '../../utils/DiscordPermission';
const EMBEDS = {
EARLY_ACCESS_INVALID_STATUS: (data: HybridInteractionMessage, locale: I18n) => {
return makeErrorEmbed({
title: 'Invalid status, Use ``true`` or ``false``',
user: data.getUser()
});
},
NO_EARLY_ACCESS_STATUS_PROVIDED: async (
data: HybridInteractionMessage,
locale: I18n,
isServiceAnnouncementEnabled: boolean
) => {
return makeInfoEmbed({
title: 'Early Access Opt-in Status',
description: `Early Access features are ${
isServiceAnnouncementEnabled ? '**enabled**' : '**disabled**'
} on this server`,
user: data.getUser()
});
},
EARLY_ACCESS_STATUS_UPDATED: (data: HybridInteractionMessage, locale: I18n, newStatus: boolean) => {
return makeSuccessEmbed({
title: `Early Access features are now ${newStatus ? 'enabled' : 'disabled'}`,
user: data.getUser()
});
},
EARLY_ACCESS_STATUS_ALREADY_SET: (data: HybridInteractionMessage, locale: I18n, status: boolean) => {
return makeInfoEmbed({
title: `Early Access features are already ${status ? 'enabled' : 'disabled'}`,
user: data.getUser()
});
},
EARLY_ACCESS_ENABLED_WARNING: (data: HybridInteractionMessage, locale: I18n) => {
return makeWarningEmbed({
title: locale.__('early_access_warning.title'),
description: locale.__('early_access_warning.description'),
user: data.getUser()
});
}
};
export const setEnableEarlyAccess = async (data: HybridInteractionMessage, args: any, guild: Guild, locale: I18n) => {
let member = data.getMember();
if (!member) return;
if (
!(await checkMemberPermissionsInGuild({
member,
data,
locale,
permissions: [PermissionsBitField.Flags.Administrator]
}))
)
return;
let GuildCache = await Cache.getCachedGuild(guild.id);
if (!GuildCache) return;
let newStatus: string | null | undefined;
if (data.isMessage()) {
let _name: string;
if (typeof args[1] === 'undefined')
return await sendHybridInteractionMessageResponse(data, {
embeds: [await EMBEDS.NO_EARLY_ACCESS_STATUS_PROVIDED(data, locale, GuildCache.EarlyAccess_Enabled)]
});
let __name = args;
__name.shift();
_name = __name.join(' ');
newStatus = _name;
} else if (data.isApplicationCommand())
newStatus = data.getSlashCommand().options.get('status', true).value?.toString();
if (!newStatus)
return await sendHybridInteractionMessageResponse(data, {
embeds: [await EMBEDS.NO_EARLY_ACCESS_STATUS_PROVIDED(data, locale, GuildCache.EarlyAccess_Enabled)]
});
if (!['true', 'false', 'yes', 'no', 'y', 'n', 'enable', 'disable', 'on', 'off'].includes(newStatus.toLowerCase()))
return await sendHybridInteractionMessageResponse(data, {
embeds: [EMBEDS.EARLY_ACCESS_INVALID_STATUS(data, locale)]
});
const newStatusBool = ['true', 'yes', 'y', 'enable', 'on'].includes(newStatus.toLowerCase()) ? true : false;
if (GuildCache?.EarlyAccess_Enabled === newStatusBool)
return await sendHybridInteractionMessageResponse(data, {
embeds: [EMBEDS.EARLY_ACCESS_STATUS_ALREADY_SET(data, locale, newStatusBool)]
});
let placeholder = await sendHybridInteractionMessageResponse(data, {
embeds: [COMMON_EMBEDS.PROCESSING(data, locale)]
});
await Prisma.client.guild.update({
where: { id: guild.id },
data: {
EarlyAccess_Enabled: newStatusBool
}
});
await Cache.updateGuildCache(guild.id);
let toSend = [EMBEDS.EARLY_ACCESS_STATUS_UPDATED(data, locale, newStatusBool)];
if (newStatusBool) toSend.push(EMBEDS.EARLY_ACCESS_ENABLED_WARNING(data, locale));
if (data.isMessage())
return await (placeholder as Message).edit({
embeds: toSend
});
else if (data.isApplicationCommand())
return await sendHybridInteractionMessageResponse(
data,
{
embeds: toSend
},
true
);
};
+11
View File
@@ -15,6 +15,7 @@ import {
import * as PrefixModule from './Prefix';
import * as LanguageModule from './Language';
import * as ServiceAnnouncementModule from './ServiceAnnouncement';
import * as EarlyAccessModule from './EarlyAccess';
import * as PurgeLimitModule from './PurgeLimit';
export const COMMON_EMBEDS = {
@@ -49,6 +50,14 @@ export const COMMON_EMBEDS = {
description: locale.__('common.processing_description'),
user: data.getUser()
});
},
EARLY_ACCESS_WARNING: (data: HybridInteractionMessage, locale: I18n) => {
return makeInfoEmbed({
icon: '🧪',
title: locale.__('common.early_access_features'),
description: locale.__('common.early_access_features_description'),
user: data.getUser()
});
}
};
@@ -118,6 +127,8 @@ export default class Settings extends DiscordModule {
return await ServiceAnnouncementModule.setEnableServiceAnnouncement(data, args, guild, locale);
case 'serviceannouncementchannel':
return await ServiceAnnouncementModule.setServiceAnnouncementChannel(data, args, guild, locale);
case 'earlyaccess':
return await EarlyAccessModule.setEnableEarlyAccess(data, args, guild, locale);
}
}
}