Payloads in Custom IDs

Sometimes, you might run into a use case where you need to pass custom data into your modal or button handlers that just isn't available from the Interaction object itself, like timestamps or custom input.

To solve this issue, you can pass extra data when you create your message component by adding setting them in your Custom ID separated by a pipe (|).

Passing Data to Custom IDs

To attach extra data in your Custom IDs, add them in front of your actual ID separated by the Pipe (|) character.

TIP

You can use any string format you prefer, like CSV or JSON.

WARNING

The 100-character Custom ID limit still applies!

import { defineSlashCommand } from 'chooksie'
import { MessageActionRow, MessageButton } from 'discord.js'

export default defineSlashCommand({
  name: 'timer',
  description: 'Starts a timer.',
  async execute(ctx) {
    const now = Date.now()

    const button = new MessageButton()
      .setCustomId(`timer-end|${now}`)
      .setEmoji('⏱️')
      .setLabel('Stop Timer')
      .setStyle('DANGER')

    const row = new MessageActionRow()
      .addComponents(button)

    await ctx.interaction.reply({
      content: 'Timer started!',
      components: [row],
    })
  },
})










 













import { defineSlashCommand } from 'chooksie'
import { MessageActionRow, MessageButton } from 'discord.js'

export default defineSlashCommand({
  name: 'timer',
  description: 'Starts a timer.',
  async execute(ctx) {
    const now = Date.now()

    const button = new MessageButton()
      .setCustomId(`timer-end|${now}`)
      .setEmoji('⏱️')
      .setLabel('Stop Timer')
      .setStyle('DANGER')

    const row = new MessageActionRow()
      .addComponents(button)

    await ctx.interaction.reply({
      content: 'Timer started!',
      components: [row],
    })
  },
})










 













const { defineSlashCommand } = require('chooksie')
const { MessageActionRow, MessageButton } = require('discord.js')

module.exports = defineSlashCommand({
  name: 'timer',
  description: 'Starts a timer.',
  async execute(ctx) {
    const now = Date.now()

    const button = new MessageButton()
      .setCustomId(`timer-end|${now}`)
      .setEmoji('⏱️')
      .setLabel('Stop Timer')
      .setStyle('DANGER')

    const row = new MessageActionRow()
      .addComponents(button)

    await ctx.interaction.reply({
      content: 'Timer started!',
      components: [row],
    })
  },
})










 













Getting Data from Custom IDs

Everything past the first | character are then passed as a string into your handlers via the payload prop.

WARNING

The payload property is null by default.

import { defineButtonHandler } from 'chooksie'

export default defineButtonHandler({
  customId: 'timer-end',
  async execute(ctx) {
    const now = Date.now()
    const startTime = Number(ctx.payload)

    const elapsed = now - startTime

    await ctx.interaction.reply({
      content: `Timer ended! Time elapsed: ${elapsed.toLocaleString()}ms`,
      ephemeral: true,
    })
  },
})



 


 









import { defineButtonHandler } from 'chooksie'

export default defineButtonHandler({
  customId: 'timer-end',
  async execute(ctx) {
    const now = Date.now()
    const startTime = Number(ctx.payload)

    const elapsed = now - startTime

    await ctx.interaction.reply({
      content: `Timer ended! Time elapsed: ${elapsed.toLocaleString()}ms`,
      ephemeral: true,
    })
  },
})



 


 









const { defineButtonHandler } = require('chooksie')

module.exports = defineButtonHandler({
  customId: 'timer-end',
  async execute(ctx) {
    const now = Date.now()
    const startTime = Number(ctx.payload)

    const elapsed = now - startTime

    await ctx.interaction.reply({
      content: `Timer ended! Time elapsed: ${elapsed.toLocaleString()}ms`,
      ephemeral: true,
    })
  },
})