← back to Slack To Steve

whoami.mjs

22 lines

// whoami.mjs — resolve the #claude-to-steve channel ID and Steve's user ID,
// so .env can be filled without hunting through Slack. $0 (Web API only).
// Uses only channels:read + users:read (already granted / lightweight).
import fs from 'fs';
import path from 'path';
const ENV = (() => { const o = {}; try { for (const l of fs.readFileSync(path.join(process.cwd(), '.env'), 'utf8').split('\n')) { const m = l.match(/^([A-Z0-9_]+)=(.*)$/); if (m) o[m[1]] = m[2].replace(/^['"]|['"]$/g, ''); } } catch {} return o; })();
const TOKEN = ENV.SLACK_BOT_TOKEN || process.env.SLACK_BOT_TOKEN;
const NAME = process.argv[2] || 'claude-to-steve';
async function slack(m, p = {}) { const r = await fetch('https://slack.com/api/' + m + '?' + new URLSearchParams(p), { headers: { Authorization: 'Bearer ' + TOKEN } }); return r.json(); }
(async () => {
  if (!TOKEN) { console.log('set SLACK_BOT_TOKEN in .env first'); process.exit(1); }
  let cursor = '', found = null;
  do {
    const r = await slack('conversations.list', { limit: '200', types: 'public_channel,private_channel', cursor });
    if (!r.ok) { console.log('channel list error: ' + r.error); break; }
    found = (r.channels || []).find(c => c.name === NAME);
    cursor = r.response_metadata?.next_cursor || '';
  } while (cursor && !found);
  console.log(found ? `#${NAME} → SLACK_CHANNEL_ID=${found.id}` : `#${NAME} not found — create it in Slack + invite the bot`);
  console.log('\nTo find Steve\'s user ID: Slack → his profile → ⋯ → Copy member ID (U...).');
})();