Dart Flutter 应用程序中使用 AT Protocol API 和 Bluesky API 插件bluesky的使用

Flutter 应用程序中使用 AT Protocol API 和 Bluesky API 插件bluesky的使用

1. 概述 🌎

bluesky 是一个用于在 Dart 和 Flutter 应用程序中使用 AT Protocol API 和 Bluesky API 的最强大库。该库跨平台,并且已经在许多应用程序中使用。更多详情请参见 官方展示

1.1. 功能特性 ⭐

  • 零依赖
  • ✅ 支持强大的内置重试机制,使用 指数退避和抖动
  • ✅ 支持所有 app.bsky.* 和 chat.bsky.* 端点
  • ✅ 文档齐全且经过充分测试
  • ✅ 支持强大的 Firehose API
  • ✅ 支持强大的审核 API
  • ✅ 支持 OAuth DPoP
  • ✅ 100% 空安全
  • ✅ 内置 atproto 功能

1.2. 入门指南 💪

安装

pubspec.yaml 文件中添加以下依赖:

dependencies:
  bluesky: ^0.1.0

然后运行 flutter pub getdart pub get

导入

在 Dart 文件中导入 bluesky 包:

import 'package:bluesky/bluesky.dart';

实例化 Bluesky

final bsky = Bluesky.fromSession(
  session,
  service: 'SERVICE_NAME',
  relayService: 'STREAM_SERVICE_NAME',
  retryConfig: RetryConfig(
    maxAttempts: 5,
    jitter: Jitter(minInSeconds: 2, maxInSeconds: 5),
    onExecute: (event) => print(
      'Retry after ${event.intervalInSeconds} seconds... [${event.retryCount} times]',
    ),
  ),
  timeout: Duration(seconds: 20),
);

1.3. 支持的端点 👀

1.4. 更多提示 🏄

1.5. 贡献 🏆

如果您想为 bluesky 做贡献,请创建一个 issue 或提交一个 Pull Request。您可以参考以下资源:

或者您可以在 讨论区 发起讨论。

1.6. 支持 ❤️

最简单的方式是给项目一个星标,您可以在 GitHubPub.dev 上进行操作。

您也可以通过成为 GitHub 赞助者来支持这个项目:

您还可以在您的仓库中使用以下徽章来显示您的应用是使用 bluesky 构建的:

Powered by bluesky Powered by bluesky Powered by bluesky


### 1.7. 许可证 🔑

`bluesky` 的所有资源均在 [BSD-3](https://github.com/myConsciousness/atproto.dart/blob/main/LICENSE) 许可证下提供。

### 1.8. 更多信息 🧐

`bluesky` 由 [Shinya Kato (@myConsciousness)](https://github.com/myConsciousness) 设计和实现。

- [创作者简介](https://github.com/myConsciousness)
- [许可证](https://github.com/myConsciousness/atproto.dart/blob/main/LICENSE)
- [API 文档](https://pub.dev/documentation/bluesky/latest/bluesky/bluesky-library.html)
- [发布说明](https://github.com/myConsciousness/atproto.dart/releases)
- [Bug 报告](https://github.com/myConsciousness/atproto.dart/issues)

## 示例代码

以下是一个简单的示例代码,展示了如何使用 `bluesky` 插件:

```dart
import 'dart:io';

import 'package:atproto_core/atproto_core.dart';
import 'package:atproto_core/atproto_oauth.dart';
import 'package:bluesky/app_bsky_embed_video.dart';
import 'package:bluesky/atproto.dart';
import 'package:bluesky/bluesky.dart';
import 'package:bluesky/bluesky_chat.dart';
import 'package:bluesky/chat_bsky_convo_defs.dart';
import 'package:bluesky/moderation.dart';

/// https://atprotodart.com/docs/packages/bluesky
Future<void> main() async {
  try {
    //! 首先需要与 ATP 服务器建立会话。
    final session = await _session;

    final bsky = Bluesky.fromSession(
      session,
      //! 默认值为 `bsky.social`,或根据会话动态解析
      service: 'SERVICE_NAME',

      //! 默认值为 `bsky.network`
      relayService: 'STREAM_SERVICE_NAME',

      //! 当与 API 通信时发生服务器错误或网络错误时,可以自动重试
      retryConfig: RetryConfig(
        maxAttempts: 5,
        jitter: Jitter(
          minInSeconds: 2,
          maxInSeconds: 5,
        ),
        onExecute: (event) => print(
          'Retry after ${event.intervalInSeconds} seconds...'
          '[${event.retryCount} times]',
        ),
      ),

      //! 默认超时时间为 30 秒。
      timeout: Duration(seconds: 20),
    );

    //! 聊天功能
    final chat = BlueskyChat.fromSession(session);
    final convos = await chat.convo.listConvos();

    for (final convo in convos.data.convos) {
      await chat.convo.sendMessage(
        convoId: convo.id,
        message: MessageInput(text: 'Hello?'),
      );
    }

    //! 审核功能
    final preferences = await bsky.actor.getPreferences();
    final moderationPrefs = preferences.data.getModerationPrefs();
    final labelDefs = await bsky.labeler.getLabelDefinitions(moderationPrefs);

    final moderationOpts = ModerationOpts(
      userDid: bsky.session!.did,
      prefs: moderationPrefs,
      labelDefs: labelDefs,
    );

    //! 获取首页时间线
    final feeds = await bsky.feed.getTimeline(
      headers: getLabelerHeaders(moderationPrefs),
    );

    for (final feed in feeds.data.feed) {
      final decision = moderatePost(
        ModerationSubjectPost.postView(data: feed.post),
        moderationOpts,
      );

      if (decision.getUI(ModerationBehaviorContext.contentView).alert) {
        // 提醒!
      }
    }

    print(feeds);

    //! 上传视频
    final uploadedVideo = await bsky.video.uploadVideo(
      File('./cool_video.mov').readAsBytesSync(),
    );

    //! 发布酷炫内容
    final createdRecord = await bsky.feed.post(
      text: 'Hello, Bluesky!',
      embed: Embed.video(
        data: EmbedVideo(
          video: uploadedVideo.data.blob!,
        ),
      ),
    );

    print(createdRecord);

    //! 删除它
    await bsky.atproto.repo.deleteRecord(
      uri: createdRecord.data.uri,
    );

    //! 可以轻松使用 Stream API
    final subscription = await bsky.atproto.sync.subscribeRepos();

    subscription.data.stream.listen((event) {
      event.when(
        //! 可以非常容易地处理 commit 事件
        //! 使用 RepoCommitAdaptor。
        commit: RepoCommitAdaptor(
          //! 创建事件。
          onCreatePost: (data) => data.record,
          onCreateLike: print,

          //! 更新事件。
          onUpdateProfile: print,

          //! 删除事件。
          onDeletePost: print,
        ).execute,
        identity: print,
        account: print,
        handle: print,
        migrate: print,
        tombstone: print,
        info: print,
        unknown: print,
      );
    });
  } on UnauthorizedException catch (e) {
    print(e);
  } on XRPCException catch (e) {
    print(e);
  }
}

Future<Session> get _session async {
  final session = await createSession(
    service: 'SERVICE_NAME', //! 默认值为 `bsky.social`
    identifier: 'YOUR_HANDLE_OR_EMAIL', //! 如 `shinyakato.bsky.social`
    password: 'YOUR_PASSWORD',
  );

  return session.data;
}

/// Flutter 应用的 OAuth 流程:
// ignore: unused_element
Future<OAuthSession> get _oAuthSession async {
  // 使用您的客户端元数据
  final metadata = await getClientMetadata(
    'https://atprotodart.com/oauth/bluesky/atprotodart/client-metadata.json',
  );

  final oauth = OAuthClient(metadata);

  final (authUrl, ctx) = await oauth.authorize('shinyakato.dev');
  print(authUrl);
  print(ctx);

  // 让用户访问 URL
  // final callback = await FlutterWebAuth2.authenticate(
  //   url: authorizationUrl,
  //   callbackUrlScheme: 'https',
  // );

  final session = await oauth.callback(
    // 回调 URL
    'https://atprotodart.com/oauth/bluesky/auth.html?iss=xxxx&state=xxxxxxx&code=xxxxxxx',
    ctx,
  );
  print(session.accessToken);
  print(session.$dPoPNonce); // 每次请求都会更新
  print(session.$publicKey);
  print(session.$privateKey);

  // 您可以从存储的密钥中恢复 OAuthSession
  final restoredSession = restoreOAuthSession(
    accessToken: session.accessToken,
    refreshToken: session.refreshToken,
    publicKey: session.$publicKey,
    privateKey: session.$privateKey,
  );

  // 如果您想刷新会话
  // final refreshed = await oauth.refresh(bsky.oAuthSession!);

  return restoredSession;
}

希望这些信息对您有所帮助!如果有任何问题或需要进一步的帮助,请随时提问。


更多关于Dart Flutter 应用程序中使用 AT Protocol API 和 Bluesky API 插件bluesky的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

回到顶部