notwonderful/trovo-sdk

PHP SDK for Trovo.live API — OAuth, channels, users, chat, clips, drops and more

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/notwonderful/trovo-sdk

0.1.0 2026-02-11 08:31 UTC

This package is auto-updated.

Last update: 2026-02-11 10:16:07 UTC


README

Logo

PHP Version License

PHP 8.3+ SDK for the Trovo.live API.

Installation

composer require notwonderful/trovo-sdk

Quick Start

use Notwonderful\TrovoSdk\TrovoClient;
use Notwonderful\TrovoSdk\Config;
use Notwonderful\TrovoSdk\Enum\Scope;

$trovo = new TrovoClient(new Config(
    clientId: 'your_client_id',
    clientSecret: 'your_client_secret',
    redirectUri: 'https://example.com/callback',
));

Authentication

OAuth 2.0 Authorization Code Flow

// 1. Redirect user to Trovo login
$url = $trovo->getAuthorizationCodeUrl(
    scopes: [Scope::UserDetailsSelf, Scope::ChannelDetailsSelf],
    state: 'random_csrf_token',
);

// 2. After redirect, exchange code for tokens
$token = $trovo->exchangeCode($_GET['code']);
// $token->accessToken, $token->refreshToken, $token->expiresIn

// 3. Set the token for subsequent API calls
$trovo->setAccessToken($token->accessToken);

OAuth 2.0 Implicit Flow

$url = $trovo->getImplicitFlowUrl(
    scopes: [Scope::UserDetailsSelf],
    state: 'random_csrf_token',
);
// Access token will be in the URL fragment after redirect

Token Management

// Refresh
$newToken = $trovo->refreshToken($token->refreshToken);

// Validate
$info = $trovo->validateToken($token->accessToken);
// $info->uid, $info->scopes, $info->expireTs, $info->isExpired()

// Revoke
$trovo->revokeToken($token->accessToken);

API Usage

Categories

// Top categories (sorted by popularity)
$categories = $trovo->categories()->getTopCategories();
// returns Category[] — id, name, shortName, iconUrl, desc

// Search
$result = $trovo->categories()->search(query: 'apex', limit: 10);
// $result->items (Category[]), $result->hasMore

Channels

// Top live channels with pagination
$page = $trovo->channels()->getTopChannels(limit: 20);
// $page->items (Channel[]), $page->totalPage, $page->cursor, $page->token

// Next page
$page2 = $trovo->channels()->getTopChannels(
    limit: 20,
    after: true,
    token: $page->token,
    cursor: $page->cursor,
);

// Channel info by ID or username
$channel = $trovo->channels()->getById(channelId: 100000031);
$channel = $trovo->channels()->getById(username: 'username');

// Own channel with stream key (requires channel_details_self)
$my = $trovo->channels()->getMy();
// $my->streamKey, $my->isLive, $my->title, ...

// Update channel (requires channel_update_self)
use Notwonderful\TrovoSdk\Enum\AudienceType;

$trovo->channels()->update(
    channelId: 100000031,
    liveTitle: 'New title',
    categoryId: '10023',
    languageCode: 'EN',
    audiType: AudienceType::Teen,
);

// Followers
$followers = $trovo->channels()->getFollowers(channelId: 100000031, limit: 50);
// $followers->items (Follower[]), $followers->total, $followers->totalPage

// Viewers (grouped by role)
$viewers = $trovo->channels()->getViewers(channelId: 100000031);
// $viewers['chatters']['moderators']['viewers'], $viewers['total'], ...

Users

// Lookup by usernames
$users = $trovo->users()->getByUsernames(['user1', 'user2']);
// returns User[] — userId, userName, nickName, channelId

// Authenticated user info (requires user_details_self)
$me = $trovo->users()->getUserInfo();
// $me->userId, $me->userName, $me->email, $me->profilePic

Subscribers

use Notwonderful\TrovoSdk\Enum\SortDirection;

// Requires channel_subscriptions scope
$subs = $trovo->subscribers()->get(
    channelId: 100000031,
    limit: 50,
    offset: 0,
    direction: SortDirection::Desc,
);
// $subs->items (Subscriber[]), $subs->total
// Subscriber: userId, username, displayName, subCreatedAt, subLv, subTier

Emotes

use Notwonderful\TrovoSdk\Enum\EmoteType;

$emotes = $trovo->emotes()->get(
    emoteType: EmoteType::All,
    channelIds: [100000031],
);
// Raw array: globalEmotes, eventEmotes, customizedEmotes

Streams & Past Streams

// Live stream URLs (restricted access)
$urls = $trovo->streams()->getLiveStreamUrls(channelId: 100000031);
// returns StreamUrl[] — playUrl, desc (resolution)

// Past streams
use Notwonderful\TrovoSdk\Enum\Period;

$past = $trovo->streams()->getPastStreams(
    channelId: 100000031,
    period: Period::Month,
    limit: 10,
);
// $past->items (PastStream[]), $past->total, $past->totalPage

Clips

$clips = $trovo->clips()->get(
    channelId: 100000031,
    period: Period::Week,
    limit: 20,
);
// $clips->items (Clip[]) — clipId, title, url, thumbnail, duration, views, likes

Chat

// Send to own channel (requires chat_send_self)
$trovo->chat()->sendToMyChannel('Hello!');

// Send to another channel (requires chat_send_self + send_to_my_channel)
$trovo->chat()->sendToChannel('Hello!', channelId: 100000031);

// Delete message (requires manage_messages)
$trovo->chat()->deleteMessage(
    channelId: '100000031',
    messageId: 'msg_123',
    userId: '100000021',
);

// Chat commands (requires manage_messages)
$result = $trovo->chat()->performCommand('mod @username', channelId: 100000031);
// $result->isSuccess, $result->displayMsg

Drops (App Access Token)

Drops APIs use Trovo Signature (HMAC-SHA1) automatically:

use Notwonderful\TrovoSdk\Enum\FulfillmentStatus;

$drops = $trovo->drops()->getEntitlements(
    limit: 50,
    fulfillmentStatus: FulfillmentStatus::Claimed,
);
// $drops->items (DropEntitlement[]), $drops->total, $drops->hasMore

$results = $trovo->drops()->updateEntitlements(
    entitlementIds: ['ent_1', 'ent_2'],
    fulfillmentStatus: FulfillmentStatus::Fulfilled,
);
// returns DropUpdateResult[] — entitlementId, status, isSuccess()

Laravel Integration

The package auto-registers its ServiceProvider via Laravel's package discovery.

Add credentials to your .env:

TROVO_CLIENT_ID=your_client_id
TROVO_CLIENT_SECRET=your_client_secret
TROVO_REDIRECT_URI=https://example.com/callback

Optionally publish the config:

php artisan vendor:publish --tag=trovo-config

Then resolve from the container:

use Notwonderful\TrovoSdk\TrovoClient;

$trovo = app(TrovoClient::class);
$categories = $trovo->categories()->getTopCategories();

Or inject via constructor:

public function __construct(private TrovoClient $trovo) {}

Error Handling

use Notwonderful\TrovoSdk\Exception\ApiException;
use Notwonderful\TrovoSdk\Exception\AuthenticationException;
use Notwonderful\TrovoSdk\Exception\RateLimitException;

try {
    $user = $trovo->users()->getUserInfo();
} catch (RateLimitException $e) {
    // $e->limit, $e->remaining, $e->resetsAt, $e->getSecondsUntilReset()
    sleep($e->getSecondsUntilReset());
} catch (AuthenticationException $e) {
    // Access token missing or not set
} catch (ApiException $e) {
    // $e->statusCode (HTTP), $e->trovoErrorCode, $e->trovoError, $e->getMessage()
}

Custom HTTP Client

Implement HttpClientInterface to use your own HTTP client or for testing:

use Notwonderful\TrovoSdk\Http\HttpClientInterface;

$trovo = new TrovoClient($config, new MyCustomHttpClient());

Available Scopes

Enum Value Description
Scope::UserDetailsSelf user_details_self View email and user profile
Scope::ChannelDetailsSelf channel_details_self View channel details + stream key
Scope::ChannelUpdateSelf channel_update_self Update channel settings
Scope::ChannelSubscriptions channel_subscriptions Get subscribers list
Scope::ChatSendSelf chat_send_self Send chat messages
Scope::SendToMyChannel send_to_my_channel Allow others to send to your channel
Scope::ManageMessages manage_messages Delete messages and chat commands

Support

If you like this package, please consider giving it a star ⭐ on GitHub!