diff --git a/src/Support/NotificationPayloadFactory.php b/src/Support/NotificationPayloadFactory.php index fba59e3..71bfcbc 100644 --- a/src/Support/NotificationPayloadFactory.php +++ b/src/Support/NotificationPayloadFactory.php @@ -37,8 +37,14 @@ class NotificationPayloadFactory $previewSnippet = $this->buildPreviewText($blueprint); $reasonText = $this->buildReasonTextEn($blueprint); + $landingPageUrl = $this->buildLandingPageUrl($blueprint); - $teamsTabLink = $this->buildTeamsTabLink($landingPageUrl); + $subjectUrl = $this->resolveSubjectUrl($blueprint); + + $teamsTabLink = $this->buildTeamsTabLink( + $landingPageUrl, + $subjectUrl + ); return [ 'topic' => [ @@ -91,25 +97,53 @@ class NotificationPayloadFactory /** * Build a Teams deep link to the personal app tab. */ - protected function buildTeamsTabLink(string $webUrl): string - { - $teamsAppId = trim((string) $this->settings->get( - 'sbp-jm-msteams-webhook.teams_app_id', - self::DEFAULT_TEAMS_APP_ID - )); +/** + * Build a Teams deep link to the personal app tab. + * + * The static landing page is supplied as webUrl. The exact Flarum + * discussion or post URL is passed as subEntityId and is exposed by + * TeamsJS v2 as context.page.subPageId. + */ + protected function buildTeamsTabLink( + string $webUrl, + ?string $subjectUrl + ): string { + $teamsAppId = trim( + (string) $this->settings->get( + 'sbp-jm-msteams-webhook.teams_app_id', + self::DEFAULT_TEAMS_APP_ID + ) + ); - if ($teamsAppId === '') { - $teamsAppId = self::DEFAULT_TEAMS_APP_ID; + if ($teamsAppId === '') { + $teamsAppId = self::DEFAULT_TEAMS_APP_ID; + } + + $query = [ + 'webUrl' => $webUrl, + ]; + + if ($subjectUrl !== null) { + $query['context'] = json_encode( + [ + 'subEntityId' => $subjectUrl, + ], + JSON_UNESCAPED_SLASHES + | JSON_THROW_ON_ERROR + ); + } + return sprintf( + 'https://teams.microsoft.com/l/entity/%s/%s?%s', + rawurlencode($teamsAppId), + rawurlencode(self::TEAMS_ENTITY_ID), + http_build_query( + $query, + '', + '&', + PHP_QUERY_RFC3986 + ) + ); } - - return sprintf( - 'https://teams.microsoft.com/l/entity/%s/%s?webUrl=%s', - rawurlencode($teamsAppId), - rawurlencode(self::TEAMS_ENTITY_ID), - rawurlencode($webUrl) - ); - } - /** * Resolve and validate the configured public forum base URL. */ @@ -157,7 +191,6 @@ class NotificationPayloadFactory return null; } - /** * Resolve the URL to the discussion or exact post. */