# Clique Pipelines SDK

The `Clique Pipelines SDK` is an open-source library that enables user to access `Clique Pipelines Data` easily and quickly. We currently support NodeJS and Web SDKs.

### Setup

#### NodeJS

Add the dependency:

```sh
pnpm add @cliqueofficial/clique-pipelines-sdk-node
# OR
yarn add @cliqueofficial/clique-pipelines-sdk-node
# OR 
npm install @cliqueofficial/clique-pipelines-sdk-node
```

Get the client instance:

```typescript
import { Client } from '@cliqueofficial/clique-pipelines-sdk-node';

const config = {
  // Whether the Pipelines Data is retrieved in a TEE environment.
  enableTee: true,
  // Clique Pipelines Data Service URL, 
  serviceUrl: 'https://pipelines-server.sit.clique-test.tech',
};
const client = new Client(config);
```

#### Web

Add the dependency:

```sh
pnpm add @cliqueofficial/clique-pipelines-sdk-web
# OR
yarn add @cliqueofficial/clique-pipelines-sdk-web
# OR 
npm install @cliqueofficial/clique-pipelines-sdk-web
```

Get the client instance:

```typescript
import { Client } from '@cliqueofficial/clique-pipelines-sdk-web';

const config = {
  // Whether the Pipelines Data is retrieved in a TEE environment.
  enableTee: true,
  // Clique Pipelines Data Service URL, 
  serviceUrl: 'https://pipelines-server.sit.clique-test.tech',
};
const client = new Client(config);
```

### Pipelines

{% hint style="info" %}
We currently only support the data available through the official platform APIs. If you wish to access more private pipeline data from users, please use our [Clique Browser Extension](/toolchain/clique-browser-extension.md).
{% endhint %}

#### Common Types

* `Response`

```typescript
interface Response {
   id: number;
   attestation?: {
     id: string;
     type: 'SGX';
     isvEnclaveQuoteBody: string;
   };
   signature?: string;
   result: Record<string, any>; 
}
```

The `attestation` and `signature` will be `undefined` if you disable `TEE`.

#### Twitter

* `userInfo`

```typescript
interface TwitterUserInfo {
  idStr: string;
  name: string;
  screenName: string;
  profileImageUrlHttps: string;
  description: string;
  fastFollowersCount: number;
  favouritesCount: number;
  followersCount: number;
  friendsCount: number;
  mediaCount: number;
  statusesCount: number;
  createdAt: string;
  isBlueVerified: boolean;
}

const oauthAccessToken = 'xxxxxx';
const response: Response = await client.twitter.userInfo(oauthAccessToken);
const userInfo = response.result[response.id]; // TwitterUserInfo
```

#### Steam

* `userInfo`

```typescript
export interface SteamUserInfo {
  steamId: string;
  communityVisibilityState: number;
  profileState: number;
  personaName: string;
  profileUrl: string;
  lastLogOff: number;
  timeCreated: number;
  personaState: number;
  locCountryCode: string;
}
const steamId = 'xxxxxx';
const response: Response = await client.steam.userInfo(steamId);
const userInfo = response.result[response.id]; // SteamUserInfo
```

* `listBadge`

```typescript
interface SteamBadges {
  badges: {
    badgeId: number;
    completionTime: number;
    level: number;
    scarcity: number;
    xp: number;
  }[];
}

const steamId = 'xxxxxx';
const response: Response = await client.steam.listBadges(steamId);
const badges = response.result[response.id].badges; // SteamBadges
```

* `userOwnedGames`

```typescript
export interface SteamPlayerOwnedGame {
  appId: string;
  name: string;
  playtimeForever: number;
  imgIconUrl: string;
  hasCommunityVisibleStats: boolean;
  playtimeWindowsForever: number;
  playtimeMacForever: number;
  playtimeLinuxForever: number;
  playtimeDeckForever: number;
  rtimeLastPlayed: number;
  playtimeDisconnected: number;
}

export interface SteamUserOwnedGames {
  games: SteamPlayerOwnedGame[];
  gameCount: number;
}
const steamId = 'xxxxxx';
const response: Response = await client.steam.userOwnedGames(steamId);
const userOwnedGames = response.result[response.id]; // SteamUserOwnedGames
```

* `gameStats`

```typescript
interface SteamGameStatsRequest {
  // how many top data
  top?: number;
}

export interface SteamGameStats {
  sumMoneySpentOnGames: number;
  listCategory: {
    gameId: number;
    category: string[];
  }[];
  sumHoursPlayed: string;
  sumOwnedGames: number;
  topPlayedGames: {
    gameId: number;
    name: string;
    hours: string;
  }[];
  gamePlayedTime: {
    name: string;
    time: number;
  }[];
  topGenresByHours: {
    name: string;
    hours: string;
  }[];
  topCategoriesByHours: {
    name: string;
    hours: string;
  }[];
  ownedGameNames: string[];
  userGameAchievements: {
    steamId: string;
    gameName: string;
    achievements: {
      apiName: string;
      name: string;
      achieved: boolean;
      unlockTime: number;
      description: string;
    }[];
  }[];
  sumAchievedAchievement: number;
}

const steamId = 'xxxxxx';
const request: SteamGameStatsRequest = {};
const response: Response = await client.steam.gameStats(steamId, request);
const gameStats = response.result[response.id]; // SteamGameStats
```

#### Discord

* `userInfo`

```typescript
interface DiscordUserInfo {
  id: string;
  username: string;
  discriminator: string;
  publicFlags: number;
  flags: number;
  globalName: string;
  mfaEnabled: boolean;
  locale: string;
  premiumType: number;
  createdAt: number;
}
const oauthAccessToken = 'xxxxxx';
const response: Response = await client.discord.userInfo(oauthAccessToken);
const userInfo = response.result[response.id]; // DiscordUserInfo
```

* `isMemberOf`

```typescript
interface DiscordIsMemberOf {
  isMemberOf: boolean;
}
const botToken = 'xxxxxx';
const serverId = 'xxxxxx';
const uid = 'xxxxxx';
const response: Response = await client.discord.isMemberOf({
  botToken, serverId, uid,
});
const isMemberOf = response.result[response.id].isMemberOf;
```

* `timeJoined`

```typescript
interface DiscordTimeJoined {
  joinedAt: number;
}
const botToken = 'xxxxxx';
const serverId = 'xxxxxx';
const uid = 'xxxxxx';
const response: Response = await client.discord.timeJoined({
  botToken, serverId, uid,
});
const timeJoined = response.result[response.id].joinedAt;
```

* `numInvites`

```typescript
interface DiscordNumInvites {
  numInvites: number;
}
const botToken = 'xxxxxx';
const serverId = 'xxxxxx';
const uid = 'xxxxxx';
const response: Response = await client.discord.numInvites({
  botToken, serverId, uid,
});
const numInvites = response.result[response.id].numInvites;
```

* `userRoles`

```typescript
interface DiscordUserRoles {
  roles: string[];
}
const botToken = 'xxxxxx';
const serverId = 'xxxxxx';
const uid = 'xxxxxx';
const response: Response = await client.discord.userRoles({
  botToken, serverId, uid,
});
const userRoles = response.result[response.id].userRoles;
```

#### GitHub

* `userInfo`

```typescript
interface GithubUserInfo {
  id: number;
  name: string;
  login: string;
}
const oauthAccessToken = 'xxxxxx';
const response: Response = await client.github.userInfo(oauthAccessToken);
const userInfo = response.result[response.id]; // GithubUserInfo
```

* `stats`

```typescript
interface GithubStats {
  name: string;
  login: string;
  followers: number;
  totalPRs: number;
  totalCommits: number;
  totalIssues: number;
  totalStars: number;
  contributedTo: number;
}
const oauthAccessToken = 'xxxxxx';
const response: Response = await client.github.stats(oauthAccessToken);
const stats = response.result[response.id]; // GithubStats
```

#### Spotify

* `userInfo`

```typescript
interface SpotifyUserInfo {
  id: number;
  country: string;
  displayName: string;
  followers: number;
  email: string;
}
const oauthAccessToken = 'xxxxxx';
const response: Response = await client.spotify.userInfo(oauthAccessToken);
const userInfo = response.result[response.id]; // SpotifyUserInfo
```

* `topTracks`

```typescript
interface SpotifyTopTracksStats {
  top10Artists: string[];
  top10Genres: string[];
  topTracks: string[];
}
const oauthAccessToken = 'xxxxxx';
const response: Response = await client.spotify.topTracks(oauthAccessToken);
const topTracks = response.result[response.id]; // SpotifyTopTracksStats
```

* `followedArtists`

```typescript
interface SpotifyArtist {
  id: string;
  genres: string[];
  name: string;
  imageUrl: string;
}
interface SpotifyFollowedArtists {
  artists: SpotifyArtist[];
}
const oauthAccessToken = 'xxxxxx';
const response: Response = await client.spotify.followedArtists(oauthAccessToken);
const followedArtists = response.result[response.id]; // SpotifyFollowedArtists
```

* `recentPlayedTracks`

```typescript
interface SpotifyTrack {
  id: string;
  name: string;
}
interface SpotifyRecentPlayedTrack {
  tracks: SpotifyTrack[];
}
const oauthAccessToken = 'xxxxxx';
const response: Response = await client.spotify.recentPlayedTracks(oauthAccessToken);
const recentPlayedTracks = response.result[response.id]; // SpotifyRecentPlayedTrack[]
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.clique.tech/toolchain/clique-pipelines-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
