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

Lark Custom Bot Bundle Laravel Package

tourze/lark-custom-bot-bundle

Integrates Lark/Feishu custom bot webhooks into Symfony applications, providing configuration and services to send notifications and messages to group chats with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

tourze/lark-custom-bot-bundle is a Tourze-ecosystem package for talking to a Lark/Feishu custom bot (the webhook you get from a group chat: Settings → Bots → Add Custom Bot). That means the day-to-day use case is narrow and concrete: push text, rich-post, or interactive-card messages into a chat from your Laravel app (deploy notices, order alerts, error escalations).

Important framing before you composer require: despite the Laravel context, this is a Symfony bundle, not a Laravel package. 0.0.1 ships with only a changelog link — there is no README, no documented config tree, no service provider, no facade. Treat it as source-code-first.

Minimal steps:

  1. composer require tourze/lark-custom-bot-bundle:0.0.1 — pin the exact version. There is no stability promise at this tag.
  2. Read the package before wiring it. Look in this order:
    • vendor/tourze/lark-custom-bot-bundle/src/ — the *Bundle class, any *Interface files, and the client/message classes.
    • src/DependencyInjection/ — the extension class shows the config keys the bundle expects (webhook URL, secret, etc.). This is your de-facto documentation.
    • Resources/config/services.yaml (or config/services.php in newer Tourze layouts) — the service IDs and constructor arguments you'll need to reproduce.
  3. Create the bot in Lark, copy the webhook URL and, if you enable it, the signing secret.
  4. Because Laravel won't auto-register a Symfony Bundle, register the needed classes yourself in a service provider:
// app/Providers/LarkBotServiceProvider.php
public function register(): void
{
    $this->app->singleton(LarkBotClient::class, fn () => new LarkBotClient(
        webhookUrl: config('services.lark_bot.webhook'),
        secret:     config('services.lark_bot.secret'),
    ));
}
  1. First smoke test: send a plain text message and assert on the response body, not the HTTP status (Lark returns HTTP 200 for failures).

If the above sounds like more glue than value, that is a legitimate read at 0.0.1 — see Gotchas.

Implementation Patterns

Config over constructor. Keep the webhook URL and secret in config/services.php and .env (LARK_BOT_WEBHOOK, LARK_BOT_SECRET), then feed them into whichever class the bundle exposes. Do not let the Symfony config tree leak into your app — you're bypassing it anyway.

One bot per channel, resolved by name. Real apps need multiple bots (deploy channel, on-call channel, per-tenant). Model that as a small resolver rather than a hardcoded singleton:

class LarkBotManager
{
    /** @param array<string, array{webhook: string, secret: ?string}> $bots */
    public function __construct(private array $bots) {}

    public function channel(string $name): LarkBotClient { /* cached factory */ }
}

Wrap it in a Notification channel. This is the highest-leverage integration for a Laravel dev: one LarkChannel class implementing send(), then Notification::route('lark', $webhook) or a routeNotificationForLark() on your User/Team model. It gives you queueing, ShouldQueue, and per-notification toLark() payload shaping for free — things the bundle will never provide in a Symfony-first design.

Always queue outbound sends. implements ShouldQueue on the notification/job, with tries = 3 and backoff = [1, 5, 15]. Custom bots are rate-limited (roughly 5 msg/sec and 100/min per bot); a burst of exception alerts will happily trip this.

Signing. If the bot has a secret enabled, the request needs timestamp (seconds) and sign = base64(hmac_sha256(key: secret, data: "{timestamp}\n{secret}")). The HMAC key is the secret and the payload is the concatenation — this is the single most common misimplementation. Verify what the bundle actually does here rather than assuming.

Rich cards for anything beyond text. Text messages are fine for a one-line deploy ping; for error alerts use an interactive card (colored header, fields, a "view logs" button). Build the card as a PHP array in a dedicated LarkCard value object so it's testable and reusable, rather than inlining 60 lines of nested arrays in a job.

Test without network. Bind a fake client in the container during tests and assert on the captured payloads. For integration-style tests, Http::fake() works if the bundle ends up going through Laravel/Symfony's HTTP client; if it constructs its own Guzzle client internally, you'll want to decorate or wrap it behind your own interface so testing stays possible.

Local/CI environments. Gate sending behind config('services.lark_bot.enabled') (false in local/testing). Nobody wants a bot spamming the team channel from a developer's failing test suite.

Gotchas and Tips

  • 0.0.1 with an empty changelog is the headline risk. No documented features, no upgrade path, no API stability. Pin "tourze/lark-custom-bot-bundle": "0.0.1" exactly (no ^), and isolate it behind your own thin interface (LarkNotifier) so swapping to raw Http::post() later is a one-file change.
  • Symfony bundle in a Laravel app. You inherit symfony/dependency-injection, symfony/config, symfony/http-kernel and friends in your vendor/ for what is, functionally, one HTTP POST. Audit composer why symfony/http-kernel after install. For many teams the honest recommendation is: read the ~200 lines of signing/payload logic, reimplement it with Http in 20 lines, and skip the dependency.
  • HTTP 200 does not mean success. Lark returns {"code": 0, "msg": "success"} on success and non-zero code with HTTP 200 on failure. Check $response['code'] === 0; log code + msg on anything else.
  • Signing failure is opaque. A wrong secret, a millisecond timestamp, or hashing the wrong string all produce a generic sign-match error. Log the exact timestamp/sign you sent when debugging, and confirm the server clock is sane.
  • Rate limits surface as errors, not 429s. Blind retries make it worse. Use exponential backoff and consider a small throttle keyed on the bot.
  • No Laravel config publishing. There's no vendor:publish, no config/lark.php. Any config keys you find in DependencyInjection/ are Symfony config-tree keys and won't be read by Laravel's config() unless you bridge them explicitly.
  • Extension points. Check for interfaces in src/ before reaching for inheritance — decorating a client or *ProviderInterface is the intended Tourze pattern and keeps you upgrade-safe. If there are no interfaces, wrap rather than extend.
  • Message size and @-mentions. Text bodies have a practical length ceiling (truncate long stack traces, link to the full log instead). Mentioning users in a custom bot message is restricted compared to app-bot messages — verify what actually renders before promising @-on-call in a design doc.
  • Watch the repo, not the changelog. https://github.com/tourze/lark-custom-bot-bundle/commits/0.0.1 is the only release artifact. Diff against the next tag before upgrading; at 0.x, assume breaking.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo