Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ten Im Laravel Package

hedeqiang/ten-im

Tencent Cloud IM (Instant Messaging) SDK wrapper for Laravel, making it easy to integrate Tencent's IM services into your application. Provides a simple, framework-friendly interface for common IM operations such as account management, messaging, and group handling, so you can add real-time chat fea...

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and publish its configuration:

composer require hedeqiang/ten-im
php artisan vendor:publish --provider="Hedeqiang\TenIM\ServiceProvider"

This creates config/ten-im.php. Populate it in .env with values from the Tencent Cloud IM console (Application → Basic configuration and Account management):

TEN_IM_SDK_APP_ID=1400xxxxxx
TEN_IM_KEY=your_secret_key
TEN_IM_IDENTIFIER=admin
TEN_IM_EXPIRE=86400

identifier is the admin IM account created in the console, not a random user — all backend requests are authenticated as this account, so it must have permission for the endpoints you call.

First use case — generating a usersig so a client SDK can log in:

use Hedeqiang\TenIM\Facades\TenIM;

$sig = TenIM::genSig($userId);
// return ['usersig' => $sig, 'sdkappid' => ..., 'identifier' => $userId]

That single call is what most teams actually need 90% of the time: your Laravel auth layer verifies credentials, then hands the client a signed usersig to pass to tim.login({userID, userSig}). From there, call any server-side REST endpoint through the same facade — e.g. importing accounts, creating groups, or sending system messages.

Implementation Patterns

Thin controller, fat service. Wrap the facade behind your own service so you can mock it and centralize error handling:

class ImService
{
    public function userSig(string $userId): string
    {
        return TenIM::genSig($userId);
    }

    public function importAccount(string $userId, string $nick = '', string $avatar = ''): array
    {
        return TenIM::account_import([
            'UserID'   => $userId,
            'Nick'     => $nick,
            'FaceUrl'  => $avatar,
        ]);
    }
}

Cache usersigs. They are valid for TEN_IM_EXPIRE seconds and are deterministic within that window. Cache with a safety margin under the TTL and key by user id:

public function userSig(string $userId): string
{
    return Cache::remember(
        "tim:usersig:{$userId}",
        now()->addSeconds(config('ten-im.expire') - 300),
        fn () => TenIM::genSig($userId)
    );
}

Sync users on registration/profile update. Hook your User model events into account_import (idempotent — Tencent overwrites profile fields). Fire the import in a queued job so a Tencent hiccup doesn't block your registration flow.

Bulk operations. For batch account imports, chunk your user list (the API caps batch size) and dispatch one job per chunk with a slight delay to stay inside rate limits.

Group lifecycle. Create a group when a team/room is created in your app, and store Tencent's GroupId on your model. The server-side group APIs (create_group, add_group_member, destroy_group) are the standard pattern for keeping your domain model and the IM group in lockstep.

Send server-side messages for notifications. Use the REST send-message endpoint for system notifications (order shipped, invoice ready) rather than the client SDK — you control the sender identity (identifier) and audit trail.

Testing. Because the package ultimately issues HTTP calls against https://console.tim.qq.com, bind a fake in tests or swap your ImService for a mock. Avoid hitting the live API in CI.

Gotchas and Tips

  • Pin the version. Last release was July 2023 — specify an exact constraint ("hedeqiang/ten-im": "1.x.y") so a silent transitive dependency change doesn't break you. With 0 dependents, expect to read the source when something behaves unexpectedly.

  • Check ErrorCode, not HTTP status. Tencent IM returns 200 OK with ActionStatus: "FAIL" on business errors. Always inspect ErrorCode/ErrorInfo even when the call succeeds at the transport level:

    $res = TenIM::account_import($payload);
    if (($res['ActionStatus'] ?? '') !== 'OK') {
        throw new ImException($res['ErrorInfo'] ?? 'unknown', $res['ErrorCode'] ?? -1);
    }
    
  • Clock skew breaks signatures. The usersig embeds a timestamp; if your server clock drifts more than a few minutes, logins silently fail. Run NTP on app servers.

  • Admin permissions are per-endpoint. identifier in config/ten-im.php must hold the corresponding console privileges. A missing permission shows up as a generic failure on that endpoint only — check Account management → admin account → permissions first when debugging a single failing method.

  • Don't log the payloads. TEN_IM_KEY and returned usersig values are credentials; scrub them from Laravel logs, Sentry, and Telescope exports.

  • Rate limits are per API and per app. genSig is local (no network), but account/group/message endpoints are rate limited. Add retry-with-backoff around ActionStatus: "FAIL" responses that carry a rate-limit ErrorCode (usually -1 or 10002-ish depending on endpoint) rather than retrying all failures blindly.

  • Wrap the HTTP layer for timeouts. The package delegates to an HTTP client; set a connect_timeout/timeout at the Guzzle/Http level rather than relying on defaults, especially inside request cycles.

  • Callback verification isn't included. When Tencent calls your server-side callback (e.g. after-user-login hooks), you must verify the signature yourself — the package is a client SDK and won't do it.

  • Fall back to raw REST if needed. The REST surface is stable and documented; when the package lags a new endpoint (releases stopped in 2023), hit https://console.tim.qq.com/v4/{svc}/{cmd} directly and reuse the package only for genSig. Keeping the signature generation behind your ImService makes this migration trivial.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels