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
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.
await schedule("send_message", "in 2 hours", {"channel": "general", "content": "Sale is live! 🎉"})How it works
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:
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 aremember/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 outchannel→ 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.
# 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.
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.
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.
await schedule("delete_message", "in 1 hour", {"channel": "temp", "message": 111222333444555666})pin_message
Pin a message. data: channel, message.
await schedule("pin_message", "friday 6pm", {"channel": "news", "message": 111222333444555666})unpin_message
Unpin a message. data: channel, message.
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).
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).
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.
# 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.
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).
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.
# 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.
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.
await schedule("unmute_member", "in 30 min", 725591847862534154)Channels
lock_channel
Deny @everyone Send Messages (other permissions untouched). data: channel.
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.
await schedule("unlock_channel", "tomorrow 8am", "off-topic")set_slowmode
Set a channel's slowmode. data: channel, seconds (0–21600 = 6h).
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).
await schedule("update_channel", "friday 6pm", {"channel": "stream", "name": "🔴-live-now", "topic": "We are live!"})delete_channel
Delete a channel. data: channel.
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).
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
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 waitinglist_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.