PHP code example of agencelex / notifications-microsoft-teams

1. Go to this page and download the library: Download agencelex/notifications-microsoft-teams library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

agencelex / notifications-microsoft-teams example snippets


use Lex\Notifications\Notification;
use Lex\Notifications\MicrosoftTeams\Channel\TeamsChannel;
use Lex\Notifications\MicrosoftTeams\Domain\Model\Ability\CanSendToTeams;
use Lex\Notifications\MicrosoftTeams\Message\AdaptiveCard;
use Lex\Notifications\MicrosoftTeams\Message\Action\OpenUrl;
use Lex\Notifications\MicrosoftTeams\Message\Element\TextBlock;
use Lex\Notifications\MicrosoftTeams\Message\TeamsMessage;

class HelloTeamsNotification extends Notification
{
    use CanSendToTeams;

    public function via(object $notifiable): array
    {
        return [TeamsChannel::CHANNEL];
    }

    public function toTeams(object $notifiable): TeamsMessage
    {
        return TeamsMessage::create()
            ->card(
                AdaptiveCard::make()
                    ->body([
                        TextBlock::make('Hello from TYPO3!')->weight('Bolder')->size('Large'),
                        TextBlock::make('Your notification system is working.')->wrap(true),
                    ])
                    ->actions([
                        OpenUrl::make('Visit site', 'https://example.com'),
                    ])
            );
    }
}

// Inject NotificationDispatcherInterface via constructor
$this->notificationDispatcher->send($frontendUser, new HelloTeamsNotification());

use Lex\Notifications\Notification;
use Lex\Notifications\MicrosoftTeams\Domain\Model\Ability\CanSendToTeams;
use Lex\Notifications\MicrosoftTeams\Message\TeamsMessage;

class MyNotification extends Notification
{
    use CanSendToTeams;

    // Enforced by the trait — omitting this causes a fatal error
    public function toTeams(object $notifiable): TeamsMessage
    {
        return TeamsMessage::create()->card(AdaptiveCard::make()->body([...]));
    }
}

use Lex\Notifications\Domain\Model\Ability\Notifiable;
use Lex\Notifications\MicrosoftTeams\Domain\Model\Ability\HasRouteNotificationForTeams;

class MyFrontendUser extends AbstractEntity
{
    use Notifiable;
    use HasRouteNotificationForTeams;

    public function routeNotificationForTeams(): string
    {
        return 'https://prod.webhook.office.com/webhookb2/...';
    }
}

public function toTeams(object $notifiable): TeamsMessage
{
    return TeamsMessage::create()
        ->webhookUrl('https://prod.webhook.office.com/webhookb2/...')
        ->card(AdaptiveCard::make()->body([...]));
}

class Department extends AbstractEntity
{
    use Notifiable;
    use HasRouteNotificationForTeams;

    public function routeNotificationForTeams(): string
    {
        return $this->teamsWebhookUrl; // stored on the entity
    }
}

AdaptiveCard::make()
    ->version('1.6')                         // optional, default 1.6
    ->body([...elements...])                 // set all body elements at once
    ->add(TextBlock::make('More text'))      // append individual elements
    ->actions([...actions...])               // card-level action buttons
    ->addAction(OpenUrl::make('...', '…'))   // append individual actions
    ->minHeight('200px')                     // optional minimum card height
    ->verticalContentAlignment('Center')     // Top | Center | Bottom
    ->backgroundImage('https://…/bg.png')   // optional background image URL
    ->rtl(true)                              // right-to-left text
    ->speak('Screen reader text');           // accessibility narration

TextBlock::make('Hello, world!')
    ->size('Large')                 // Default | Small | Medium | Large | ExtraLarge
    ->weight('Bolder')              // Default | Lighter | Bolder
    ->color('Accent')               // Default | Dark | Light | Accent | Good | Warning | Attention
    ->horizontalAlignment('Center') // Left | Center | Right
    ->fontType('Monospace')         // Default | Monospace
    ->isSubtle(true)                // reduced emphasis
    ->wrap(false)                   // disable wrapping
    ->maxLines(3)                   // truncate after N lines
    ->style('heading')              // default | heading | columnHeader
    ->spacing('Medium')             // None | Small | Default | Medium | Large | ExtraLarge | Padding
    ->separator(true);              // draw a line above this element

FactSet::make([
    Fact::make('Customer', 'Jane Doe'),
    Fact::make('Order #',  '98765'),
    Fact::make('Total',    '€149.00'),
    Fact::make('Status',   'Paid'),
])->spacing('Medium');

// Single image
Image::make('https://example.com/logo.png')
    ->altText('Company logo')
    ->size('Medium')                // Auto | Stretch | Small | Medium | Large
    ->style('Person')               // Default | Person (renders as a circle avatar)
    ->horizontalAlignment('Center')
    ->backgroundColor('#f0f0f0')    // CSS colour for transparent PNGs
    ->width('80px')                 // explicit pixel width
    ->selectAction(OpenUrl::make('Visit', 'https://example.com'));

// Collection of images
ImageSet::make([
    Image::make('https://example.com/a.png'),
    Image::make('https://example.com/b.png'),
    Image::make('https://example.com/c.png'),
])->size('Small');

Container::make([
    TextBlock::make('Section Title')->weight('Bolder'),
    TextBlock::make('Body text goes here.')->wrap(true),
    FactSet::make([Fact::make('Key', 'Value')]),
])
->style('emphasis')                 // default | emphasis | good | attention | warning | accent
->bleed(true)                       // extend to cover surrounding padding
->minHeight('100px')
->verticalContentAlignment('Top')   // Top | Center | Bottom
->selectAction(OpenUrl::make('Open', 'https://example.com'));

ColumnSet::make([
    Column::make([
        Image::make('https://example.com/avatar.png')
            ->style('Person')
            ->size('Small'),
    ])->width('auto'),

    Column::make([
        TextBlock::make('Jane Doe')->weight('Bolder'),
        TextBlock::make('Engineering Lead')->isSubtle(true)->spacing('None'),
    ])->width('stretch'),
])->spacing('Medium');

RichTextBlock::make([
    ['type' => 'TextRun', 'text' => 'Deploy status: '],
    ['type' => 'TextRun', 'text' => 'SUCCESS', 'color' => 'Good', 'weight' => 'Bolder'],
])
->addInline(['type' => 'TextRun', 'text' => ' — no issues found.', 'isSubtle' => true]);

ActionSet::make([
    OpenUrl::make('View in browser', 'https://example.com'),
    Submit::make('Acknowledge', ['action' => 'ack']),
]);

use Lex\Notifications\MicrosoftTeams\Message\Action\OpenUrl;

OpenUrl::make('View Order', 'https://example.com/orders/123')
    ->style('positive')   // default | positive | destructive
    ->iconUrl('https://example.com/icons/view.png')
    ->tooltip('Opens the order detail page');

use Lex\Notifications\MicrosoftTeams\Message\Action\Submit;

Submit::make('Approve', ['action' => 'approve', 'orderId' => 123])
    ->style('positive')
    ->associatedInputs('Auto'); // Auto | None

use Lex\Notifications\MicrosoftTeams\Message\Action\ShowCard;

ShowCard::make('Show Details',
    AdaptiveCard::make()->body([
        TextBlock::make('Here are the full details…')->wrap(true),
    ])
);

use Lex\Notifications\MicrosoftTeams\Message\Action\ToggleVisibility;

// Toggle by element id
ToggleVisibility::make('Toggle Details', ['detailsContainer']);

// Force a specific state
ToggleVisibility::make('Show Details', [
    ['elementId' => 'detailsContainer', 'isVisible' => true],
    ['elementId' => 'summaryContainer',  'isVisible' => false],
]);

use Lex\Notifications\Notification;
use Lex\Notifications\MicrosoftTeams\Channel\TeamsChannel;
use Lex\Notifications\MicrosoftTeams\Domain\Model\Ability\CanSendToTeams;
use Lex\Notifications\MicrosoftTeams\Message\Action\OpenUrl;
use Lex\Notifications\MicrosoftTeams\Message\AdaptiveCard;
use Lex\Notifications\MicrosoftTeams\Message\Element\Fact;
use Lex\Notifications\MicrosoftTeams\Message\Element\FactSet;
use Lex\Notifications\MicrosoftTeams\Message\Element\TextBlock;
use Lex\Notifications\MicrosoftTeams\Message\TeamsMessage;

class OrderPlacedNotification extends Notification
{
    use CanSendToTeams;

    public function __construct(private readonly Order $order) {}

    public function via(object $notifiable): array
    {
        return [TeamsChannel::CHANNEL];
    }

    public function toTeams(object $notifiable): TeamsMessage
    {
        return TeamsMessage::create()
            ->card(
                AdaptiveCard::make()
                    ->body([
                        TextBlock::make('New Order Received')
                            ->size('Large')
                            ->weight('Bolder')
                            ->color('Accent'),
                        TextBlock::make('Order #' . $this->order->getNumber())
                            ->isSubtle(true)
                            ->spacing('None'),
                        FactSet::make([
                            Fact::make('Customer', $this->order->getCustomerName()),
                            Fact::make('Items',    (string) $this->order->getItemCount()),
                            Fact::make('Total',    $this->order->getFormattedTotal()),
                            Fact::make('Payment',  $this->order->getPaymentMethod()),
                            Fact::make('Shipping', $this->order->getShippingMethod()),
                        ])->spacing('Medium'),
                    ])
                    ->actions([
                        OpenUrl::make('View Order', $this->order->getBackendUrl())
                            ->style('positive'),
                        OpenUrl::make('View Customer', $this->order->getCustomerUrl()),
                    ])
            );
    }
}

class FulfilmentChannel extends AbstractEntity
{
    use Notifiable;
    use HasRouteNotificationForTeams;

    public function routeNotificationForTeams(): string
    {
        return $this->teamsWebhookUrl;
    }
}

$this->notificationDispatcher->send($fulfilmentChannel, new OrderPlacedNotification($order));

use Lex\Notifications\Notification;
use Lex\Notifications\MicrosoftTeams\Channel\TeamsChannel;
use Lex\Notifications\MicrosoftTeams\Domain\Model\Ability\CanSendToTeams;
use Lex\Notifications\MicrosoftTeams\Message\Action\OpenUrl;
use Lex\Notifications\MicrosoftTeams\Message\AdaptiveCard;
use Lex\Notifications\MicrosoftTeams\Message\Element\Fact;
use Lex\Notifications\MicrosoftTeams\Message\Element\FactSet;
use Lex\Notifications\MicrosoftTeams\Message\Element\TextBlock;
use Lex\Notifications\MicrosoftTeams\Message\TeamsMessage;

class ServerAlertNotification extends Notification
{
    use CanSendToTeams;

    public function __construct(
        private readonly string $serverName,
        private readonly string $metric,
        private readonly string $value,
        private readonly string $threshold,
        private readonly string $dashboardUrl,
        private readonly string $webhookUrl,
    ) {}

    public function via(object $notifiable): array
    {
        return [TeamsChannel::CHANNEL];
    }

    public function toTeams(object $notifiable): TeamsMessage
    {
        return TeamsMessage::create()
            ->webhookUrl($this->webhookUrl) // URL embedded directly — no notifiable routing needed
            ->card(
                AdaptiveCard::make()
                    ->body([
                        TextBlock::make('CRITICAL — ' . $this->serverName)
                            ->size('Large')
                            ->weight('Bolder')
                            ->color('Attention'),
                        TextBlock::make('Threshold exceeded. Immediate attention 

// Dispatch from a Scheduler task — no special notifiable needed
$this->notificationDispatcher->send(new \stdClass(), new ServerAlertNotification(
    serverName:   'prod-web-01',
    metric:       'CPU Usage',
    value:        '98%',
    threshold:    '85%',
    dashboardUrl: 'https://grafana.internal/d/servers',
    webhookUrl:   'https://prod.webhook.office.com/webhookb2/...',
));

use Lex\Notifications\Notification;
use Lex\Notifications\MicrosoftTeams\Channel\TeamsChannel;
use Lex\Notifications\MicrosoftTeams\Domain\Model\Ability\CanSendToTeams;
use Lex\Notifications\MicrosoftTeams\Message\Action\OpenUrl;
use Lex\Notifications\MicrosoftTeams\Message\AdaptiveCard;
use Lex\Notifications\MicrosoftTeams\Message\Element\Column;
use Lex\Notifications\MicrosoftTeams\Message\Element\ColumnSet;
use Lex\Notifications\MicrosoftTeams\Message\Element\Fact;
use Lex\Notifications\MicrosoftTeams\Message\Element\FactSet;
use Lex\Notifications\MicrosoftTeams\Message\Element\Image;
use Lex\Notifications\MicrosoftTeams\Message\Element\TextBlock;
use Lex\Notifications\MicrosoftTeams\Message\TeamsMessage;

class UserRegisteredNotification extends Notification
{
    use CanSendToTeams;

    public function __construct(private readonly FrontendUser $user) {}

    public function via(object $notifiable): array
    {
        return [TeamsChannel::CHANNEL];
    }

    public function toTeams(object $notifiable): TeamsMessage
    {
        $avatarUrl = sprintf(
            'https://ui-avatars.com/api/?name=%s&size=128&background=0D3880&color=fff',
            urlencode($this->user->getName()),
        );

        return TeamsMessage::create()
            ->card(
                AdaptiveCard::make()
                    ->body([
                        TextBlock::make('New User Registered')
                            ->size('Large')
                            ->weight('Bolder'),
                        ColumnSet::make([
                            Column::make([
                                Image::make($avatarUrl)
                                    ->style('Person')
                                    ->size('Small'),
                            ])->width('auto'),
                            Column::make([
                                TextBlock::make($this->user->getName())
                                    ->weight('Bolder'),
                                TextBlock::make($this->user->getEmail())
                                    ->isSubtle(true)
                                    ->spacing('None'),
                            ])->width('stretch'),
                        ])->spacing('Medium'),
                        FactSet::make([
                            Fact::make('Username',   $this->user->getUsername()),
                            Fact::make('Registered', (new \DateTimeImmutable())->format('d/m/Y H:i')),
                            Fact::make('User group', $this->user->getUsergroup()->first()?->getTitle() ?? '—'),
                        ]),
                    ])
                    ->actions([
                        OpenUrl::make('Edit user', $this->user->getBackendEditUrl()),
                    ])
            );
    }
}

use Lex\Notifications\Notification;
use Lex\Notifications\MicrosoftTeams\Channel\TeamsChannel;
use Lex\Notifications\MicrosoftTeams\Domain\Model\Ability\CanSendToTeams;
use Lex\Notifications\MicrosoftTeams\Message\Action\OpenUrl;
use Lex\Notifications\MicrosoftTeams\Message\Action\ToggleVisibility;
use Lex\Notifications\MicrosoftTeams\Message\AdaptiveCard;
use Lex\Notifications\MicrosoftTeams\Message\Element\Container;
use Lex\Notifications\MicrosoftTeams\Message\Element\Fact;
use Lex\Notifications\MicrosoftTeams\Message\Element\FactSet;
use Lex\Notifications\MicrosoftTeams\Message\Element\TextBlock;
use Lex\Notifications\MicrosoftTeams\Message\TeamsMessage;

class ContentApprovalRequestNotification extends Notification
{
    use CanSendToTeams;

    public function __construct(
        private readonly PageRecord $page,
        private readonly BackendUser $submitter,
        private readonly string $note,
    ) {}

    public function via(object $notifiable): array
    {
        return [TeamsChannel::CHANNEL];
    }

    public function toTeams(object $notifiable): TeamsMessage
    {
        return TeamsMessage::create()
            ->card(
                AdaptiveCard::make()
                    ->body([
                        TextBlock::make('Content Approval Required')
                            ->size('Large')
                            ->weight('Bolder'),
                        FactSet::make([
                            Fact::make('Page',         $this->page->getTitle()),
                            Fact::make('Submitted by', $this->submitter->getRealName()),
                            Fact::make('URL',          $this->page->getSlug()),
                        ])->spacing('Medium'),
                        Container::make([
                            TextBlock::make('Editorial Note')->weight('Bolder'),
                            TextBlock::make($this->note)->wrap(true)->isSubtle(true),
                        ])
                        ->id('editorialNote')
                        ->isVisible(false)
                        ->style('emphasis')
                        ->spacing('Medium'),
                    ])
                    ->actions([
                        OpenUrl::make('Preview page', $this->page->getFrontendPreviewUrl()),
                        OpenUrl::make('Open in backend', $this->page->getBackendUrl()),
                        ToggleVisibility::make('Show editorial note', ['editorialNote']),
                    ])
            );
    }
}

use Lex\Notifications\Notification;
use Lex\Notifications\NotificationChannel;
use Lex\Notifications\MicrosoftTeams\Channel\TeamsChannel;
use Lex\Notifications\MicrosoftTeams\Domain\Model\Ability\CanSendToTeams;
use Lex\Notifications\MicrosoftTeams\Message\AdaptiveCard;
use Lex\Notifications\MicrosoftTeams\Message\Element\TextBlock;
use Lex\Notifications\MicrosoftTeams\Message\TeamsMessage;
use TYPO3\CMS\Core\Mail\MailMessage;

class DeploymentFinishedNotification extends Notification
{
    use CanSendToTeams;

    public function __construct(
        private readonly string $environment,
        private readonly string $version,
        private readonly bool $success,
    ) {}

    public function via(object $notifiable): array
    {
        return [TeamsChannel::CHANNEL, NotificationChannel::CHANNEL_MAIL];
    }

    public function toTeams(object $notifiable): TeamsMessage
    {
        $status = $this->success ? 'SUCCESS' : 'FAILED';
        $color  = $this->success ? 'Good'    : 'Attention';

        return TeamsMessage::create()
            ->card(
                AdaptiveCard::make()
                    ->body([
                        TextBlock::make("Deploy {$status} — {$this->environment}")
                            ->size('Large')
                            ->weight('Bolder')
                            ->color($color),
                        TextBlock::make("Version {$this->version} deployed to {$this->environment}.")
                            ->wrap(true),
                    ])
            );
    }

    public function toMail(object $notifiable): MailMessage
    {
        return (new MailMessage())
            ->subject("Deploy {$this->environment}: " . ($this->success ? 'SUCCESS' : 'FAILED'))
            ->text("Version {$this->version} was deployed to {$this->environment}.");
    }
}