diff --git a/plugins/ActivityPub/ActivityPubPlugin.php b/plugins/ActivityPub/ActivityPubPlugin.php index 96e26a7ac2..c27938be27 100644 --- a/plugins/ActivityPub/ActivityPubPlugin.php +++ b/plugins/ActivityPub/ActivityPubPlugin.php @@ -97,9 +97,17 @@ class ActivityPubPlugin extends Plugin // Look for a local notice (unfortunately GNU social doesn't // provide this functionality natively) try { - $candidate = Notice::getByID((int)substr($url, (strlen(Activitypub_notice::note_uri(0))-1))); + $id = (int)substr($url, (strlen(Activitypub_notice::note_uri(0))-1)); + if ($id <= 0) { + // Substr failed (url starts with 'tag:') + // Avoid duplication + $id = (int)basename($url); + } + $candidate = Notice::getByID($id); if (Activitypub_notice::note_uri($candidate->getID()) === $url) { // Sanity check return $candidate; + } elseif ($candidate->getLocalUrl() === $url) { // Sanity check (url starts with 'tag:') + return $candidate; } else { common_debug('ActivityPubPlugin Notice Grabber: '.$candidate->getUrl(). ' is different of '.$url); } @@ -127,6 +135,12 @@ class ActivityPubPlugin extends Plugin throw new Exception("A notice can't be created without an actor."); } if (parse_url($acclaimed_actor_profile->getUri(), PHP_URL_HOST) == parse_url($object['id'], PHP_URL_HOST)) { + try { + // Keep conversation tree + return Notice::getByUri($object['id']); + } catch (Exception $e) { + // NOOP + } return Activitypub_notice::create_notice($object, $acclaimed_actor_profile); } else { throw new Exception("The acclaimed actor didn't create this note."); diff --git a/plugins/ActivityPub/lib/models/Activitypub_notice.php b/plugins/ActivityPub/lib/models/Activitypub_notice.php index 908b804ae0..14b4c3eae2 100644 --- a/plugins/ActivityPub/lib/models/Activitypub_notice.php +++ b/plugins/ActivityPub/lib/models/Activitypub_notice.php @@ -347,8 +347,15 @@ class Activitypub_notice public static function getUri(Notice $notice): string { if ($notice->isLocal()) { - return common_local_url('apNotice', ['id' => $notice->getID()]); + // 'common_local_url' returns '/activity/xxx' (has problem for conversation tree) + // 'note_url' return '/object/note/xxx' + return self::note_uri($notice->getID()); } else { + // use 'uri' instead of 'url' (avoid duplication) + $uri = $notice->getUri(); + if (common_valid_http_url($uri)) { + return $uri; + } return $notice->getUrl(); } }