flarum-msteams-webhook/src/Support/NotificationPayloadFactory.php

194 lines
6.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace SbpJm\FlarumMSTeamsWebhook\Support;
use Flarum\Discussion\Discussion;
use Flarum\Notification\Blueprint\BlueprintInterface;
use Flarum\Post\Post;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\User;
class NotificationPayloadFactory
{
public function __construct(protected SettingsRepositoryInterface $settings)
{
}
/**
* @return array<string,mixed>
*/
/**
* @return array<string,mixed>
*/
public function make(User $recipient, BlueprintInterface $blueprint): array
{
$activityType = trim((string) $this->settings->get('sbp-jm-msteams-webhook.activity_type', 'systemDefault'));
$forumName = trim((string) $this->settings->get('forum_title', 'Flarum')) ?: 'Flarum';
$iconId = trim((string) $this->settings->get('sbp-jm-msteams-webhook.icon_id', ''));
// Diskussionstitel + URL dynamisch aus dem Subject ziehen
// $discussionTitle = $this->resolveDiscussionTitle($blueprint) ?? $forumName;
// $discussionUrl = $this->resolveSubjectUrl($blueprint) ?? 'https://forum.sbp.de';
// $previewSnippet = $this->buildPreviewText($blueprint);
$discussionTitle = 'Backup-Strategie für Forum';
$discussionUrl = 'https://forum.sbp.de/d/34-which-file-extensions-are-allowed-for-uploads/2';
$previewSnippet = 'Bitte prüft, ob wir tägliche Snapshots brauchen.';
$reasonText = 'Neue Antwort in beobachteter Diskussion';
// Freie Actor+Reason-Zeile für systemDefault
$reasonText = match ($blueprint::getType()) {
'newPost' => 'There was a new answer in one of your folloed posts',
'postMentioned' => 'Your post has been mentioned',
'userMentioned' => 'You have been mentioned',
'postLiked' => 'Your post has been liked',
default => 'New sbp forum update',
};
// Teams-App-/Tab-Ziel aus deinem aktuellen Manifest
$teamsManifestAppId = 'd92b1be6-ea92-46b1-bcb0-c08ffdd1a61a';
$teamsEntityId = '8ffe419f-ca44-4627-a4b2-f223da2d07aa';
$discussionTitle = 'Backup-Strategie für Forum';
$discussionUrl = 'https://forum.sbp.de/d/34-which-file-extensions-are-allowed-for-uploads/2';
$subEntityId = 'discussion:34:2';
$contextJson = json_encode([
'subEntityId' => $subEntityId,
], JSON_UNESCAPED_SLASHES);
$teamsDeepLink = sprintf(
'https://teams.microsoft.com/l/entity/%s/%s?tenantId=%s&webUrl=%s&label=%s&context=%s',
rawurlencode('d92b1be6-ea92-46b1-bcb0-c08ffdd1a61a'),
rawurlencode('8ffe419f-ca44-4627-a4b2-f223da2d07aa'),
rawurlencode('e2052793-a0f4-47d8-a3a3-52c926e79df5'),
rawurlencode($discussionUrl),
rawurlencode($discussionTitle),
rawurlencode($contextJson)
);
$payload = [
'topic' => [
'source' => 'text',
'value' => $discussionTitle,
'webUrl' => $teamsDeepLink,
],
'activityType' => $activityType !== '' ? $activityType : 'systemDefault',
'previewText' => [
'content' => mb_substr($previewSnippet, 0, 150),
],
'templateParameters' => [
[
'name' => 'systemDefaultText',
'value' => $reasonText,
],
],
];
if ($iconId !== '') {
$payload['iconId'] = $iconId;
}
if (($payload['activityType'] ?? 'systemDefault') !== 'systemDefault') {
$payload['templateParameters'] = [
[
'name' => 'notificationText',
'value' => mb_substr($previewSnippet, 0, 150),
],
];
}
return $payload;
}
protected function buildPreviewText(BlueprintInterface $blueprint): string
{
if ($blueprint::getType() === 'teamsTest') {
return 'Flarum ➜ Teams Test erfolgreich angestoßen';
}
$actor = $blueprint->getFromUser();
$actorName = $actor instanceof User ? (string) ($actor->display_name ?? $actor->username ?? 'Jemand') : 'Jemand';
$type = $blueprint::getType();
$subject = $blueprint->getSubject();
$subjectTitle = null;
if ($subject instanceof Discussion) {
$subjectTitle = (string) $subject->title;
} elseif ($subject instanceof Post && $subject->discussion) {
$subjectTitle = (string) $subject->discussion->title;
}
$text = match ($type) {
'newPost' => sprintf('%s hat in einer beobachteten Diskussion geantwortet', $actorName),
'postMentioned' => sprintf('%s hat dich in einem Beitrag erwähnt', $actorName),
'userMentioned' => sprintf('%s hat dich erwähnt', $actorName),
'postLiked' => sprintf('%s hat einen Beitrag von dir geliked', $actorName),
'discussionRenamed' => sprintf('%s hat eine Diskussion umbenannt', $actorName),
default => sprintf('%s: neue Flarum-Benachrichtigung (%s)', $actorName, $type),
};
if ($subjectTitle) {
$text .= ' ' . $subjectTitle;
}
return mb_substr($text, 0, 150);
}
protected function resolveDiscussionTitle(BlueprintInterface $blueprint): ?string
{
$subject = $blueprint->getSubject();
if ($subject instanceof Discussion) {
return (string) $subject->title;
}
if ($subject instanceof Post && $subject->discussion) {
return (string) $subject->discussion->title;
}
return null;
}
protected function resolveSubjectUrl(BlueprintInterface $blueprint): ?string
{
$baseUrl = rtrim((string) $this->settings->get('sbp-jm-msteams-webhook.forum_base_url', ''), '/');
if ($baseUrl === '') {
return null;
}
$subject = $blueprint->getSubject();
if ($subject instanceof Discussion) {
return sprintf('%s/d/%s', $baseUrl, $subject->id);
}
if ($subject instanceof Post) {
$discussionId = $subject->discussion_id;
$postNumber = $subject->number;
if ($discussionId !== null && $postNumber !== null) {
return sprintf('%s/d/%s/%s', $baseUrl, $discussionId, $postNumber);
}
}
return $baseUrl;
}
protected function buildChainId(User $recipient, BlueprintInterface $blueprint): int
{
$subject = $blueprint->getSubject();
$subjectId = is_object($subject) && isset($subject->id) ? (string) $subject->id : '0';
return abs(crc32(implode('|', [
(string) $recipient->id,
$blueprint::getType(),
$subjectId,
])));
}
}