# User Operations

Retrieve user information, manage user profiles, and handle user presence.

## Capabilities

### Get User Information

Retrieve detailed information about users in the workspace.

```typescript { .api }
/**
 * Get information about a user
 * @param options - User info parameters
 * @returns Promise resolving to user details
 */
users.info(options: UsersInfoArguments): Promise<UsersInfoResponse>;

interface UsersInfoArguments {
  /** User ID to get info about */
  user: string;
  /** Include locale information in the response */
  include_locale?: boolean;
}
```

**Usage Examples:**

```typescript
import { WebClient } from "@slack/web-api";

const web = new WebClient(token);

// Get basic user info
const userInfo = await web.users.info({
  user: 'U1234567890'
});

console.log('User name:', userInfo.user.name);
console.log('Display name:', userInfo.user.profile.display_name);
console.log('Email:', userInfo.user.profile.email);

// Get user info with locale
const detailedInfo = await web.users.info({
  user: 'U1234567890',
  include_locale: true
});

console.log('User locale:', detailedInfo.user.locale);
```

### List Users

Retrieve lists of users in the workspace with pagination support.

```typescript { .api }
/**
 * List users in the workspace
 * @param options - List parameters
 * @returns Promise resolving to users list
 */
users.list(options?: UsersListArguments): Promise<UsersListResponse>;

interface UsersListArguments {
  /** Cursor for pagination */
  cursor?: string;
  /** Include deactivated users */
  include_locale?: boolean;
  /** Maximum number of users to return (1-1000, default: 0 for all) */
  limit?: number;
  /** Team ID (Enterprise Grid) */
  team_id?: string;
}
```

**Usage Examples:**

```typescript
// List all active users
const users = await web.users.list();

console.log(`Found ${users.members.length} users`);

// List users with pagination
const activeUsers = [];
for await (const page of web.paginate('users.list', { limit: 100 })) {
  const active = page.members.filter(user => !user.deleted && !user.is_bot);
  activeUsers.push(...active);
}

console.log(`Found ${activeUsers.length} active human users`);
```

### Lookup User by Email

Find users by their email address.

```typescript { .api }
/**
 * Look up a user by email address
 * @param options - Lookup parameters
 * @returns Promise resolving to user details
 */
users.lookupByEmail(options: UsersLookupByEmailArguments): Promise<UsersLookupByEmailResponse>;

interface UsersLookupByEmailArguments {
  /** Email address to look up */
  email: string;
}
```

**Usage Examples:**

```typescript
// Find user by email
const user = await web.users.lookupByEmail({
  email: 'john.doe@company.com'
});

console.log('Found user:', user.user.id);
console.log('Display name:', user.user.profile.display_name);
```

### User Profile Management

Get and update user profile information.

```typescript { .api }
/**
 * Get a user's profile information
 * @param options - Profile get parameters
 * @returns Promise resolving to profile details
 */
users.profile.get(options?: UsersProfileGetArguments): Promise<UsersProfileGetResponse>;

/**
 * Set a user's profile information
 * @param options - Profile set parameters
 * @returns Promise resolving to updated profile
 */
users.profile.set(options: UsersProfileSetArguments): Promise<UsersProfileSetResponse>;

interface UsersProfileGetArguments {
  /** Include labels for each ID in custom profile fields */
  include_labels?: boolean;
  /** User ID to get profile for (defaults to authed user) */
  user?: string;
}

interface UsersProfileSetArguments {
  /** Name of the profile field to set */
  name?: string;
  /** JSON-encoded profile object to update */
  profile?: string;
  /** User ID to set profile for (admins only) */
  user?: string;
  /** Value to set for the profile field */
  value?: string;
}
```

**Usage Examples:**

```typescript
// Get current user's profile
const profile = await web.users.profile.get();

console.log('Current status:', profile.profile.status_text);
console.log('Phone:', profile.profile.phone);

// Get another user's profile
const otherProfile = await web.users.profile.get({
  user: 'U1234567890',
  include_labels: true
});

// Update current user's status
await web.users.profile.set({
  profile: JSON.stringify({
    status_text: 'In a meeting',
    status_emoji: ':calendar:'
  })
});

// Update specific profile field
await web.users.profile.set({
  name: 'phone', 
  value: '+1-555-123-4567'
});
```

### User Presence

Manage and retrieve user presence information.

```typescript { .api }
/**
 * Get a user's presence status
 * @param options - Presence parameters
 * @returns Promise resolving to presence info
 */
users.getPresence(options: UsersGetPresenceArguments): Promise<UsersGetPresenceResponse>;

/**
 * Set the current user's presence
 * @param options - Presence set parameters
 * @returns Promise resolving to presence update result
 */
users.setPresence(options: UsersSetPresenceArguments): Promise<UsersSetPresenceResponse>;

interface UsersGetPresenceArguments {
  /** User ID to get presence for */
  user: string;
}

interface UsersSetPresenceArguments {
  /** Presence to set ('auto' or 'away') */
  presence: 'auto' | 'away';
}
```

**Usage Examples:**

```typescript
// Get user's presence
const presence = await web.users.getPresence({
  user: 'U1234567890'
});

console.log('User presence:', presence.presence); // 'active' or 'away'
console.log('Online status:', presence.online); // true or false

// Set current user to away
await web.users.setPresence({
  presence: 'away'
});

// Set current user to auto (active when using Slack)
await web.users.setPresence({
  presence: 'auto'
});
```

### User Photo Management

Upload and manage user profile photos.

```typescript { .api }
/**
 * Set a user's profile photo
 * @param options - Photo set parameters
 * @returns Promise resolving to photo update result
 */
users.setPhoto(options: UsersSetPhotoArguments): Promise<UsersSetPhotoResponse>;

/**
 * Delete a user's profile photo
 * @param options - Photo delete parameters
 * @returns Promise resolving to deletion result
 */
users.deletePhoto(options?: UsersDeletePhotoArguments): Promise<UsersDeletePhotoResponse>;

interface UsersSetPhotoArguments {
  /** Height of crop box (default: full image height) */
  crop_h?: number;
  /** Width of crop box (default: full image width) */
  crop_w?: number;
  /** X coordinate of top-left corner of crop box */
  crop_x?: number;
  /** Y coordinate of top-left corner of crop box */
  crop_y?: number;
  /** Image data as multipart/form-data */
  image?: Buffer | NodeJS.ReadableStream;
}

interface UsersDeletePhotoArguments {
  /** Token for the user whose photo will be deleted */
  token?: string;
}
```

**Usage Examples:**

```typescript
import { createReadStream } from 'fs';

// Set profile photo from file
await web.users.setPhoto({
  image: createReadStream('./profile-photo.jpg'),
  crop_x: 10,
  crop_y: 10,
  crop_w: 200,
  crop_h: 200
});

// Delete current profile photo
await web.users.deletePhoto();
```

### User Identity

Get identity information for the authenticated user (for OAuth apps).

```typescript { .api }
/**
 * Get identity information about the current user
 * @param options - Identity parameters
 * @returns Promise resolving to identity details
 */
users.identity(options?: UsersIdentityArguments): Promise<UsersIdentityResponse>;

interface UsersIdentityArguments {
  /** Token for the user */
  token?: string;
}
```

**Usage Examples:**

```typescript
// Get current user identity (useful for OAuth apps)
const identity = await web.users.identity();

console.log('User ID:', identity.user.id);
console.log('Team ID:', identity.team.id);
console.log('User name:', identity.user.name);
```

### User Conversations

List conversations that a user is a member of.

```typescript { .api }
/**
 * List conversations the user is a member of
 * @param options - Conversations parameters
 * @returns Promise resolving to conversations list
 */
users.conversations(options?: UsersConversationsArguments): Promise<UsersConversationsResponse>;

interface UsersConversationsArguments {
  /** Cursor for pagination */
  cursor?: string;
  /** Set to true to exclude archived channels from the list */
  exclude_archived?: boolean;
  /** Maximum number of conversations to return */
  limit?: number;
  /** Team ID (Enterprise Grid) */
  team_id?: string;
  /** Mix and match conversation types to return */
  types?: string;
  /** Browse conversations by a specific user ID's membership */
  user?: string;
}
```

**Usage Examples:**

```typescript
// List current user's conversations
const myConversations = await web.users.conversations({
  exclude_archived: true,
  types: 'public_channel,private_channel,mpim,im'
});

console.log(`User is in ${myConversations.channels.length} conversations`);

// List another user's public channels
const userChannels = await web.users.conversations({
  user: 'U1234567890',
  types: 'public_channel',
  limit: 100
});
```

### Discoverable Contacts

Look up users who can be contacted outside the workspace.

```typescript { .api }
/**
 * Look up discoverable contacts
 * @param options - Lookup parameters
 * @returns Promise resolving to contact details
 */
users.discoverableContacts.lookup(options: UsersDiscoverableContactsLookupArguments): Promise<UsersDiscoverableContactsLookupResponse>;

interface UsersDiscoverableContactsLookupArguments {
  /** Email address to look up */
  email: string;
}
```

**Usage Examples:**

```typescript
// Look up external contact
const contact = await web.users.discoverableContacts.lookup({
  email: 'external.contact@otherdomain.com'
});

if (contact.ok) {
  console.log('Contact found:', contact.user.name);
}
```

## Types

```typescript { .api }
interface UsersInfoResponse extends WebAPICallResult {
  user: {
    id: string;
    team_id: string;
    name: string;
    deleted: boolean;
    color: string;
    real_name: string;
    tz: string;
    tz_label: string;
    tz_offset: number;
    profile: UserProfile;
    is_admin: boolean;
    is_owner: boolean;
    is_primary_owner: boolean;
    is_restricted: boolean;
    is_ultra_restricted: boolean;
    is_bot: boolean;
    is_app_user: boolean;
    updated: number;
    is_email_confirmed: boolean;
    who_can_share_contact_card: string;
    locale?: string;
  };
}

interface UserProfile {
  title: string;
  phone: string;
  skype: string;
  real_name: string;
  real_name_normalized: string;
  display_name: string;
  display_name_normalized: string;
  fields: { [key: string]: UserProfileField };
  status_text: string;
  status_emoji: string;
  status_expiration: number;
  avatar_hash: string;
  email: string;
  first_name: string;
  last_name: string;
  image_24: string;
  image_32: string;
  image_48: string;
  image_72: string;
  image_192: string;
  image_512: string;
  status_text_canonical: string;
  team: string;
}

interface UserProfileField {
  value: string;
  alt: string;
  label?: string;
}

interface UsersListResponse extends WebAPICallResult {
  members: UsersInfoResponse['user'][];
  cache_ts: number;
  response_metadata?: {
    next_cursor?: string;
  };
}

interface UsersGetPresenceResponse extends WebAPICallResult {
  presence: 'active' | 'away';
  online: boolean;
  auto_away?: boolean;
  manual_away?: boolean;
  connection_count?: number;
  last_activity?: number;
}
```