Bluesky, Farcaster, Lemmy, Mastodon, Nostr, Threads providers with Core\Plug\Web3 namespace alignment. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
139 lines
4.2 KiB
PHP
139 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Core\Plug\Web3\Lemmy;
|
|
|
|
use Core\Plug\Concern\BuildsResponse;
|
|
use Core\Plug\Concern\ManagesTokens;
|
|
use Core\Plug\Concern\UsesHttp;
|
|
use Core\Plug\Contract\Commentable;
|
|
use Core\Plug\Response;
|
|
|
|
/**
|
|
* Lemmy comment publishing.
|
|
*/
|
|
class Comment implements Commentable
|
|
{
|
|
use BuildsResponse;
|
|
use ManagesTokens;
|
|
use UsesHttp;
|
|
|
|
private string $instanceUrl = '';
|
|
|
|
/**
|
|
* Set the instance URL.
|
|
*/
|
|
public function forInstance(string $instanceUrl): self
|
|
{
|
|
$this->instanceUrl = rtrim($instanceUrl, '/');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Create a comment on a post.
|
|
*
|
|
* @param string $text Comment content (markdown)
|
|
* @param string $postId Post ID to comment on
|
|
* @param array $params Optional: parent_id for replies, language_id
|
|
*/
|
|
public function comment(string $text, string $postId, array $params = []): Response
|
|
{
|
|
if (! $this->instanceUrl) {
|
|
return $this->error('Instance URL is required');
|
|
}
|
|
|
|
$commentData = [
|
|
'content' => $text,
|
|
'post_id' => (int) $postId,
|
|
];
|
|
|
|
// Handle reply to existing comment
|
|
if (isset($params['parent_id'])) {
|
|
$commentData['parent_id'] = (int) $params['parent_id'];
|
|
}
|
|
|
|
// Language
|
|
if (isset($params['language_id'])) {
|
|
$commentData['language_id'] = $params['language_id'];
|
|
}
|
|
|
|
$response = $this->http()
|
|
->withHeaders(['Authorization' => 'Bearer '.$this->accessToken()])
|
|
->post($this->instanceUrl.'/api/v3/comment', $commentData);
|
|
|
|
return $this->fromHttp($response, fn ($data) => [
|
|
'id' => $data['comment_view']['comment']['id'],
|
|
'content' => $data['comment_view']['comment']['content'],
|
|
'post_id' => $data['comment_view']['comment']['post_id'],
|
|
'ap_id' => $data['comment_view']['comment']['ap_id'],
|
|
'published' => $data['comment_view']['comment']['published'],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get comments for a post.
|
|
*/
|
|
public function getComments(int $postId, array $params = []): Response
|
|
{
|
|
if (! $this->instanceUrl) {
|
|
return $this->error('Instance URL is required');
|
|
}
|
|
|
|
$response = $this->http()
|
|
->withHeaders($this->authHeaders())
|
|
->get($this->instanceUrl.'/api/v3/comment/list', [
|
|
'post_id' => $postId,
|
|
'sort' => $params['sort'] ?? 'Hot', // Hot, Top, New, Old
|
|
'limit' => $params['limit'] ?? 50,
|
|
'page' => $params['page'] ?? 1,
|
|
'max_depth' => $params['max_depth'] ?? 8,
|
|
]);
|
|
|
|
return $this->fromHttp($response, fn ($data) => [
|
|
'comments' => array_map(fn ($item) => [
|
|
'id' => $item['comment']['id'],
|
|
'content' => $item['comment']['content'],
|
|
'path' => $item['comment']['path'],
|
|
'author' => $item['creator']['name'],
|
|
'upvotes' => $item['counts']['upvotes'] ?? 0,
|
|
'downvotes' => $item['counts']['downvotes'] ?? 0,
|
|
'published' => $item['comment']['published'],
|
|
], $data['comments'] ?? []),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Edit a comment.
|
|
*/
|
|
public function edit(int $commentId, string $content): Response
|
|
{
|
|
if (! $this->instanceUrl) {
|
|
return $this->error('Instance URL is required');
|
|
}
|
|
|
|
$response = $this->http()
|
|
->withHeaders(['Authorization' => 'Bearer '.$this->accessToken()])
|
|
->put($this->instanceUrl.'/api/v3/comment', [
|
|
'comment_id' => $commentId,
|
|
'content' => $content,
|
|
]);
|
|
|
|
return $this->fromHttp($response, fn ($data) => [
|
|
'id' => $data['comment_view']['comment']['id'],
|
|
'content' => $data['comment_view']['comment']['content'],
|
|
'updated' => $data['comment_view']['comment']['updated'] ?? null,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get auth headers if token is available.
|
|
*/
|
|
protected function authHeaders(): array
|
|
{
|
|
$token = $this->accessToken();
|
|
|
|
return $token ? ['Authorization' => 'Bearer '.$token] : [];
|
|
}
|
|
}
|