-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #38 from Arcoz0308/feature/primes
Feature/primes and update to discord.js v14.12
- Loading branch information
Showing
21 changed files
with
470 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import type {ChatInputCommandInteraction} from 'discord.js'; | ||
import type {Result} from 'rustic-error'; | ||
import {ok} from 'rustic-error'; | ||
import type {CommandError} from '$core/utils/error'; | ||
import {globalConfig} from '$core/config/global'; | ||
import {sendCommandReply} from '$core/handlers/commands'; | ||
import {errorEmbed} from '$core/utils/discord'; | ||
import {commandsConfig} from '$core/config/message/command'; | ||
|
||
/** | ||
* If is owner, return false for code facility | ||
*/ | ||
export const ownerOnly = async (interaction: ChatInputCommandInteraction, defer = true): Promise<Result<boolean, CommandError>> => { | ||
if (!globalConfig.owners.includes(interaction.user.id)) { | ||
return sendCommandReply(interaction, {embeds: [errorEmbed(commandsConfig.admin.exec.ownerOnly)]}, defer); | ||
} | ||
return ok(false); | ||
}; |
89 changes: 89 additions & 0 deletions
89
src/commands/globals/other/admin/prime_staff/prime_staff.class.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import {SubCommand} from '$core/handlers/commands'; | ||
import {commandsConfig} from '$core/config/message/command'; | ||
import type {Result} from 'rustic-error'; | ||
import {error, ok, resultify} from 'rustic-error'; | ||
import {CommandError} from '$core/utils/error'; | ||
import type {ChatInputCommandInteraction, EmbedBuilder} from 'discord.js'; | ||
import {userMention} from 'discord.js'; | ||
import {ownerOnly} from '$core/commands/globals/other/admin/admin.util'; | ||
import {getPrimes} from '$core/commands/globals/other/admin/prime_staff/prime_staff.util'; | ||
import {errorEmbed, simpleEmbed} from '$core/utils/discord'; | ||
import {msgParams} from '$core/utils/function/string'; | ||
import {confirmIds, getConfirmButtons} from '$core/handlers/buttons/confirm'; | ||
|
||
const config = commandsConfig.admin.exec.primeStaff; | ||
|
||
export class PrimeStaff extends SubCommand { | ||
name = commandsConfig.admin.subcmds.primeStaff.name; | ||
preReply = { | ||
enable: true, | ||
ephemeral: false | ||
}; | ||
|
||
async run(interaction: ChatInputCommandInteraction): Promise<Result<boolean, CommandError>> { | ||
const ownerOnlyResult = await ownerOnly(interaction); | ||
if (!ownerOnlyResult.ok) { | ||
return error(ownerOnlyResult.error); | ||
} | ||
if (ownerOnlyResult.value) { | ||
return ok(false); | ||
} | ||
|
||
const primeResult = await getPrimes(); | ||
if (!primeResult.ok) { | ||
return error(new CommandError('failed to get staff primes', interaction, primeResult.error)); | ||
} | ||
|
||
if (typeof primeResult.value === 'string') { | ||
return this.sendReply(interaction, {embeds: [errorEmbed(primeResult.value)]}); | ||
} | ||
|
||
const infos: string[] = []; | ||
for (const prime of primeResult.value) { | ||
infos.push(msgParams(config.primeInfo, [ | ||
userMention(prime.userId), | ||
prime.role, | ||
prime.username, | ||
prime.totalPrime, | ||
prime.prime, | ||
prime.associationPrime | ||
])); | ||
} | ||
|
||
const embeds: EmbedBuilder[] = []; | ||
|
||
|
||
// thx https://stackoverflow.com/a/8495740 | ||
const chunkSize = 30; | ||
for (let i = 0; i < infos.length; i += chunkSize) { | ||
const chunk = infos.slice(i, i + chunkSize); | ||
embeds.push(simpleEmbed(chunk.join('\n'))); | ||
} | ||
|
||
const replyResult = await this.sendReply(interaction, { | ||
embeds: [embeds[0].setTitle(config.primeInfoTitle)] | ||
}); | ||
if (!replyResult.ok) { | ||
return error(replyResult.error); | ||
} | ||
|
||
for (const embed of embeds.slice(1)) { | ||
const result = await resultify(() => interaction.followUp({ | ||
embeds: [embed] | ||
})); | ||
if (!result.ok) { | ||
return error(new CommandError('failed to followUp interaction', interaction, result.error)); | ||
} | ||
} | ||
|
||
const result = await resultify(() => interaction.followUp({ | ||
embeds: [simpleEmbed(config.primeDescription)], | ||
components: getConfirmButtons(confirmIds.primeStaff) | ||
})); | ||
if (!result.ok) { | ||
return error(new CommandError('failed to followUp interaction', interaction, result.error)); | ||
} | ||
return ok(true); | ||
|
||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/commands/globals/other/admin/prime_staff/prime_staff.type.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import type {Snowflake} from 'discord-api-types/globals'; | ||
|
||
export type PrimeInfos = { | ||
username: string; | ||
role: string; | ||
prime: number; | ||
associationPrime: number; | ||
totalPrime: number; | ||
userId: Snowflake; | ||
} |
95 changes: 95 additions & 0 deletions
95
src/commands/globals/other/admin/prime_staff/prime_staff.util.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import {google} from 'googleapis'; | ||
import {env} from '$core/config/env'; | ||
import type {PrimeInfos} from '$core/commands/globals/other/admin/prime_staff/prime_staff.type'; | ||
import {msgParams} from '$core/utils/function/string'; | ||
import {commandsConfig} from '$core/config/message/command'; | ||
import type {Result} from 'rustic-error'; | ||
import {error, ok} from 'rustic-error'; | ||
import {anyToError} from '$core/utils/error'; | ||
|
||
let lastSavedPrimes: PrimeInfos[] | undefined; | ||
|
||
export const getSavedPrimes = () => lastSavedPrimes; | ||
|
||
const getIndexes = (header: string[]): Record<keyof PrimeInfos, number> | string => { | ||
const baseIndexes = { | ||
'Adhesion Asso': header.findIndex(v => v === 'Adhésion Asso'), | ||
'Primes': header.findIndex(v => v === 'Primes'), | ||
'Poste': header.findIndex(v => v === 'Poste'), | ||
'TOTAL Sans Bonus': header.findIndex(v => v === 'TOTAL Sans Bonus'), | ||
'Idd': header.findIndex(v => v === 'Idd'), | ||
'Pseudo': header.findIndex(v => v === 'Pseudo') | ||
}; | ||
let msg = ''; | ||
for (const [key, value] of Object.entries(baseIndexes)) { | ||
if (value < 0) { | ||
msg += `${msgParams(commandsConfig.admin.exec.primeStaff.columnNotFound, [key])}\n`; | ||
} | ||
} | ||
if (msg !== '') { | ||
return msg; | ||
} | ||
|
||
return { | ||
associationPrime: baseIndexes['Adhesion Asso'], | ||
prime: baseIndexes.Primes, | ||
role: baseIndexes.Poste, | ||
totalPrime: baseIndexes['TOTAL Sans Bonus'], | ||
userId: baseIndexes.Idd, | ||
username: baseIndexes.Pseudo | ||
}; | ||
}; | ||
|
||
export const getPrimes = async (): Promise<Result<PrimeInfos[] | string, Error>> => { | ||
try { | ||
const auth = new google.auth.GoogleAuth({ | ||
scopes: [ | ||
'https://www.googleapis.com/auth/spreadsheets' | ||
], | ||
credentials: { | ||
private_key: env.GOOGLE_PRIVATE_KEY.split(String.raw`\n`).join('\n'), | ||
client_email: env.GOOGLE_MAIL | ||
} | ||
}); | ||
const sheets = google.sheets({ | ||
version: 'v4', | ||
auth: auth | ||
}); | ||
const res = await sheets.spreadsheets.values.get({ | ||
spreadsheetId: env.GOOGLE_SHEETS_ID, | ||
range: 'Registre Staff!A:I' | ||
}); | ||
|
||
if (res.data.values === null || typeof res.data.values === 'undefined' || | ||
res.data.values.length === 0 || res.data.values[0].length === 0) { | ||
|
||
return error(new Error('No rows gets')); | ||
} | ||
const indexes = getIndexes(res.data.values[0]); | ||
if (typeof indexes === 'string') { | ||
return ok(indexes); | ||
} | ||
|
||
const primes: PrimeInfos[] = []; | ||
|
||
for (const row of res.data.values.slice(1)) { | ||
const prime: PrimeInfos = { | ||
associationPrime: parseInt(row[indexes.associationPrime], 10), | ||
prime: parseInt(row[indexes.prime], 10), | ||
role: row[indexes.role], | ||
totalPrime: parseInt(row[indexes.totalPrime], 10), | ||
userId: row[indexes.userId], | ||
username: row[indexes.username] | ||
}; | ||
if (!Object.values(prime).includes('')) { | ||
primes.push(prime); | ||
} | ||
} | ||
lastSavedPrimes = primes; | ||
return ok(primes); | ||
} catch (e) { | ||
return error(new Error(`failed to get prime staff infos, error : ${anyToError(e).message}`)); | ||
} | ||
}; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.