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

Hipchat Laravel Package

laravel-notification-channels/hipchat

Laravel notification channel for sending messages to HipChat rooms via webhooks. It integrates with Laravel’s notification system so apps can deliver room alerts from notification classes, making it useful for legacy HipChat integrations.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check before you install: HipChat was discontinued by Atlassian in 2019, and this channel has been archived since its last release in November 2018. There is no supported HipChat cloud to send to. The only legitimate day-to-day use is maintaining a legacy Laravel app that still talks to an on-prem HipChat Server or an internal proxy that speaks the HipChat v2 API. For anything new, budget the migration to Slack/Teams/Discord instead of adopting this package.

What v2.2.0 changes: very little. The release is a dependency-constraint cleanup that widens the supported Laravel range to 5.7+. It is a maintenance bump on an archived package — it does not unarchive the project, does not restore any HipChat service, and does not add features. Treat it as "the constraints no longer fight you on a 5.7/5.8 app," not as a signal that the package is maintained again.

For the legacy case, the minimal path is:

  1. Install the channel (pin the version; don't float it):

    composer require laravel-notification-channels/hipchat:^2.2 --with-all-dependencies
    

    v2.2.0 loosened the constraint web, so a 5.7/5.8 app should resolve cleanly where earlier tags fought over Guzzle/Illuminate versions. Do not read "Laravel 5.7+" as "Laravel 10/11" — read the require block of the v2.2.0 tag before assuming. On anything modern you will still be overriding constraints in a fork branch rather than forcing --ignore-platform-reqs in production.

  2. Register the provider only if you're below Laravel 5.5. On 5.5+ package discovery handles NotificationChannels\HipChat\HipChatServiceProvider. On older apps, add it to config/app.php.

  3. Add credentials to config/services.php (this is the package's config surface — there is no separate publishable config file in most versions):

    'hipchat' => [
        'token' => env('HIPCHAT_TOKEN'),
    ],
    
    HIPCHAT_TOKEN=your-hipchat-api-v2-token
    

    The token needs permission to post room notifications (send_notification). Room notification tokens are scoped to a single room; a personal/integration token with broader scope lets you target rooms dynamically.

  4. Look here first:

    • src/HipChatChannel.php — how the room is resolved (message->room vs. routeNotificationFor...) and the exact API endpoint/base URI it calls.
    • src/HipChatMessage.php — the builder methods actually available (room, message, from, color, notify, format).
    • The exception class (conventionally CouldNotSendNotification) — what gets thrown on non-2xx responses.
    • composer.json at the v2.2.0 tag — the authoritative list of what "5.7+" actually means for your app.
    • README — for the exact services.php key name and builder method names for your pinned version.
  5. First use case — smoke test the token and room before writing any notification class. Wire a minimal notification and send it synchronously in tinker:

    use NotificationChannels\HipChat\HipChatChannel;
    use NotificationChannels\HipChat\HipChatMessage;
    use Illuminate\Notifications\Notification;
    
    class DeployFinished extends Notification
    {
        public function via($notifiable)
        {
            return [HipChatChannel::class];
        }
    
        public function toHipChat($notifiable)
        {
            return HipChatMessage::create()
                ->room('ops-alerts')
                ->from('Deploy Bot')
                ->message('Deploy #1234 finished')
                ->color('green');
        }
    }
    

    If that returns a 2xx and the message lands, everything else is just routing and message composition.

Implementation Patterns

Static room in the message, dynamic room on the notifiable. For team-wide alerts, hard-code ->room() in the notification. For per-user or per-tenant routing, implement the route method on the notifiable and let the channel fall back to it:

class Team extends Model
{
    use Notifiable;

    public function routeNotificationForHipChat($notification)
    {
        return $this->hipchat_room_id;
    }
}

Confirm precedence in HipChatChannel::send() — typically an explicit ->room() on the message wins, with the notifiable route as fallback. Knowing this prevents "why did it go to the wrong room" bugs.

Severity mapping in a base notification. Wrap the package's builder once so every alert has consistent color/notify semantics:

abstract class HipChatAlert extends Notification implements ShouldQueue
{
    protected function alert(string $text, string $severity): HipChatMessage
    {
        $color = match ($severity) {
            'critical' => 'red',
            'warning'  => 'yellow',
            default    => 'green',
        };

        return HipChatMessage::create()
            ->from(config('app.name'))
            ->message($text)
            ->color($color)
            ->notify($severity === 'critical'); // triggers HipChat notification, not just room history
    }
}

On-demand notifications. For ad-hoc messages that aren't tied to a model, use anonymous notifiable routing. Verify the route key against the channel source first — it's usually the channel name (HipChat):

Notification::route('HipChat', 'ops-alerts')->notify(new DeployFinished());

Queue everything, and throttle it. The channel makes a synchronous HTTP call. Implement ShouldQueue, put alerts on a dedicated queue, and rate-limit when you fan out to many rooms:

public function __construct(public string $message) {}

public function via($notifiable) { return [HipChatChannel::class]; }

public function middleware() // Laravel 8+; use ->onQueue('alerts') on older versions
{
    return [(new RateLimited('hipchat'))->dontReport()];
}

Guard dev/test environments. The easiest way to spam a real incident room is a local test suite. Configure rooms per environment and short-circuit outside production:

public function via($notifiable)
{
    return app()->environment('production') ? [HipChatChannel::class] : [];
}

Testing. Notification::fake() asserts that the channel was selected, not the payload:

Notification::fake();
$team->notify(new DeployFinished());

Notification::assertSentTo($team, DeployFinished::class, function ($notification, $channels) {
    return in_array(HipChatChannel::class, $channels, true);
});

v2.2.0 does not change the HTTP layer, so the package still predates Http::fake() and likely uses a Guzzle client directly. You usually cannot assert the outgoing request with Laravel's HTTP fake. Bind a Guzzle MockHandler into the container if the package resolves its client, or do a single integration test against a stub endpoint.

Abstract the channel now. Even if you're keeping the integration alive, define your own AlertChannel interface or a HipChatNotifier service and call that from jobs. When you migrate off HipChat, you change one class instead of hunting every via() method.

Gotchas and Tips

  • Archived, zero dependents, dead upstream — v2.2.0 doesn't change that. It's a constraint cleanup, not a revival. Treat any further change as a fork-and-patch job: pin the exact version in composer.json, vendor the source if necessary, and do not build new features on it. The high "opportunity" score here is the opportunity to replace it, not adopt it.
  • "Laravel 5.7+" is a floor, not a promise. Read the tag's composer.json rather than the release note. If you're on Laravel 9+, still expect to override Illuminate/Guzzle constraints in a fork branch — --ignore-platform-reqs in production is not a plan.
  • Hard-coded API base URI. The channel almost certainly targets https://api.hipchat.com/v2/. On-prem HipChat Server or a compatibility proxy needs a different host. Check HipChatChannel/the client class for a configurable base URL; if there isn't one, you'll need a fork or a local proxy that rewrites the host.
  • Token scope and room identity. Room IDs are safer than URL-encoded room names. A room-scoped token can only post to its own room — dynamic routing silently fails if you use one. A 401/403 from HipChat usually means scope, not a bad token string.
  • Colors are a fixed enum (yellow, green, red, purple, gray, random in the v2 API). An arbitrary hex value is rejected by the API. Keep severity→color mapping in one place.
  • notify is what makes noise. Without it, messages only appear in room history. Mentioning users requires notify(true) and the right message format plus valid user IDs (@UserId), not display names.
  • HTML format is an injection surface. If you pass user-supplied text with an HTML message format, escape it. Prefer plain text unless you deliberately need markup.
  • Message and payload limits. HipChat caps notification message length (order of 10k characters). Truncate stack traces and exception dumps before sending, or the API returns 4xx and your queued notification fails.
  • Failures bubble. The channel throws on non-2xx. In a queued notification, that means retries; a 4xx will never succeed on retry. Catch and fall back (log, or route to a secondary channel) rather than letting alerting failures mask the original incident.
  • Config caching. After adding the services.hipchat block, run php artisan config:cache in deployed environments. A stale config cache producing "token is null" is the most common self-inflicted failure here.
  • Notification::fake() lies about payloads. It won't catch a malformed room or a color the API rejects. Keep one real end-to-end smoke test against a staging room.
  • Migration mapping is straightforward: room → Slack channel/webhook, color → attachment color or emoji prefix, notify → <!channel> / <!here> or user mentions, from → attachment author or bot username. Write the mapping table before you start so behavior stays equivalent during cutover.
  • Extension points, limited but usable: subclass HipChatMessage to add defaults, wrap the channel in your own notification channel class implementing send(), or replace the package entirely with a ~40-line channel built on Laravel's HTTP client pointing at whatever incident tool you actually use. Given the package's state, the third option is usually the cheapest long-term move.
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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route