npm package: @redonvn/tiktok-sdk
Description: TikTok API SDK for TypeScript/Node.js backend applications
Author: redonvn
Latest version: 1.0.0

# TikTok SDK for TypeScript/Node.js

A comprehensive TypeScript SDK for integrating TikTok APIs in Node.js backend applications. This SDK provides easy-to-use interfaces for OAuth authentication, user information retrieval, video management, and content posting.

## Features

- = **OAuth 2.0 Authentication** - Complete OAuth flow implementation
- =d **User Information** - Retrieve user profiles and statistics
- <� **Video Management** - List and query user videos
- =� **Content Posting** - Upload videos and photos programmatically
- = **Token Management** - Automatic token refresh and revocation
- =� **Type-Safe** - Full TypeScript support with comprehensive types
- � **Easy to Use** - Simple and intuitive API design

## Installation

```bash
npm install @tiktok/sdk
```

## Quick Start

### 1. Initialize the SDK

```typescript
import TikTokSDK from '@tiktok/sdk';

const tiktok = new TikTokSDK({
  clientKey: 'your_client_key',
  clientSecret: 'your_client_secret',
  redirectUri: 'https://your-app.com/callback',
});
```

### 2. OAuth Authentication Flow

```typescript
// Generate authorization URL
const scopes = ['user.info.basic', 'video.list', 'video.publish'];
const state = tiktok.oauth.generateState(); // CSRF protection
const authUrl = tiktok.oauth.getAuthorizationUrl(scopes, state);

// Redirect user to authUrl
console.log('Authorize at:', authUrl);

// After user authorizes, exchange code for tokens
const tokens = await tiktok.oauth.getAccessToken(authorizationCode);
console.log('Access Token:', tokens.access_token);
console.log('Refresh Token:', tokens.refresh_token);
console.log('Expires In:', tokens.expires_in);
```

### 3. Get User Information

```typescript
const userInfo = await tiktok.display.getUserInfo(accessToken);

console.log('User:', userInfo.display_name);
console.log('Followers:', userInfo.follower_count);
console.log('Videos:', userInfo.video_count);
```

### 4. List User Videos

```typescript
const videos = await tiktok.display.getVideoList(accessToken, {
  max_count: 20,
  cursor: 0,
});

console.log('Videos:', videos.videos);
console.log('Has More:', videos.has_more);
console.log('Next Cursor:', videos.cursor);
```

### 5. Upload Video

```typescript
// From local file
const publishId = await tiktok.contentPosting.publishVideoFromFile(
  accessToken,
  './video.mp4',
  {
    title: 'My awesome video!',
    privacy_level: 'PUBLIC_TO_EVERYONE',
    disable_comment: false,
    disable_duet: false,
    disable_stitch: false,
  }
);

// From URL
const publishId = await tiktok.contentPosting.publishVideoFromUrl(
  accessToken,
  'https://example.com/video.mp4',
  {
    title: 'My video from URL',
    privacy_level: 'PUBLIC_TO_EVERYONE',
  }
);

// Check upload status
const status = await tiktok.contentPosting.getPublishStatus(accessToken, publishId);
console.log('Status:', status.status);
```

## API Reference

### OAuth Module

#### `getAuthorizationUrl(scopes, state?)`
Generate OAuth authorization URL.

**Parameters:**
- `scopes`: Array of TikTok scopes
- `state`: Optional CSRF token

**Returns:** Authorization URL string

#### `generateState()`
Generate random state token for CSRF protection.

**Returns:** Random state string

#### `getAccessToken(code)`
Exchange authorization code for access token.

**Parameters:**
- `code`: Authorization code from callback

**Returns:** Token response with access token and refresh token

#### `refreshAccessToken(refreshToken)`
Refresh an expired access token.

**Parameters:**
- `refreshToken`: Refresh token from previous response

**Returns:** New token response

#### `revokeToken(accessToken)`
Revoke an access token.

**Parameters:**
- `accessToken`: Token to revoke

#### `getClientAccessToken()`
Get client access token for app-level operations.

**Returns:** Client access token

### Display API Module

#### `getUserInfo(accessToken, fields?)`
Get user profile information.

**Required Scope:** `user.info.basic`

**Parameters:**
- `accessToken`: User access token
- `fields`: Optional array of fields to retrieve

**Returns:** User information object

#### `getVideoList(accessToken, options?)`
Get list of user's videos.

**Required Scope:** `video.list`

**Parameters:**
- `accessToken`: User access token
- `options`: Query options
  - `cursor`: Pagination cursor (default: 0)
  - `max_count`: Max videos to return (default: 20)
  - `fields`: Optional fields array

**Returns:** Video list with pagination info

#### `queryVideos(accessToken, videoIds, fields?)`
Query specific videos by IDs.

**Required Scope:** `video.list`

**Parameters:**
- `accessToken`: User access token
- `videoIds`: Array of video IDs
- `fields`: Optional fields array

**Returns:** Array of video objects

### Content Posting API Module

#### `getCreatorInfo(accessToken)`
Get creator information and posting capabilities.

**Required Scope:** `video.publish`

**Parameters:**
- `accessToken`: User access token

**Returns:** Creator info with settings and limits

#### `publishVideoFromFile(accessToken, filePath, postInfo)`
Upload and publish video from local file or Buffer.

**Required Scopes:** `video.publish`, `video.upload`

**Parameters:**
- `accessToken`: User access token
- `filePath`: Local file path or Buffer
- `postInfo`: Post settings
  - `title`: Video title
  - `privacy_level`: 'PUBLIC_TO_EVERYONE' | 'MUTUAL_FOLLOW_FRIENDS' | 'SELF_ONLY'
  - `disable_comment`: Boolean
  - `disable_duet`: Boolean
  - `disable_stitch`: Boolean

**Returns:** Publish ID

#### `publishVideoFromUrl(accessToken, videoUrl, postInfo)`
Publish video from public URL.

**Required Scope:** `video.publish`

**Parameters:**
- `accessToken`: User access token
- `videoUrl`: Public video URL
- `postInfo`: Post settings (same as above)

**Returns:** Publish ID

#### `publishPhotoContent(accessToken, photoUrls, postInfo, coverIndex?)`
Publish photo slideshow content.

**Required Scope:** `video.publish`

**Parameters:**
- `accessToken`: User access token
- `photoUrls`: Array of public image URLs
- `postInfo`: Post settings
- `coverIndex`: Index of cover photo (default: 0)

**Returns:** Publish ID

#### `getPublishStatus(accessToken, publishId)`
Check publishing status.

**Parameters:**
- `accessToken`: User access token
- `publishId`: Publish ID from upload

**Returns:** Status information

## Available Scopes

- `user.info.basic` - Basic user information
- `user.info.profile` - Extended profile information
- `user.info.stats` - User statistics
- `video.list` - List and query videos
- `video.publish` - Publish content
- `video.upload` - Upload video files

## Error Handling

```typescript
import { TikTokAPIError } from '@tiktok/sdk';

try {
  const userInfo = await tiktok.display.getUserInfo(accessToken);
} catch (error) {
  if (error instanceof TikTokAPIError) {
    console.error('TikTok API Error:', error.code);
    console.error('Message:', error.message);
    console.error('Log ID:', error.logId);
  } else {
    console.error('Unexpected error:', error);
  }
}
```

## Complete Example: OAuth Flow with Express

```typescript
import express from 'express';
import TikTokSDK from '@tiktok/sdk';

const app = express();
const tiktok = new TikTokSDK({
  clientKey: process.env.TIKTOK_CLIENT_KEY!,
  clientSecret: process.env.TIKTOK_CLIENT_SECRET!,
  redirectUri: 'http://localhost:3000/callback',
});

// Store state tokens (use Redis in production)
const stateStore = new Map<string, boolean>();

// Login route
app.get('/login', (req, res) => {
  const state = tiktok.oauth.generateState();
  stateStore.set(state, true);

  const scopes = ['user.info.basic', 'video.list'];
  const authUrl = tiktok.oauth.getAuthorizationUrl(scopes, state);

  res.redirect(authUrl);
});

// Callback route
app.get('/callback', async (req, res) => {
  const { code, state } = req.query;

  // Verify state token
  if (!state || !stateStore.has(state as string)) {
    return res.status(403).send('Invalid state token');
  }
  stateStore.delete(state as string);

  try {
    // Exchange code for tokens
    const tokens = await tiktok.oauth.getAccessToken(code as string);

    // Get user info
    const userInfo = await tiktok.display.getUserInfo(tokens.access_token);

    // Store tokens securely (use database in production)
    // storeTokens(userInfo.open_id, tokens);

    res.json({
      message: 'Authentication successful!',
      user: userInfo,
      tokens: {
        access_token: tokens.access_token,
        expires_in: tokens.expires_in,
      },
    });
  } catch (error) {
    console.error('Error during callback:', error);
    res.status(500).send('Authentication failed');
  }
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
  console.log('Visit http://localhost:3000/login to start');
});
```

## TypeScript Support

The SDK is written in TypeScript and provides comprehensive type definitions:

```typescript
import TikTokSDK, {
  TikTokConfig,
  UserInfo,
  Video,
  TikTokScope
} from '@tiktok/sdk';

const config: TikTokConfig = {
  clientKey: 'your_key',
  clientSecret: 'your_secret',
  redirectUri: 'your_uri',
};

const sdk = new TikTokSDK(config);
```

## Rate Limits

TikTok enforces rate limits on API endpoints. Make sure to:
- Implement proper retry logic with exponential backoff
- Cache responses when appropriate
- Monitor rate limit headers in responses

## Security Best Practices

1. **Never expose credentials** - Keep client secret secure on backend only
2. **Validate state tokens** - Always use state parameter to prevent CSRF
3. **Secure token storage** - Store tokens encrypted in database
4. **HTTPS only** - Use HTTPS for all redirect URIs
5. **Token rotation** - Refresh tokens before expiration
6. **Scope minimization** - Only request necessary scopes

## Requirements

- Node.js 14 or higher
- TypeScript 4.5 or higher (for TypeScript projects)

## Resources

- [TikTok Developers Portal](https://developers.tiktok.com/)
- [API Documentation](https://developers.tiktok.com/doc/overview)
- [Register Your App](https://developers.tiktok.com/apps)

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Support

For issues and questions:
- GitHub Issues: [Create an issue](https://github.com/your-repo/issues)
- TikTok Developer Support: [TikTok Support](https://developers.tiktok.com/support)