code icon Code

List Slack Users

Fetch all workspace users with pagination

Source Code

import fs from "fs";
import path from "path";

const [outputPath = "", includeBots = "false"] = process.argv.slice(2);
const includeBotsFlag = includeBots === "true";

console.log("Fetching Slack workspace users...");

try {
  // Get auth info and users in parallel
  const [authData, users] = await Promise.all([
    (async () => {
      const res = await fetch("https://slack.com/api/auth.test", {
        headers: { Authorization: "Bearer PLACEHOLDER_TOKEN" },
      });
      const data = await res.json();
      if (!data.ok) throw new Error(`Auth failed: ${data.error}`);
      return data;
    })(),

    (async () => {
      const allUsers = [];
      let cursor = null;

      do {
        const params = new URLSearchParams({ limit: "200" });
        if (cursor) params.set("cursor", cursor);

        const res = await fetch("https://slack.com/api/users.list?" + params, {
          headers: { Authorization: "Bearer PLACEHOLDER_TOKEN" },
        });
        const data = await res.json();

        if (!data.ok) throw new Error(`users.list failed: ${data.error}`);
        allUsers.push(...(data.members || []));
        cursor = data.response_metadata?.next_cursor;
      } while (cursor);

      return allUsers;
    })(),
  ]);

  // Filter and transform
  const transformedUsers = users
    .filter(u => {
      if (u.deleted) return false;
      if (!includeBotsFlag && u.is_bot) return false;
      return true;
    })
    .map(u => ({
      id: u.id,
      name: u.profile?.display_name || u.real_name || u.name,
      realName: u.real_name,
      username: u.name,
      email: u.profile?.email,
      isBot: u.is_bot,
      isAdmin: u.is_admin,
      isOwner: u.is_owner,
      timezone: u.tz,
      avatar: u.profile?.image_72,
    }));

  const result = {
    workspace: authData.team,
    fetchedAt: new Date().toISOString(),
    count: transformedUsers.length,
    users: transformedUsers,
  };

  if (outputPath) {
    const dir = path.dirname(outputPath);
    if (dir && dir !== ".") fs.mkdirSync(dir, { recursive: true });
    fs.writeFileSync(outputPath, JSON.stringify(result, null, 2));
    console.log(`Written to: ${outputPath}`);
  }

  console.log(`✓ Workspace: ${authData.team}`);
  console.log(`  ${transformedUsers.length} users found`);

  console.log(JSON.stringify({
    success: true,
    workspace: authData.team,
    count: transformedUsers.length,
  }));
} catch (error) {
  console.error("Error:", error.message);
  throw error;
}