char-slop/city-role-bot

discord auto role applicator bot for charlotte polycule city

git clone https://git.t4t.associates/char-slop/city-role-bot

Charlotte Somadd color selection354c8fb

main
3.5 KiB120 linesraw
1import { ButtonStyles, ComponentTypes } from 'oceanic.js'
2import { currentColor, parseHex, setMemberColor } from '../colors.ts'
3import { button, guard, modal, slash } from '../rosepack.ts'
4
5const inGuild = [guard.guild({ message: 'this only works in a server.' })]
6
7const FAILED = 'i could not change your color. ask an admin to check that i have manage roles.'
8
9export const colorModal = modal({
10  customID: 'color/set',
11  title: 'pick a name color',
12  guards: inGuild,
13  fields: {
14    color: {
15      kind: 'text',
16      label: 'hex color',
17      placeholder: '#ff66aa',
18      minLength: 6,
19      maxLength: 7,
20      required: true,
21      style: 'short'
22    }
23  },
24
25  async execute(context) {
26    await context.defer({ ephemeral: true })
27    const hex = parseHex(context.values.color)
28    if (hex === undefined) {
29      await context.reply('that is not a hex color. try something like #ff66aa.')
30      return
31    }
32    const { guildID, member } = context.interaction
33    try {
34      await setMemberColor(context.client, guildID, member, hex)
35    } catch (error) {
36      console.error(`could not set ${member.id}'s color to ${hex} in ${guildID}:`, error)
37      await context.reply(FAILED)
38      return
39    }
40    await context.reply(`your name color is now ${hex}.`)
41  }
42})
43
44export const setColorButton = button({
45  customID: 'color/pick',
46  guards: inGuild,
47
48  async execute(context) {
49    const { guildID, member } = context.interaction
50    await context.showModal(colorModal, { values: { color: currentColor(guildID, member.roles) } })
51  }
52})
53
54export const clearColorButton = button({
55  customID: 'color/clear',
56  guards: inGuild,
57
58  async execute(context) {
59    await context.defer({ ephemeral: true })
60    const { guildID, member } = context.interaction
61    try {
62      await setMemberColor(context.client, guildID, member, undefined)
63    } catch (error) {
64      console.error(`could not clear ${member.id}'s color in ${guildID}:`, error)
65      await context.reply(FAILED)
66      return
67    }
68    await context.reply('your name color is cleared.')
69  }
70})
71
72export default slash({
73  name: 'colorpanel',
74  description: 'post a panel that lets members pick their own name color',
75  guards: [
76    guard.guild({ message: 'this command only works in a server.' }),
77    guard.userPermissions('MANAGE_ROLES', { message: 'you need manage roles to do that.' })
78  ],
79  options: {
80    message: {
81      description: 'what the panel message should say',
82      kind: 'string',
83      maxLength: 2_000
84    }
85  },
86
87  async execute(context) {
88    await context.defer({ ephemeral: true })
89    try {
90      await context.client.rest.channels.createMessage(context.interaction.channelID, {
91        content: context.options.message ?? 'pick a color for your name!',
92        components: [
93          {
94            type: ComponentTypes.ACTION_ROW,
95            components: [
96              {
97                type: ComponentTypes.BUTTON,
98                style: ButtonStyles.PRIMARY,
99                customID: setColorButton.buildID(),
100                label: 'set color'
101              },
102              {
103                type: ComponentTypes.BUTTON,
104                style: ButtonStyles.SECONDARY,
105                customID: clearColorButton.buildID(),
106                label: 'clear color'
107              }
108            ]
109          }
110        ]
111      })
112    } catch {
113      await context.reply(
114        'i could not post the panel here. check that i have view channel and send messages in this channel.'
115      )
116      return
117    }
118    await context.reply('panel posted.')
119  }
120})