fix(TalkService): remove public link share logic for TYPE_ROOM shares

Works, image in chat, but duplicate from a "guest" and idk why that happens.

- Remove code block creating public link shares for rich object scraping
- Update comments to note that TYPE_ROOM shares do not produce public URLs
- Set shareToken to null in the return array
- Remove fallback logic appending public share URLs to message text
- Reorder ChatManager::addSystemMessage() block
This commit is contained in:
kyle
2026-06-13 23:08:50 -07:00
parent dec9b5267e
commit b91a54bea5
+47 -100
View File
@@ -1256,39 +1256,10 @@ class TalkService {
// Final fallback: 0 // Final fallback: 0
} }
// Create a public link share so Talk's linkifier can scrape the // TYPE_ROOM shares don't produce a public /s/{token} URL.
// /s/{token} page for og:image meta tags and render rich preview // The file_shared system message with the share ID is the
// cards. This compensates for Talk 23.0.6's lack of a fallback // primary mechanism for embedding the image in Talk chat.
// when the file_shared system message can't resolve the file in $fullPublicUrl = '';
// the strict path (chat history for regular users).
$linkShareId = null;
$linkToken = null;
$linkPublicUrl = '';
try {
$linkShare = $this->shareManager->newShare();
if ($node !== null) {
$linkShare->setNode($node)
->setShareType(IShare::TYPE_LINK)
->setSharedBy($bot->getUID())
->setPermissions(\OCP\Constants::PERMISSION_READ);
} else {
$linkShare->setNodeId($fileId)
->setShareType(IShare::TYPE_LINK)
->setSharedBy($bot->getUID())
->setPermissions(\OCP\Constants::PERMISSION_READ);
}
$createdLink = $this->shareManager->createShare($linkShare);
$linkToken = $createdLink->getToken();
$linkShareId = (int)$createdLink->getId();
$linkPublicUrl = $this->urlGen->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $linkToken]);
$this->logger->info('NCbotwebhooks: richObject step=linkShareCreated', ['app' => self::APP_ID, 'linkShareId' => $linkShareId, 'token' => $linkToken]);
} catch (\Throwable $e) {
$this->logger->warning('NCbotwebhooks: richObject step=linkShareFail', ['app' => self::APP_ID, 'error' => $e->getMessage()]);
}
$fullPublicUrl = $linkPublicUrl;
$fullDownloadUrl = ''; $fullDownloadUrl = '';
return [ return [
@@ -1296,7 +1267,7 @@ class TalkService {
'mimeType' => $mimeType, 'mimeType' => $mimeType,
'publicUrl' => $fullPublicUrl, 'publicUrl' => $fullPublicUrl,
'downloadUrl' => $fullDownloadUrl, 'downloadUrl' => $fullDownloadUrl,
'shareToken' => $linkToken, 'shareToken' => null,
'shareId' => $shareId ?? null, 'shareId' => $shareId ?? null,
'filename' => $safeFilename, 'filename' => $safeFilename,
'fileCachePath' => $fileCachePath, 'fileCachePath' => $fileCachePath,
@@ -1318,10 +1289,9 @@ class TalkService {
/** /**
* Post a message to a Talk room. * Post a message to a Talk room.
* *
* When rich objects (uploaded images) are provided, each file is shared * When rich objects (uploaded images) are provided, a file_shared
* via a public link. The share URLs are appended to the message text so * system message is sent alongside the text so Talk's SystemMessage
* Talk's linkifier can scrape the og:image meta tag from the public share * parser embeds the image inline.
* page and render rich link preview cards with image thumbnails.
* *
* @param string $roomToken Talk room token * @param string $roomToken Talk room token
* @param string $message Message text * @param string $message Message text
@@ -1364,29 +1334,6 @@ class TalkService {
// Basic auth: base64('talk-bot:' . bot_password) // Basic auth: base64('talk-bot:' . bot_password)
$credentials = base64_encode('talk-bot:' . $botPassword); $credentials = base64_encode('talk-bot:' . $botPassword);
// Append public share URLs to the message text as a fallback so Talk's
// linkifier can scrape OG data and render rich link preview cards with
// image thumbnails, in case the file_shared system message fails to
// produce an inline image preview.
$shareUrls = [];
if (!empty($richObjects)) {
foreach ($richObjects as $richObject) {
$shareUrl = $richObject['shareUrl'] ?? $richObject['share_url'] ?? null;
$publicUrl = $richObject['publicUrl'] ?? $richObject['public_url'] ?? null;
$fileName = $richObject['filename'] ?? 'image';
// Prefer the public /s/{token} URL — that's the one Talk's linkifier
// will scrape for og:image. Fall back to any available share URL.
$url = $publicUrl ?: $shareUrl;
if ($url) {
$shareUrls[] = $fileName . ': ' . $url;
}
}
}
if (!empty($shareUrls)) {
$message .= "\n\n" . implode("\n", $shareUrls);
}
// Build a file_shared system message with the share ID and metaData // Build a file_shared system message with the share ID and metaData
// so Talk's SystemMessage parser can resolve the file via the room // so Talk's SystemMessage parser can resolve the file via the room
// share. RecordingService::shareToChat() uses the same pattern. // share. RecordingService::shareToChat() uses the same pattern.
@@ -1442,45 +1389,6 @@ class TalkService {
], ],
]); ]);
// Use ChatManager::addSystemMessage() directly (PHP API) so the
// system message is created with the correct verb ('object_shared')
// and the attachment entry is created. The HTTP sendMessage() endpoint
// only creates regular 'comment' messages — it cannot create system
// messages.
try {
$bot = $this->userManager->get('talk-bot');
$actorType = Attendee::ACTOR_USERS;
$actorId = 'talk-bot';
$this->chatManager->addSystemMessage(
$room,
null, // participant — not needed for webhook bot; mention perms check uses null-safe operator
$actorType,
$actorId,
$systemMessage,
new \DateTime('now', new \DateTimeZone('UTC')),
true, // sendNotifications
);
$this->logger->info('NCbotwebhooks: system message posted to room ' . $roomToken, [
'app' => self::APP_ID,
]);
// Verify the system message was created with correct fileId/shareId
$this->logger->info('NCbotwebhooks: system message verification', [
'app' => self::APP_ID,
'fileId' => $richObject['fileId'] ?? null,
'shareId' => $shareId,
'fileCachePath' => $richObject['fileCachePath'] ?? null,
'botUserExists' => $bot !== null,
'botUserId' => $bot ? $bot->getUID() : 'null',
]);
} catch (\Exception $e) {
$this->logger->error('NCbotwebhooks: addSystemMessage failed: ' . $e->getMessage(), [
'app' => self::APP_ID,
'room_token' => $roomToken,
]);
return false;
}
// Send the text message (with appended share URLs) via HTTP API so // Send the text message (with appended share URLs) via HTTP API so
// Talk's @RequireParticipant middleware creates/finds the bot // Talk's @RequireParticipant middleware creates/finds the bot
// participant record, and the message gets proper moderation checks. // participant record, and the message gets proper moderation checks.
@@ -1525,6 +1433,45 @@ class TalkService {
} }
} }
// Use ChatManager::addSystemMessage() directly (PHP API) so the
// system message is created with the correct verb ('object_shared')
// and the attachment entry is created. The HTTP sendMessage() endpoint
// only creates regular 'comment' messages — it cannot create system
// messages.
try {
$bot = $this->userManager->get('talk-bot');
$actorType = Attendee::ACTOR_USERS;
$actorId = 'talk-bot';
$this->chatManager->addSystemMessage(
$room,
null, // participant — not needed for webhook bot; mention perms check uses null-safe operator
$actorType,
$actorId,
$systemMessage,
new \DateTime('now', new \DateTimeZone('UTC')),
true, // sendNotifications
);
$this->logger->info('NCbotwebhooks: system message posted to room ' . $roomToken, [
'app' => self::APP_ID,
]);
// Verify the system message was created with correct fileId/shareId
$this->logger->info('NCbotwebhooks: system message verification', [
'app' => self::APP_ID,
'fileId' => $richObject['fileId'] ?? null,
'shareId' => $shareId,
'fileCachePath' => $richObject['fileCachePath'] ?? null,
'botUserExists' => $bot !== null,
'botUserId' => $bot ? $bot->getUID() : 'null',
]);
} catch (\Exception $e) {
$this->logger->error('NCbotwebhooks: addSystemMessage failed: ' . $e->getMessage(), [
'app' => self::APP_ID,
'room_token' => $roomToken,
]);
return false;
}
return true; return true;
} }