laravel-notification-channels / google-chat
Google Chat Notification Channel for Laravel (fka. Hangouts Chat)
Installs: 343 529
Dependents: 2
Suggesters: 0
Security: 0
Stars: 46
Watchers: 11
Forks: 19
Open Issues: 7
Requires
- php: >=8.0
- guzzlehttp/guzzle: ^6.3 || ^7.0
- illuminate/notifications: ^9.0.2 || ^10.0 || ^11.0
- illuminate/support: ^9.0.2 || ^10.0 || ^11.0
Requires (Dev)
- orchestra/testbench: ^7.0 || ^9.0
- phpunit/phpunit: ^9.5.10 || ^10.5
README
Google Chat - Laravel Notification Channel
This package makes it easy to send notifications using Google Chat , (formerly known as Hangouts Chat) with Laravel 9.x
class InvoicePaidNotification extends Notification { // Create a super simple message public function toGoogleChat($notifiable) { return GoogleChatMessage::create('An invoice was paid!'); } // ...Or you can use some simple formatting public function toGoogleChat($notifiable) { return GoogleChatMessage::create() ->text('Someone just paid an invoice... ') ->bold('Woo-hoo!') ->line('Looking for ') ->link(route('invoices'), 'the details?') ->to('sales_team'); // ... and route it to specific rooms } // ...You can even make a fancy card! public function toGoogleChat($notifiable) { return GoogleChatMessage::create() ->text('Invoice Paid! Here\'s the details:') ->card( Card::create( Section::create( KeyValue::create('Amount', '$520.99', '#10004756') ->onClick(route('invoices')) ->button(TextButton::create(route('invoices'), 'View')) ) ) ) } }
For Laravel 8.x, please use version 1.x of this package.
Contents
- Installation
- Configuring & Using Webhooks in Your Application
- Usage
- API Overview
- Changelog
- Testing
- Security
- Contributing
- Credits
- License
Installation
The Google Chat notification channel can be installed easily via Composer:
$ composer require laravel-notification-channels/google-chat
Generating a Webhook
This package makes use of Google Chat's convenient 'Webhooks' feature, which allows for quick and easy setup.
You can learn how to create a room, and generate a new Webhook on Google's documentation.
Throughout Google's own documentation, the term 'space' is used to reference conversations generally across Google Chat, whether that be a one-on-one chat between co-workers, or a 'room' with conversations between multiple people.
Although this package only has the ability to send messages into 'rooms', we still refer to a room as a 'space' for consistency between this package's documentation, and Google's.
Configuring & Using Webhooks in Your Application
Firstly, let's publish the configuration file used by the Google Chat notification channel into your application, so that we can start configuring our webhooks:
$ php artisan vendor:publish --tag google-chat-config
Default Room
If we only have a single room / webhook we want to post into, we can simply configure the space
key which defines the default conversation notifications sent via the Google Chat channel will be posted to.
// config/google-chat.php return [ 'space' => 'https://chat.googleapis.com/room-webhook-for-all-notifications?key=xxxxx' ]
Notifications that have not otherwise been directed to another room will now be sent to this default space.
CAUTION! If your application sends sensitive notifications via Google Chat, we recommend you configure the space
key to NULL
, so that notifications must be explicitly directed to an endpoint.
Alternate Rooms (Preferred)
You can also define alternate webhooks under the spaces
(plural) key, and reference these more easily throughout your application:
// config/google-chat.php return [ 'spaces' => [ 'sales_team' => 'https://chat.googleapis.com/sales-team-room?key=xxxxx', 'dev_team' => 'https://chat.googleapis.com/dev-team-room?key=xxxxx', 'executive' => 'https://chat.googleapis.com/executives?key=xxxxx', ] ]
You can now direct notifications to one of these configured rooms by using the relevant key anywhere you can route notifications, like:
Notification::route('googleChat', 'sales_team')->... // Or GoogleChatMessage::create()->to('dev_team')->... // Or, even in your notifiable class: public function routeNotificationForGoogleChat() { return 'executive'; }
Explicit Webhook Routing
If needed, you can route notifications to explicit webhooks in all the same places listed above. This isn't the preferred method, however, as it gives you less flexibility should you ever need to change a webhook.
Notification::route('googleChat', 'https://chat.googleapis.com/xxxxx')->... // Or GoogleChatMessage::create()->to('https://chat.googleapis.com/xxxxx')->... // Or, even in your notifiable class: public function routeNotificationForGoogleChat() { return 'https://chat.googleapis.com/xxxxx'; }
Usage
In order to send a notification via the Google Chat channel, you'll need to specify the channel in the via()
method of your notification:
use NotificationChannels\GoogleChat\GoogleChatChannel; // ... public function via($notifiable) { return [ GoogleChatChannel::class ] }
If you haven't already, make sure you understand how notification classes are constructed.
Google Chat messages have two formats: Simple Messages, and Card Messages. This package allows you to construct both.
Simple Messages
Simple messages can be created easily using a NotificationChannels\GoogleChat\GoogleChatMessage
instance directly, and returned in your notification class like so:
use NotificationChannels\GoogleChat\GoogleChatMessage; public function toGoogleChat($notifiable) { return GoogleChatMessage::create('Hello world!'); }
Simple messages can also contain basic formatting:
use NotificationChannels\GoogleChat\GoogleChatMessage; public function toGoogleChat($notifiable) { return GoogleChatMessage::create() ->bold('Heads Up!') ->line('An error was encountered whilst communicating with an external service:') ->monospaceBlock($this->errorMessage) ->italic('Want to know more? ') ->link('https://status.example.com/logs', 'Check Out the Logs.'); }
Card Messages
Google Chat cards are more complex pieces of UI that can display organized information to the recipient. Cards are added to a GoogleChatMessage
instance, and can be used in combination with a simple message.
The structure of cards in this package closely resembles the actual data format sent to the webhook endpoint. For this reason, it's worth checking out how cards are structured.
use NotificationChannels\GoogleChat\GoogleChatMessage; use NotificationChannels\GoogleChat\Card; use NotificationChannels\GoogleChat\Section; use NotificationChannels\GoogleChat\Widgets\KeyValue; use NotificationChannels\GoogleChat\Enums\Icon; use NotificationChannels\GoogleChat\Enums\ImageStyle; public function toGoogleChat($notifiable) { return GoogleChatMessage::create() ->text('An invoice was just paid... ') ->bold('Woo-hoo!') ->card( Card::create() ->header( 'Invoice Paid', '#1004756', 'https://cdn.example.com/avatars/xxx.png', ImageStyle::CIRCULAR ) ->section( Section::create( KeyValue::create( 'Payment Received', '$20.14', 'Paid by Josephine Smith' ) ->icon(Icon::DOLLAR) ->onClick(route('invoice.show')) ) ) ) }
Visual learner? Us too. Here's a visual overview of the card structure:
cards
|
|---card
| |
| |---header (complex)
| | ...
| |
| |---sections
| | |
| | |---section
| | | |
| | | |---header (simple)
| | | | ...
| | | |
| | | |---widgets
| | | | |
| | | | |---widget
| | | | | ...
| | | | |
| | | | |---widget
| | | | | ...
| | |
| | |---section
| | | ...
|
|---card
| ...
API Overview
Google Chat Message
Namespace: NotificationChannels\GoogleChat\GoogleChatMessage
The GoogleChatMessage
class encompasses an entire message that will be sent to the Google Chat room.
static create(?string $text)
Instantiates and returns a newGoogleChatMessage
instance, optionally pre-configuring it with the provided simple textto(string $space)
Specifies the webhook or space key this notification will be sent to. This takes precedence over the default space and any value returned by a notifiable'srouteNotificationForGoogleChat()
methodtext(string $message)
Appends$message
to the simple message contentline(string $message)
Appends$message
on a new linebold(string $message)
Appends bold textitalic(string $message)
Appends italic textstrikethrough(string $message)
Appends strikethorugh textstrike(string $message)
Alias forstrikethrough()
monospace(string $message)
Appends monospace textmono(string $message)
Alias formonospace()
monospaceBlock(string $message)
Appends a block of monospace textlink(string $link, ?string $displayText)
Appends a text link, optionally with custom display textmention(string $userId)
Appends a mention text targeting a specific user idmentionAll(?string $prependText, ?string $appendText)
Appends a mention-all text, optionally with text before and after the blockcard(Card|Card[] $card)
Add one or more complex card UIs to the message
Card Layout
The layout is split into two concepts: The card, and the section. The card can be thought of as the container, whilst the sections can be thought of as rows within the card itself. The card can have a complex, overarching header, whilst each section can contain a simple text based header.
You can add multiple sections to a card, in order to group related pieces of information.
Card
Namespace: NotificationChannels\GoogleChat\Card
The Card
class represents the top level layout definition for a Card UI to be sent in a message. Cards define one or more sections, and may optionally define header information
static create(Section|Section[]|null $section)
Instantiates and returns a newCard
instance, optionally pre-configuring it with the provided section or sectionsheader(string $title, ?string $subtitle, ?string $imageUrl, ?string $imageStyle)
Optional - Configures the header UI for the card. Note that$imageStyle
is one of the constants defined inNotificationChannels\GoogleChat\Enums\ImageStyle
section(Section|Section[] $section)
Add one or more sections to the card
Section
Namespace: NotificationChannels\GoogleChat\Section
The Section
class defines the intermediary layout definition of a card. From a UI perspective, it groups related widgets.
static create(AbstractWidget|AbstractWidget[]|null $widgets)
Instantiates and returns a newSection
instance, optionally pre-configuring it with the provided widget or widgetsheader(string $text)
Optionally defines the simple header displayed at the top of the sectionwidget(AbstractWidget|AbstractWidgets[] $widget)
Adds one or more widgets to the section
Widgets
Widgets are the meaningful pieces of UI displayed throughout a single card. There are different types of widgets, in order to display information more appropriately to the user.
Widgets are added to a section, and a section can contain multiple widgets of various types.
Text Paragraph
Namespace: NotificationChannels\GoogleChat\Widgets\TextParagraph
The TextParagraph
widget defines rich text. This widget can define more complex text formats than permissible in a simple message.
static create(?string $message)
Instantiates and returns a newTextParagraph
instance, optionally pre-configuring it with the provided texttext(string $message)
Appends the$message
to the widget contentbold(string $message)
Appends bold textitalic(string $message)
Appends italic textunderline(string $message)
Appends underline textstrikethrough(string $message)
Appends strikethrough textstrike(string $message)
Alias forstrikethrough()
color(string $message, string $hex)
Appends colored text according to the$hex
colorlink(string $link, ?string $displayText)
Appends a textual link, optionally with the provided display textbreak()
Appends a line break
Key Value
Namespace: NotificationChannels\GoogleChat\Widgets\KeyValue
The KeyValue
widget defines a table like element that can segment information and provide an external click through
static create(?string $topLabel, ?string $content, ?string $bottomLabel)
Instantiates and returns a newKeyValue
instance, optionally pre-configuring it with a top label, content and bottom label.topLabel(string $message)
Defines the top label textcontent(string $content)
Defines the primary text content of the widgetbottomLabel(string $message)
Defines the bottom label textsetContentMultiline(bool $value)
Determines whether the primary content should flow onto multiple lines. Google defaults this value tofalse
onClick(string $url)
Defines a click through URL which can be activated by clicking the widget itself. Note that this is a different definition from the button, which may optionally be added to the widget too.icon(string $icon)
Defines the glyph icon displayed with the text content; One of the constants defined inNotificationChannels\GoogleChat\Enums\Icon
button(AbstractButton $button)
Optionally defines a button displayed alongside the text content
Image
Namespace: NotificationChannels\GoogleChat\Widgets\Image
The Image
widget defines a simple image to be displayed in the card. Optionally, a click through URL can be configured for when a user clicks/taps on the image.
static create(?string $imageUrl, ?string $onClickUrl)
Instantiates and returns a newImage
instance, optionally pre-configuring it with an image URL and click through URL.imageUrl(string $url)
Defines the image URL where the image can be sourcedonClick(string $url)
Defines a URL the user will be taken to if they click/tap on the image
Buttons
Namespace: NotificationChannels\GoogleChat\Widgets\Buttons
The Buttons
widget acts as a container for one or more buttons, laid out horizontally. This widget accepts instances of NotificationChannels\GoogleChat\Components\Button\AbstractButton
and can accept buttons of different types.
static create(AbstractButton|AbstractButton[]|null $buttons)
Instantiates and returns a newButtons
instance, optionally pre-configuring it with the provided buttonsbutton(AbstractButton|AbstractButton[] $button)
Adds one or more buttons
Components
Components are structures that are nestled within widgets. For simplicity, the Google Chat notification channel only supports button components.
Both the Text Button and Image Button can be nested within the Buttons
widget, as well as in the button properties of the KeyValue
and ImageWidget
.
Text Button
Namespace: NotificationChannels\GoogleChat\Components\Button\TextButton
The TextButton
defines a simple text button, and can be accepted anywhere that an AbstractButton
is accepted.
static create(?string $url, ?string $displayText)
Instantiates and returns a newTextButton
instance, optionally pre-configuring it with the provided URL and display texturl(string $url)
Defines the target endpoint for the buttontext(string $text)
Defines the display text for the button
Image Button
Namespace: NotificationChannels\GoogleChat\Components\Button\ImageButton
The ImageButton
defines a clickable icon or image, and can be accepted anywhere that an AbstractButton
is accepted. The icon can either be a default icon (one of the constants defined in NotificationChannels\GoogleChat\Enums\Icon
) or an external image url.
static create(?string $url, ?string $icon)
Instantiates and returns a newImageButton
instance, optionally pre-configuring it with the provided URL and iconurl(string $url)
Defines the target endpoint for the buttonicon(string $icon)
Defines the icon or image to display for the button.
Changelog
Please see CHANGELOG for more information what has changed recently.
Testing
$ composer test
The test suite also includes one end-to-end test. In order for this test to pass, a GOOGLE_CHAT_TEST_SPACE
environment variable should be set, containing a webhook to a test room.
Alternatively, you can exclude this test with PHPUnit during local development:
$ ./vendor/bin/phpunit --exclude-group external
Security
If you discover any security related issues, please email frank@thetreehouse.family instead of using the issue tracker.
Contributing
Please see CONTRIBUTING for details.
Credits
License
The MIT License (MIT). Please see License File for more information.