rikudou/lemmy-api

使用PHP与Lemmy API进行通信

v0.8.0 2024-08-23 15:11 UTC

README

Lemmy现在非常流行!此包允许您使用PHP与Lemmy进行通信,这为编写机器人打开了巨大的可能性!

所有方法都是完全类型化的,因此您的IDE应该会帮您很多忙。

请注意,这是一个alpha版本,尽管一切应该都能正常工作,但随着我找到更好的方法名和/或位置,公共API可能会发生变化。

安装

需要PHP 8.2。

composer require rikudou/lemmy-api

您还需要安装兼容的PSR http客户端PSR http请求工厂

composer require rikudou/lemmy-api guzzlehttp/guzzle

composer require rikudou/lemmy-api symfony/http-client nyholm/psr7

或您喜欢的任何其他实现。

使用方法

<?php

use Rikudou\LemmyApi\DefaultLemmyApi;
use Rikudou\LemmyApi\Enum\LemmyApiVersion;
use Symfony\Component\HttpClient\Psr18Client;
use Nyholm\Psr7\Factory\Psr17Factory;
use Rikudou\LemmyApi\Enum\Language;
use Rikudou\LemmyApi\Exception\LemmyApiException;

$api = new DefaultLemmyApi(
    instanceUrl: 'https://my-lemmy-instance.world', 
    version: LemmyApiVersion::Version3, // this is currently the only supported version
    httpClient: new Psr18Client(), // assuming you use Symfony, otherwise provide any other implementation
    requestFactory: new Psr17Factory(), // assuming you use Nyholm, otherwise provide any other implementation,
);

// before calling anything else, you must login

$response = $api->login('my_username_or_email', 'myPassword');

// now you can call any other methods, you don't even have to store the $response result, you are logged in automatically

try {
    $community = $api->community()->get('some_cool_community');
    $result = $api->post()->create($community, 'Post Name', body: 'Some content', language: Language::English);
} catch (LemmyApiException $e) {
    // todo handle exception - all exceptions implement the LemmyApiException interface
}

非严格模式

默认情况下,库在严格模式下工作 - 当Lemmy在响应中返回库不期望的属性时,它会抛出异常。当库没有更新以与最新版本兼容且Lemmy在响应中添加了新参数时,可能会发生这种情况。

为了减轻这种情况,您可以通过提供参数来切换到非严格模式

<?php

use Rikudou\LemmyApi\DefaultLemmyApi;
use Rikudou\LemmyApi\Enum\LemmyApiVersion;
use Symfony\Component\HttpClient\Psr18Client;
use Nyholm\Psr7\Factory\Psr17Factory;
use Rikudou\LemmyApi\Enum\Language;
use Rikudou\LemmyApi\Exception\LemmyApiException;

$api = new DefaultLemmyApi(
    instanceUrl: 'https://my-lemmy-instance.world', 
    version: LemmyApiVersion::Version3,
    httpClient: new Psr18Client(),
    requestFactory: new Psr17Factory(),
    strictDeserialization: false, // here you disable the strict mode
);

目前,最新完全支持的版本是0.19.3,如果您使用此库连接到较新版本,关闭严格模式可能是个明智的选择。

注意事项

有许多api方法,其中大多数在上游没有文档,所以我尽力猜测它们的作用,并尝试将它们分类到不同的类中。我不太确定我是否完全正确地做到了这一点。

由于同样的原因,列出它们并提供建议也会很困难。这可能会花费我比编写代码更多的时间。如果有人愿意承担这项任务,我将非常乐意接受带有文档的PR!

为了至少让您开始,请查看各种接口以查看方法和参数的名称

目前,即使是无需登录用户即可调用的API请求,在此包中也要求登录,这意味着此包完全不允许匿名访问。将来会考虑这个问题。

目前没有测试,我计划将来进行测试,但现在一段时间内不想看到任何与Lemmy API相关的内容。

示例

一个非常简单的“提醒我”机器人

<?php

use Rikudou\LemmyApi\Enum\Language;
use Rikudou\LemmyApi\Exception\LemmyApiException;
use Rikudou\LemmyApi\LemmyApi;

final readonly class RemindMeBot
{
    public function __construct(
        private LemmyApi $api,
        // how long to sleep between each loop
        private int $sleepFor,
        private string $username,
        #[SensitiveParameter] private string $password,
    ) {
    }

    public function loop(): void
    {
        $this->login();
        while (true) {
            try {
                $unreadMentions = $this->api->currentUser()->getMentions(
                    unreadOnly: true,
                );

                foreach ($unreadMentions as $mention) {
                    $author = $mention->creator->id;
                    $message = $mention->comment->content;
                    $dateTime = $this->getDateFromMessage($message);

                    $this->storeReminderInDatabase($author, $dateTime);
                    $this->api->currentUser()->markMentionAsRead($mention->personMention);

                    $this->api->comment()->create(
                        post: $mention->post,
                        content: "Sure, I'll let you know!",
                        language: Language::English,
                        parent: $mention->comment,
                    );
                }
            } catch (LemmyApiException $e) {
                $this->logException($e);
            }

            sleep($this->sleepFor);
        }
    }

    private function login(): void
    {
        $this->api->login($this->username, $this->password);
    }

    private function getDateFromMessage(string $message): DateTimeInterface
    {
        // todo implement this yourself
    }

    private function storeReminderInDatabase(int $userId, DateTimeInterface $dateTime): void
    {
        // todo implement this yourself
    }

    private function logException(LemmyApiException $e): void
    {
        // todo implement this yourself
    }
}