huangdijia/laravel-youdu
Laravel integration for the Youdu (有度) enterprise messaging platform. Send text, image, file, and app messages to users, departments, and groups, and route Laravel notifications through Youdu with a simple, configurable API.
huangdijia/laravel-youdu is the Laravel bridge for Youdu (有度), the self-hosted enterprise IM from Beijing Erwei. It gives you a service provider, a config file, and a Youdu facade over the underlying huangdijia/youdu SDK, so you can send app messages, SMS, and manage departments/users/groups without hand-rolling the HTTP + access-token dance.
composer require huangdijia/laravel-youdu
php artisan vendor:publish --tag=youdu-config # confirm the tag from the provider if this no-ops
Package discovery registers the provider and the Youdu facade alias. Set the connection in .env (keys as they appear in the published config/youdu.php; typically YOUDU_API, YOUDU_APP_ID, YOUDU_APP_SECRET, YOUDU_BUNDLE_ID). The API URL is your own Youdu server, e.g. https://youdu.example.com:7080.
First real use case — notify a user from a queued job:
use Huangdijia\LaravelYoudu\Facades\Youdu;
Youdu::sendAppMessage('zhangsan', 'Deploy finished on prod');
// or the raw client if you need the full msg_type/msg payload
Youdu::app()->sendMsg([...]);
Read these three things before writing code: config/youdu.php (what's configurable), src/Facades/Youdu.php + the bound client class (the actual method list — it proxies the SDK, so IDE completion is hit-or-miss), and vendor/huangdijia/youdu/src/ (the endpoint wrappers and response shape).
Inject the client, don't sprinkle the facade. The facade is convenient in a controller or a tinker session, but for anything testable type-hint the underlying client (or a thin YouduNotifier wrapper you own) in the constructor. That gives you one seam to fake in tests and one place to add logging/retry.
Wrap sends in queued jobs. Every call is a synchronous Guzzle request to your own infrastructure; a slow or unreachable Youdu server should never block a web request. A SendYouduMessage job with $tries = 3 and backoff() is the default pattern — but see the idempotency note in Gotchas.
Map Laravel users to Youdu ids once. Add a youdu_user_id (and youdu_dept_id for org routing) column, or resolve via a YouduIdentityResolver service that falls back to email/phone matching. Doing this ad hoc at each call site is the most common source of "message went to the wrong person" bugs.
Broadcast to departments, not individuals. For announcements, target a dept id and let Youdu fan out; looping over users is slower and hits rate limits. Note that dept lookup by name/path is exactly what v3.0.1's Dept::getId fix touches — if you resolve dept names to ids, pin ^3.0.1.
Wire it into Laravel's notification system. A custom YouduChannel taking toYoudu($notifiable) keeps your notification classes channel-agnostic and lets users opt in/out like any other channel.
Multi-app / multi-tenant. If your config supports named app connections, resolve the connection per tenant at call time and cache the resolved client in the container; don't rebuild it per message.
Testing. Youdu::shouldReceive('sendAppMessage')->once() works for facade-level assertions. For jobs, prefer swapping your own wrapper binding with a spy so you assert on intent, not on SDK method strings that shift between SDK versions.
Dept::getId (PR #4, first-time contributor). No API changes, no deprecations. If you're on 3.0.0 and rely on name→dept-id resolution, upgrade — composer update huangdijia/laravel-youdu and re-run your dept lookup tests. If you resolve dept ids from a hardcoded cache written by 3.0.0, invalidate it.redis/database, not array), and that a warm-up race doesn't stampede the token endpoint. If you see intermittent auth errors after a deploy, it's almost always two processes refreshing simultaneously.config:cache traps. Changing YOUDU_* in .env does nothing until you re-run php artisan config:cache on cached environments. Same for the published config file — it's read once.verify; if you must, scope it to the Youdu client only, never globally.youdu_messages ledger keyed by a message UUID, or WithoutOverlapping on the job) before enabling $tries > 1.(string) casts before keying arrays or comparing, or your lookups will silently miss.sendAppMessage covers text; images, files, and link cards need the raw msg_type + msg array. Content must be a string/JSON-encoded value, not an array, in several endpoints.composer.json constraints before upgrading a legacy app, and pin ^3.0.1 on new work so you get the Dept::getId fix.How can I help you explore Laravel packages today?