Slack status scheduler
Plan statuses that repeat, like lunch every weekday or a focus block on Tuesdays, and put them into Slack's own scheduler with one paste. Slack holds 5 scheduled statuses; this page shows which 5 go in and when to add the next.
Your routine
16/100
28/100
24/100
Your next 7 days
Numbered blocks fill Slack's 5 slots
Hatched blocks wait for a free slot. Click a block to see it in Slack below.
What goes into Slack's 5 slots
- 1free
- 2free
- 3free
- 4free
- 5free
What your team sees
Add a status to see it here.
Put it in Slack
- Open your workspace at app.slack.com in this browser.
- Open the console: Cmd+Option+J on a Mac, Ctrl+Shift+J on Windows. Chrome asks you to type
allow pastingthe first time. - Paste the script and press Enter. It adds the times above to Set a status > Scheduled and lists them.
Read the script (91 lines)
// Slack status schedule from https://slack.green/en/tools/slack-status-scheduler
// Paste into the console of your Slack tab (app.slack.com). It fills Slack's
// 5 scheduled-status slots with the next times from this plan, as you, using
// the same call as Set a status > Duration > Choose a start and end time.
// Times are in this computer's time zone. Paste it again any week.
(async () => {
const SLOTS = 5
const PLAN = [
{"kind":"weekly","emoji":"sandwich","text":"Lunch, back at 1","days":[1,2,3,4,5],"start":"12:00","end":"13:00","pause":false},
{"kind":"weekly","emoji":"headphones","text":"Focus time, replies after 11","days":[2,4],"start":"09:00","end":"11:00","pause":true},
{"kind":"weekly","emoji":"children_crossing","text":"School run, back at 3:30","days":[1,2,3,4,5],"start":"15:00","end":"15:30","pause":false}
]
const ERRORS = {
"too_many_scheduled_statuses": "Slack already holds 5 scheduled statuses",
"date_scheduled_in_past": "the start has passed",
"date_expire_before_scheduled": "the end is before the start",
"text_too_long": "the text is over 100 characters",
"invalid_emoji": "this workspace has no emoji with that name"
}
const teamId = (location.pathname.match(/\/client\/([TE][A-Z0-9]+)/) || [])[1]
const teams = JSON.parse(localStorage.getItem('localConfig_v2') || '{}').teams || {}
const team = teams[teamId] || Object.values(teams)[0]
if (!team || !team.token) return alert('Open your workspace at app.slack.com in this tab first.')
async function api(method, fields) {
const body = new FormData()
body.append('token', team.token)
for (const [key, value] of Object.entries(fields)) body.append(key, value)
const res = await fetch('/api/' + method, { method: 'POST', body, credentials: 'include' })
return res.json()
}
function nextOccurrences(plan, nowMs, count) {
const mins = (t) => Number(t.slice(0, 2)) * 60 + Number(t.slice(3, 5))
const out = []
for (const s of plan) {
if (s.kind === 'once') {
const start = new Date(s.start).getTime()
const end = new Date(s.end).getTime()
if (start > nowMs && end > start) out.push({ ...s, start: start / 1000, end: end / 1000 })
continue
}
const from = mins(s.start)
let to = mins(s.end)
if (to <= from) to += 24 * 60
const today = new Date(nowMs)
for (let offset = 0; offset < 56; offset++) {
const day = new Date(today.getFullYear(), today.getMonth(), today.getDate() + offset)
if (!s.days.includes(day.getDay())) continue
const start = new Date(day.getFullYear(), day.getMonth(), day.getDate(), 0, from).getTime()
const end = new Date(day.getFullYear(), day.getMonth(), day.getDate(), 0, to).getTime()
if (start > nowMs) out.push({ ...s, start: start / 1000, end: end / 1000 })
}
}
out.sort((a, b) => a.start - b.start || a.end - b.end)
return out.slice(0, count)
}
const when = (s) => new Date(s * 1000).toLocaleString([], { weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' })
const list = await api('users.customStatus.list', {})
if (!list.ok) return alert('Could not read your scheduled statuses: ' + list.error)
const queued = list.scheduled_statuses || []
const key = (emoji, text, start) => emoji + '|' + text + '|' + start
const have = new Set(queued.map((s) => key(s.emoji, s.text, s.date_scheduled)))
const next = nextOccurrences(PLAN, Date.now() + 60000, SLOTS)
const todo = next.filter((o) => !have.has(key(o.emoji ? ':' + o.emoji + ':' : '', o.text, o.start)))
const lines = []
let free = SLOTS - queued.length
for (const o of todo) {
const label = when(o.start) + ' ' + (o.emoji ? ':' + o.emoji + ': ' : '') + o.text
if (free <= 0) { lines.push('not added, no free slot: ' + label); continue }
const res = await api('users.customStatus.schedule', {
emoji: o.emoji ? ':' + o.emoji + ':' : '',
text: o.text,
date_scheduled: String(o.start),
date_expire: String(o.end),
is_dnd: String(o.pause),
duration: 'custom',
})
if (res.ok) { free--; lines.push('added: ' + label) }
else lines.push('failed, ' + (ERRORS[res.error] || res.error) + ': ' + label)
}
const after = await api('users.customStatus.list', {})
const now = (after.scheduled_statuses || []).sort((a, b) => a.date_scheduled - b.date_scheduled)
lines.push('Slack now holds ' + now.length + ' of ' + SLOTS + ' scheduled statuses:')
for (const s of now) lines.push(' ' + when(s.date_scheduled) + ' to ' + when(s.date_expire) + ' ' + s.emoji + ' ' + s.text)
if (now.length) lines.push('Paste this again after ' + when(now[0].date_scheduled) + ' to queue the next one.')
console.log(lines.join('\n'))
alert(lines.join('\n'))
})()
Or add them by hand in Slack
How to schedule a repeating Slack status
- Edit the statuses above or add one: an emoji, the text, the days, and a start and end time. Time off is a one-off range.
- Check the week. The numbered blocks are the next 5 times, the ones that go into Slack. Click a block to see the status the way your team sees it.
- Click Copy script, open your workspace at app.slack.com, open the browser console, paste, and press Enter. The times show up in Set a status under Scheduled.
- Keep the script. When the first status starts, Slack frees its slot, so paste the same script again later in the week to queue the next one.
Frequently asked questions
Can you schedule a Slack status?
Yes, once at a time. Click your photo, Update your status, write the status, open Duration and pick Choose a start and end time. The start and end lists step by 30 minutes. Slack keeps the status under Scheduled and turns it on and off with your computer off: in our test on 1 October 2026 a scheduled status went live within 29 seconds of its start.
How many statuses can I schedule in Slack?
Five. A sixth is refused with the error too_many_scheduled_statuses, which we got in a test workspace. A slot frees when its status starts, not when it ends, so with lunch every weekday the 5 slots cover one work week. That is why this page counts the slots for you and the script tops them up each time you paste it.
Can a Slack status repeat every day?
Not in Slack itself; every scheduled status runs once. Your options are this page, which refills Slack's 5 slots from a weekly plan each time you paste the script; a recurring calendar event with Slack's calendar sync, which shows In a meeting rather than your own words; or a Marketplace app such as Status Scheduler, which you install and authorize.
Is the script safe to paste into the console?
Read it first; the whole script is on this page. It uses the session of the Slack tab you paste it into and calls only Slack's own users.customStatus.list and users.customStatus.schedule, the call the Set a status dialog makes when you save a scheduled status. It sends nothing to slack.green. Chrome asks you to type allow pasting before the first paste because pasted code runs as you.
What happens to the status I already have?
The scheduled status replaces it when it starts, and Slack does not bring the old one back. In our test a status we had set by hand was replaced at the start; when the scheduled one ended, the status was empty. With Pause notifications ticked, Slack also paused notifications until the scheduled end.
Does a status keep me green on Slack?
No. A status is the emoji and text next to your name; the green dot is your presence, and Slack sets it from activity in its own window. A lunch status does not make you away, and a busy status does not keep you active.
Related reading
Slack Green does one thing: it keeps your Slack presence dot green while you are actually working, so a quiet keyboard does not mark you away. Try it free.