(v4.2.0) Panel auto-update now uses message states
This commit is contained in:
@@ -5,6 +5,7 @@ import {opendiscord, api, utilities, openticketUtils} from "../index.js"
|
||||
import * as discord from "discord.js"
|
||||
|
||||
const generalConfig = opendiscord.configs.get("opendiscord:general")
|
||||
const panelMsgState = opendiscord.states.get("opendiscord:panel-message")
|
||||
|
||||
export async function registerCommandResponders(){
|
||||
//PANEL COMMAND RESPONDER
|
||||
@@ -36,15 +37,12 @@ export async function registerCommandResponders(){
|
||||
|
||||
await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:panel-ready").build(origin,{guild,channel,user,panel}))
|
||||
const panelMessage = await channel.send((await opendiscord.builders.messages.getSafe("opendiscord:panel").build(origin,{guild,channel,user,panel})).message)
|
||||
|
||||
//add panel to database (this way, the bot knows where all panels are located)
|
||||
const globalDatabase = opendiscord.databases.get("opendiscord:global")
|
||||
await globalDatabase.set("opendiscord:panel-message",panelMessage.channel.id+"_"+panelMessage.id,panel.id.value)
|
||||
|
||||
//add panel to database for auto-update
|
||||
if (instance.options.getBoolean("auto-update",false)){
|
||||
await globalDatabase.set("opendiscord:panel-update",panelMessage.channel.id+"_"+panelMessage.id,panel.id.value)
|
||||
}
|
||||
if (panelMessage) await panelMsgState.setMsgState({channel,message:panelMessage},{
|
||||
messageOrigin:origin,
|
||||
panelId:panel.id.value,
|
||||
panelOptionIds:panel.get("opendiscord:options").value,
|
||||
panelAutoUpdate:(instance.options.getBoolean("auto-update",false) ?? false)
|
||||
},panelMessage.flags.has("Ephemeral"))
|
||||
}),
|
||||
new api.ODWorker("opendiscord:logs",-1,(instance,params,origin,cancel) => {
|
||||
opendiscord.log(instance.user.displayName+" used the 'panel' command!","info",[
|
||||
|
||||
+34
-10
@@ -6,6 +6,7 @@ import * as discord from "discord.js"
|
||||
|
||||
const generalConfig = opendiscord.configs.get("opendiscord:general")
|
||||
const lang = opendiscord.languages
|
||||
const panelMsgState = opendiscord.states.get("opendiscord:panel-message")
|
||||
|
||||
async function checkTicketCreationPerms(instance:api.ODButtonResponderInstance|api.ODDropdownResponderInstance|api.ODModalResponderInstance|api.ODCommandResponderInstance,origin:api.ODActionManagerIdMappings["opendiscord:create-ticket-permissions"]["origin"],guild:discord.Guild,user:discord.User,option:api.ODTicketOption){
|
||||
//check ticket permissions
|
||||
@@ -82,7 +83,15 @@ export async function registerButtonResponders(){
|
||||
opendiscord.responders.buttons.add(new api.ODButtonResponder("opendiscord:ticket-option",/^od:ticket-option_/))
|
||||
opendiscord.responders.buttons.get("opendiscord:ticket-option").workers.add(
|
||||
new api.ODWorker("opendiscord:ticket-option",0,async (instance,params,origin,cancel) => {
|
||||
const {guild,channel,user} = instance
|
||||
const {guild,channel,user,message} = instance
|
||||
|
||||
//check message state
|
||||
const state = await panelMsgState.getMsgState({channel,message})
|
||||
if (!state){
|
||||
//TODO TRANSLATION!!!
|
||||
await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(origin,{guild,channel,user,error:"This panel is no longer valid or has expired. Create a new panel using `{0}` to solve the issue. It is normal to receive this error after a major Open Ticket update.".replace("{0}","/panel"),layout:"simple",customTitle:"Message State Expired"}))
|
||||
return cancel()
|
||||
}
|
||||
|
||||
//responder checks
|
||||
const isInGuild = await openticketUtils.replyIsInGuild(instance,origin)
|
||||
@@ -124,7 +133,15 @@ export async function registerDropdownResponders(){
|
||||
opendiscord.responders.dropdowns.add(new api.ODDropdownResponder("opendiscord:panel-dropdown-tickets",/^od:panel-dropdown_/))
|
||||
opendiscord.responders.dropdowns.get("opendiscord:panel-dropdown-tickets").workers.add(
|
||||
new api.ODWorker("opendiscord:panel-dropdown-tickets",0,async (instance,params,origin,cancel) => {
|
||||
const {guild,channel,user} = instance
|
||||
const {guild,channel,user,message} = instance
|
||||
|
||||
//check message state
|
||||
const state = await panelMsgState.getMsgState({channel,message})
|
||||
if (!state){
|
||||
//TODO TRANSLATION!!!
|
||||
await instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error").build(origin,{guild,channel,user,error:"This panel is no longer valid or has expired. Create a new panel using `{0}` to solve the issue. It is normal to receive this error after a major Open Ticket update.".replace("{0}","/panel"),layout:"simple",customTitle:"Message State Expired"}))
|
||||
return cancel()
|
||||
}
|
||||
|
||||
//responder checks
|
||||
const isInGuild = await openticketUtils.replyIsInGuild(instance,origin)
|
||||
@@ -159,11 +176,15 @@ export async function registerDropdownResponders(){
|
||||
}
|
||||
|
||||
//update panel after dropdown usage (reset panel choice)
|
||||
const globalDatabase = opendiscord.databases.get("opendiscord:global")
|
||||
const rawPanelId = await globalDatabase.get("opendiscord:panel-message",instance.message.channel.id+"_"+instance.message.id)
|
||||
if (rawPanelId){
|
||||
const panel = opendiscord.panels.get(rawPanelId)
|
||||
if (panel) await instance.message.edit((await opendiscord.builders.messages.getSafe("opendiscord:panel").build("auto-update",{guild,channel,user,panel})).message)
|
||||
const panel = opendiscord.panels.get(state.data.panelId)
|
||||
if (panel){
|
||||
const panelMessage = await instance.message.edit((await opendiscord.builders.messages.getSafe("opendiscord:panel").build("auto-update",{guild,channel,user,panel})).message)
|
||||
if (panelMessage) await panelMsgState.setMsgState({channel,message:panelMessage},{
|
||||
messageOrigin:"auto-update",
|
||||
panelId:panel.id.value,
|
||||
panelOptionIds:panel.get("opendiscord:options").value,
|
||||
panelAutoUpdate:state.data.panelAutoUpdate //same value
|
||||
},panelMessage.flags.has("Ephemeral"))
|
||||
}
|
||||
})
|
||||
)
|
||||
@@ -171,17 +192,21 @@ export async function registerDropdownResponders(){
|
||||
|
||||
export async function registerModalResponders(){
|
||||
//TICKET QUESTIONS RESPONDER
|
||||
opendiscord.responders.modals.add(new api.ODModalResponder("opendiscord:ticket-questions",/^od:ticket-questions_/))
|
||||
opendiscord.responders.modals.add(new api.ODModalResponder("opendiscord:ticket-questions",/^od:ticket-questions\|([^|]+)\|([^|]+)/))
|
||||
opendiscord.responders.modals.get("opendiscord:ticket-questions").workers.add([
|
||||
new api.ODWorker("opendiscord:ticket-questions",0,async (instance,params,origin,cancel) => {
|
||||
const {guild,channel,user} = instance
|
||||
|
||||
const match = /^od:ticket-questions\|([^|]+)\|([^|]+)/.exec(instance.interaction.customId)
|
||||
if (!match) return cancel()
|
||||
const optionId = match[1]
|
||||
const originalOrigin = match[2] as ("panel-button"|"panel-dropdown"|"slash"|"text"|"other")
|
||||
|
||||
//responder checks
|
||||
const isInGuild = await openticketUtils.replyIsInGuild(instance,origin)
|
||||
if (!isInGuild || !guild || !channel || channel.isDMBased()) return cancel()
|
||||
|
||||
//get option data
|
||||
const optionId = instance.interaction.customId.split("_")[1]
|
||||
const option = opendiscord.options.get(optionId)
|
||||
if (!option || !(option instanceof api.ODTicketOption)){
|
||||
instance.reply(await opendiscord.builders.messages.getSafe("opendiscord:error-option-unknown").build(origin,{guild:instance.guild,channel,user:instance.user}))
|
||||
@@ -189,7 +214,6 @@ export async function registerModalResponders(){
|
||||
}
|
||||
|
||||
//check ticket permissions (modals need check after submit)
|
||||
const originalOrigin = instance.interaction.customId.split("_")[2] as ("panel-button"|"panel-dropdown"|"slash"|"text"|"other")
|
||||
if (!(await checkTicketCreationPerms(instance,originalOrigin,guild,user,option))) return cancel()
|
||||
|
||||
//get answers
|
||||
|
||||
@@ -12,6 +12,7 @@ import { ODTicketClearFilter } from "../api/ticket.js"
|
||||
export interface ODStateManagerIdMappings extends api.ODStateManagerIdConstraint {
|
||||
"opendiscord:interactive-message":ODInteractiveMessageState,
|
||||
"opendiscord:clear-message":ODClearMessageState,
|
||||
"opendiscord:panel-message":ODPanelMessageState,
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
@@ -60,3 +61,21 @@ export class ODClearMessageState extends api.ODState<{
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**## ODPanelMessageState `class
|
||||
* A special class with state types for the Open Ticket panel message.
|
||||
*/
|
||||
export class ODPanelMessageState extends api.ODState<{
|
||||
/**The method this message was generated with. */
|
||||
messageOrigin:"slash"|"text"|"auto-update"|"other",
|
||||
/**The Id of the panel associated with this message. */
|
||||
panelId:string,
|
||||
/**A list of options available in this panel. (buttons or dropdown) */
|
||||
panelOptionIds:string[]
|
||||
/**Should this panel be auto-updated on restart? */
|
||||
panelAutoUpdate:boolean
|
||||
},false,false> {
|
||||
constructor(id:api.ODValidId,client:api.ODClientManager,database:api.ODDatabase){
|
||||
super(id,client,database,{})
|
||||
}
|
||||
}
|
||||
@@ -339,8 +339,10 @@ export const migrations = [
|
||||
}
|
||||
|
||||
//migrate database
|
||||
const globalDatabase = opendiscord.databases.get("opendiscord:global")
|
||||
const optionDatabase = opendiscord.databases.get("opendiscord:options")
|
||||
const ticketDatabase = opendiscord.databases.get("opendiscord:tickets")
|
||||
const stateDatabase = opendiscord.databases.get("opendiscord:message-states")
|
||||
|
||||
for (const option of (await optionDatabase.getCategory("opendiscord:used-option") ?? [])){
|
||||
const optionData = option.value
|
||||
@@ -359,6 +361,34 @@ export const migrations = [
|
||||
|
||||
ticketDatabase.set("opendiscord:ticket",ticket.key,ticketData)
|
||||
}
|
||||
|
||||
//migrate old panel messages from global.json to the new message states
|
||||
const migratedPanelStates: {channelId:string,messageId:string,panelId:string,autoUpdate:boolean}[] = []
|
||||
opendiscord.events.get("afterClientReady").listen(async () => {
|
||||
for (const panelMessage of (await globalDatabase.getCategory("opendiscord:panel-message") ?? [])){
|
||||
const splittedId = panelMessage.key.split("_")
|
||||
const channelId = splittedId[0]
|
||||
const messageId = splittedId[1]
|
||||
const message = await opendiscord.client.fetchChannelMessage(channelId,messageId)
|
||||
const autoUpdate = typeof (await globalDatabase.get("opendiscord:panel-update",panelMessage.key)) == "string"
|
||||
//if message still exists
|
||||
if (message) migratedPanelStates.push({channelId,messageId,panelId:panelMessage.value,autoUpdate})
|
||||
|
||||
await globalDatabase.delete("opendiscord:panel-message",panelMessage.key)
|
||||
await globalDatabase.delete("opendiscord:panel-update",panelMessage.key)
|
||||
}
|
||||
})
|
||||
opendiscord.events.get("afterStatesInitiated").listen(async (states) => {
|
||||
const panelMsgState = states.get("opendiscord:panel-message")
|
||||
for (const {channelId,messageId,panelId,autoUpdate} of migratedPanelStates){
|
||||
await panelMsgState.setMsgState({channel:channelId,message:messageId},{
|
||||
messageOrigin:"auto-update",
|
||||
panelId,
|
||||
panelOptionIds:[],
|
||||
panelAutoUpdate:autoUpdate
|
||||
},false)
|
||||
}
|
||||
})
|
||||
}
|
||||
}),
|
||||
]
|
||||
@@ -69,38 +69,6 @@ export async function loadStartListeningInteractionsCode(){
|
||||
export async function loadDatabaseCleanersCode(){
|
||||
if (!mainServer) return
|
||||
|
||||
//PANEL DATABASE CLEANER
|
||||
opendiscord.code.add(new api.ODCode("opendiscord:panel-database-cleaner",12,async () => {
|
||||
const validPanels: string[] = []
|
||||
|
||||
//check global database for valid panel embeds
|
||||
for (const panel of (await globalDatabase.getCategory("opendiscord:panel-message") ?? [])){
|
||||
if (!validPanels.includes(panel.key)){
|
||||
try{
|
||||
const splittedId = panel.key.split("_")
|
||||
const message = await opendiscord.client.fetchChannelMessage(splittedId[0],splittedId[1])
|
||||
if (message) validPanels.push(panel.key)
|
||||
}catch{}
|
||||
}
|
||||
}
|
||||
|
||||
//remove all unused panels
|
||||
for (const panel of (await globalDatabase.getCategory("opendiscord:panel-message") ?? [])){
|
||||
if (!validPanels.includes(panel.key)){
|
||||
await globalDatabase.delete("opendiscord:panel-message",panel.key)
|
||||
await globalDatabase.delete("opendiscord:panel-update",panel.key)
|
||||
}
|
||||
}
|
||||
|
||||
//delete panel from database on delete
|
||||
opendiscord.client.client.on("messageDelete",async (msg) => {
|
||||
if (await globalDatabase.exists("opendiscord:panel-message",msg.channel.id+"_"+msg.id)){
|
||||
await globalDatabase.delete("opendiscord:panel-message",msg.channel.id+"_"+msg.id)
|
||||
await globalDatabase.delete("opendiscord:panel-update",msg.channel.id+"_"+msg.id)
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
//SUFFIX DATABASE CLEANER
|
||||
opendiscord.code.add(new api.ODCode("opendiscord:suffix-database-cleaner",11,async () => {
|
||||
const validSuffixCounters: string[] = []
|
||||
@@ -284,34 +252,43 @@ export async function loadDatabaseCleanersCode(){
|
||||
|
||||
export async function loadPanelAutoUpdateCode(){
|
||||
//PANEL AUTO UPDATE
|
||||
const panelMsgState = opendiscord.states.get("opendiscord:panel-message")
|
||||
opendiscord.code.add(new api.ODCode("opendiscord:panel-auto-update",7,async () => {
|
||||
const globalDatabase = opendiscord.databases.get("opendiscord:global")
|
||||
const panelIds = await globalDatabase.getCategory("opendiscord:panel-update") ?? []
|
||||
if (!mainServer) return
|
||||
|
||||
for (const panelId of panelIds){
|
||||
const panel = opendiscord.panels.get(panelId.value)
|
||||
|
||||
//panel doesn't exist anymore in config and needs to be removed
|
||||
if (!panel){
|
||||
globalDatabase.delete("opendiscord:panel-update",panelId.key)
|
||||
return
|
||||
}
|
||||
|
||||
for (const panelState of (await panelMsgState.listMsgStates()).map((rawState) => rawState.value)){
|
||||
try{
|
||||
const splittedId = panelId.key.split("_")
|
||||
const channel = await opendiscord.client.fetchGuildTextChannel(mainServer,splittedId[0])
|
||||
if (!channel) return
|
||||
const message = await opendiscord.client.fetchChannelMessage(channel,splittedId[1])
|
||||
if (!message || !message.editable) return
|
||||
//fetch panel (& check if auto-update is required)
|
||||
const panel = opendiscord.panels.get(panelState.data.panelId)
|
||||
if (!panel || !panelState.data.panelAutoUpdate) continue
|
||||
|
||||
//fetch panel channel
|
||||
const channel = await opendiscord.client.fetchGuildTextChannel(mainServer,panelState.channelId)
|
||||
if (!channel) continue
|
||||
|
||||
//fetch panel message
|
||||
const message = await opendiscord.client.fetchChannelMessage(channel,panelState.messageId)
|
||||
if (!message || !message.editable || message.flags.has("Ephemeral")) continue
|
||||
|
||||
const panelMessage = await message.edit((await opendiscord.builders.messages.getSafe("opendiscord:panel").build("auto-update",{guild:mainServer,channel,user:opendiscord.client.client.user,panel})).message)
|
||||
if (panelMessage) await panelMsgState.setMsgState({channel,message:panelMessage},{
|
||||
messageOrigin:"auto-update",
|
||||
panelId:panel.id.value,
|
||||
panelOptionIds:panel.get("opendiscord:options").value,
|
||||
panelAutoUpdate:true
|
||||
},panelMessage.flags.has("Ephemeral"))
|
||||
|
||||
message.edit((await opendiscord.builders.messages.getSafe("opendiscord:panel").build("auto-update",{guild:mainServer,channel,user:opendiscord.client.client.user,panel})).message)
|
||||
opendiscord.log("Panel in server got auto-updated!","info",[
|
||||
{key:"channelid",value:splittedId[0]},
|
||||
{key:"messageid",value:splittedId[1]},
|
||||
{key:"panel",value:panelId.value}
|
||||
{key:"channelid",value:panelState.channelId},
|
||||
{key:"messageid",value:panelState.messageId},
|
||||
{key:"panel",value:panel.id.value}
|
||||
])
|
||||
}catch{}
|
||||
}catch{
|
||||
opendiscord.log("Failed to auto-update panel","error",[
|
||||
{key:"channelid",value:panelState.channelId},
|
||||
{key:"messageid",value:panelState.messageId}
|
||||
])
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -5,4 +5,5 @@ export async function loadAllStates(){
|
||||
|
||||
opendiscord.states.add(new api.ODInteractiveMessageState("opendiscord:interactive-message",opendiscord.client,stateDatabase))
|
||||
opendiscord.states.add(new api.ODClearMessageState("opendiscord:clear-message",opendiscord.client,stateDatabase))
|
||||
opendiscord.states.add(new api.ODPanelMessageState("opendiscord:panel-message",opendiscord.client,stateDatabase))
|
||||
}
|
||||
Reference in New Issue
Block a user