Custom Commands homeCustom Commands
  • Blog
  • Privacy
  • Premium
  • Support
Back to blog
// blog

Schedule Anything using Custom Commands — One Line, No Setup

Schedule anything from temp bans to timed announcements with one line of code — no clock events or boilerplate needed.

Md Shahriyar Alam

a day ago

·6 min read

Ever wanted a command to do something later? Ban someone for three days and auto-unban them. Lock a channel at night and open it in the morning. Post an announcement at 6pm on Friday. Delete a message after an hour.

Until now that meant wiring up a clock event and writing the handler yourself. Not anymore. schedule runs a built-in action at a future time — no clock event, no boilerplate.

py
await schedule("send_message", "in 2 hours", {"channel": "general", "content": "Sale is live! 🎉"})

How it works

py
await schedule(action, when, data, member=None, channel=None)
  • action — the name of the action to run (all 20 are below).
  • when — a friendly time ("in 10 minutes", "tomorrow 8pm", "next friday 7pm") or an exact UTC datetime.
  • data — the details for the action. Almost always a dict. A bare value is only accepted as a shorthand for a single-field action (noted per action below).
  • member / channel (optional) — override the default target. Omit them and the action uses the member/channel the command is running in.

It returns an id — keep it if you want to cancel the schedule later:

py
id = await schedule("ban_member", "in 3 days", {"member": 123, "reason": "cooldown"})
await cancel_schedule(id)

⚠️ There is no positional "content" argument. The 3rd argument is always data, and the 4th/5th are member/channel. To send text to a specific channel you must use the dict form: {"channel": ..., "content": ...}.

Times, references, defaults

  • Times are natural ("in 30 minutes", "tomorrow 9am", "august 5 6pm") or an exact datetime. UTC, and must be in the future.
  • Channels & roles are referenced by id or name. Members by id or mention. Everything must belong to your server — foreign ids are rejected when you schedule.
  • Defaults: leave out member → the command's member; leave out channel → the command's channel; message → the message that triggered the command (in message/reaction events).

Action reference

Every action, its data, and a real example. Bold fields are required.

Messages

send_message

Post a message. data: channel, content, embed — needs content or embed. embed is a saved embed id (rebuilt when it sends) or a live embed object.

py
# to a specific channel
await schedule("send_message", "friday 6pm", {
    "channel": "announcements",
    "content": "Weekend event starting now!",
})

# with a saved embed (by its id, from the dashboard)
await schedule("send_message", "friday 6pm", {"channel": "news", "embed": "cl9k2m4x0000"})

# content + a live embed built in the command
embed = load_embed("cl9k2m4x0000")
await schedule("send_message", "friday 6pm", {"channel": "news", "content": "It's live!", "embed": embed})

# shorthand: bare string -> content, in the CURRENT channel
await schedule("send_message", "in 5 min", "Heads up, chat!")

send_dm

DM a member. data: member, content, embed — needs content or embed. The member must be in your server.

py
await schedule("send_dm", "in 1 hour", {"member": 725591847862534154, "content": "Your trial ends soon!"})

# with an embed
await schedule("send_dm", "in 1 hour", {"member": 725591847862534154, "embed": "cl9k2m4x0000"})

# shorthand: bare string -> content, to the CURRENT member
await schedule("send_dm", "in 1 hour", "Thanks for joining!")

edit_message

Replace a message's content. data: channel, message, content.

py
await schedule("edit_message", "in 10 min", {
    "channel": "announcements",
    "message": 111222333444555666,
    "content": "Updated: the event has started!",
})

delete_message

Delete a message. data: channel, message.

py
await schedule("delete_message", "in 1 hour", {"channel": "temp", "message": 111222333444555666})

pin_message

Pin a message. data: channel, message.

py
await schedule("pin_message", "friday 6pm", {"channel": "news", "message": 111222333444555666})

unpin_message

Unpin a message. data: channel, message.

py
await schedule("unpin_message", "monday 9am", {"channel": "news", "message": 111222333444555666})

purge_messages

Bulk-delete recent messages (under 14 days old). data: channel, amount (1–100).

py
await schedule("purge_messages", "tonight 11pm", {"channel": "spam", "amount": 50})

# shorthand: bare number -> amount, in the CURRENT channel
await schedule("purge_messages", "tonight 11pm", 50)

Members & roles

add_role

Give a member one or more roles. data: member, roles (a role or a list; ids or names).

py
await schedule("add_role", "in 1 hour", {"member": 725591847862534154, "roles": "VIP"})
await schedule("add_role", "in 1 hour", {"member": 725591847862534154, "roles": ["VIP", "Member"]})

# shorthand: bare role/list -> applied to the CURRENT member
await schedule("add_role", "in 1 hour", ["VIP", "Member"])

remove_role

Remove one or more roles. Same shape as add_role.

py
# classic temp role: grant now, remove later
await add_role(member, "VIP")
await schedule("remove_role", "in 24 hours", {"member": member.id, "roles": "VIP"})

kick_member

Kick a member. data: member, reason.

py
await schedule("kick_member", "in 10 min", {"member": 725591847862534154, "reason": "afk too long"})

# shorthand: bare member id/mention
await schedule("kick_member", "in 10 min", 725591847862534154)

ban_member

Ban a member. data: member, reason, delete_days (0–7, how much message history to purge).

py
await schedule("ban_member", "in 5 min", {"member": 725591847862534154, "reason": "raid", "delete_days": 1})

# shorthand: bare member id/mention
await schedule("ban_member", "in 5 min", 725591847862534154)

unban_member

Lift a ban. data: user, reason. Works by id even though they aren't in the server.

py
# temp ban -> auto unban
await ban_member(user, "cooldown")
await schedule("unban_member", "in 7 days", {"user": user.id})

# shorthand: bare user id
await schedule("unban_member", "in 7 days", 725591847862534154)

mute_member

Server-voice mute. data: member.

py
await schedule("mute_member", "in 2 min", {"member": 725591847862534154})

# shorthand: bare member
await schedule("mute_member", "in 2 min", 725591847862534154)

unmute_member

Server-voice unmute. data: member.

py
await schedule("unmute_member", "in 30 min", 725591847862534154)

Channels

lock_channel

Deny @everyone Send Messages (other permissions untouched). data: channel.

py
await schedule("lock_channel", "tonight 11pm", {"channel": "off-topic"})

# shorthand: bare channel (id or name)
await schedule("lock_channel", "tonight 11pm", "off-topic")

unlock_channel

Re-allow Send Messages. data: channel.

py
await schedule("unlock_channel", "tomorrow 8am", "off-topic")

set_slowmode

Set a channel's slowmode. data: channel, seconds (0–21600 = 6h).

py
await schedule("set_slowmode", "friday 8pm", {"channel": "general", "seconds": 30})

# shorthand: bare number -> seconds, in the CURRENT channel
await schedule("set_slowmode", "friday 8pm", 30)

update_channel

Change a channel's settings. data: channel, plus any of name, topic, nsfw, slowmode (0–21600).

py
await schedule("update_channel", "friday 6pm", {"channel": "stream", "name": "🔴-live-now", "topic": "We are live!"})

delete_channel

Delete a channel. data: channel.

py
await schedule("delete_channel", "in 24 hours", {"channel": "temp-event"})

# shorthand: bare channel
await schedule("delete_channel", "in 24 hours", "temp-event")

Engagement

create_poll

Open a Discord poll. data: channel, question, answers (2–10), duration (hours, 1–768, default 24), multiselect (default false).

py
await schedule("create_poll", "friday 6pm", {
    "channel": "polls",
    "question": "Which map next weekend?",
    "answers": ["Dust", "Nuke", "Mirage"],
    "duration": 48,
    "multiselect": False,
})

Manage what you scheduled

py
id = await schedule("ban_member", "in 3 days", {"member": 123})
await cancel_schedule(id)          # cancel by the id you got back
pending = await list_schedules()    # everything still waiting

list_schedules() returns each pending item's id, action, run_at and data.

Safe by design

  • Stays in your server. Foreign channel/role/member ids are rejected the moment you schedule — a scheduled action can only touch your own guild.
  • Survives restarts. Pending schedules are stored and re-armed when the bot comes back.
  • Clear errors. Unknown action, missing target, past time, wrong permissions — you're told exactly what's wrong up front.

Premium

schedule is a premium feature. Upgrade your server to unlock it.


Set it, forget it, and let your commands work on your schedule.

Loading comments…

{}

Need help?

Have a question, a suggestion, or stuck on something? Reach out — we're happy to help.

DiscordJoin support server
Custom CommandsCustom Commands

The #1 custom commands Discord bot — build commands, events and databases with zero boilerplate.

Links

HomeBlogPrivacySupport

Contact

[email protected]

2 Frederick StreetLondon, WC1X 0ND

{ / } custom commands

© WEiRDSOFT LTD. All rights reserved.