Flutter Discord API集成插件discord_api的使用

发布于 1周前 作者 h691938207 来自 Flutter

Flutter Discord API 集成插件 discord_api 的使用

Discord API

Dart Pub style: lint

这是一个用纯 Dart 编写的包,用于通过 OAuth2 连接到 Discord。

所有端点和对象都是根据 Discord API 参考文档 实现的。

开始使用

注意:此包仍处于早期阶段。虽然所有模型都已实现,但尚未完全测试,并且并非所有端点都已实现。如果您添加了特定端点的支持,请不要犹豫提交合并请求!

注意:此版本尚未完全测试。未来的版本将只在当前可用的端点完全测试后发布。您可以随时在 GitHub issues 页面 提出建议,说明哪些端点应优先添加,以满足您的需求。

要使用此包,您需要在 Discord 开发者控制台 注册一个应用程序,以获取客户端 ID 和客户端密钥。

注册完应用程序后,您需要从该包中实例化 DiscordClient 类,传入您的 clientIdclientSecretredirectUri

您还需要传递一个 DiscordHttpClient 给它。您可以自行实现,或者使用提供的 DiscordDioProvider。(请注意,此类将在以后移到自己的包中,以移除此包对 dio 的依赖)

final _discordClient = DiscordClient(
  clientId: clientId,
  clientSecret: clientSecret,
  redirectUri: redirectUri,
  discordHttpClient: DiscordDioProvider(clientId: clientId, clientSecret: clientSecret),
);

初始化客户端后,使用端点包装器之前的最后一步是管理与 Discord 应用程序的第一个连接,并初始化您将收到的令牌。

您可以在 此处 找到完整的示例,使用的是 flutter_webview_plugin 包。

您也可以使用 url_launcher 进行深度链接,如 这篇文章 中所述,由我的朋友 TesteurManiak 描述,或者根据您的目标系统使用任何其他方法。

支持的端点

注意:虽然理论上这些端点功能正常(并且在人工测试中证明有效),但尚未进行单元测试。

用户

  • ✅ 获取当前用户
  • ✅ 获取用户
  • ✅ 修改当前用户
  • ✅ 获取当前用户服务器
  • ✅ 获取当前用户服务器成员
  • ✅ 离开服务器
  • ✅ 创建私聊
  • ❌ 创建群组私聊
  • ✅ 获取当前用户连接

服务器

  • ✅ 获取服务器
  • ✅ 获取服务器预览
  • ❌ 修改服务器
  • ❌ 删除服务器
  • ❌ 创建服务器频道
  • ❌ 修改服务器频道位置
  • ❌ 列出活跃线程
  • ❌ 获取服务器成员
  • ❌ 列出服务器成员
  • ❌ 搜索服务器成员
  • ❌ 添加服务器成员
  • ❌ 修改服务器成员
  • ❌ 修改当前成员
  • ❌ 修改当前用户的昵称
  • ❌ 添加服务器成员角色
  • ❌ 移除服务器成员角色
  • ❌ 移除服务器成员
  • ❌ 获取服务器封禁
  • ❌ 获取服务器封禁
  • ❌ 创建服务器封禁
  • ❌ 移除服务器封禁
  • ❌ 获取服务器角色
  • ❌ 创建服务器角色
  • ❌ 修改服务器角色位置
  • ❌ 修改服务器角色
  • ❌ 删除服务器角色
  • ❌ 获取服务器修剪计数
  • ❌ 开始服务器修剪
  • ❌ 获取服务器语音区域
  • ❌ 获取服务器邀请
  • ❌ 获取服务器集成
  • ❌ 删除服务器集成
  • ❌ 获取服务器小部件设置
  • ❌ 修改服务器小部件
  • ❌ 获取服务器小部件
  • ❌ 获取服务器个性域名
  • ❌ 获取服务器小部件图像
  • ❌ 获取服务器欢迎屏幕
  • ❌ 修改服务器欢迎屏幕
  • ❌ 修改当前用户的语音状态
  • ❌ 修改用户语音状态

表情符号

  • ❌ 列出服务器表情符号
  • ❌ 获取服务器表情符号
  • ❌ 创建服务器表情符号
  • ❌ 修改服务器表情符号
  • ❌ 删除服务器表情符号

频道

  • ❌ 获取频道
  • ❌ 修改频道
  • ❌ 删除/关闭频道
  • ❌ 获取频道消息
  • ❌ 获取频道消息
  • ❌ 发送消息
  • ❌ 跨频道转发消息
  • ❌ 创建反应
  • ❌ 删除自己的反应
  • ❌ 删除用户反应
  • ❌ 获取反应
  • ❌ 删除所有反应
  • ❌ 删除所有表情符号的反应
  • ❌ 编辑消息
  • ❌ 删除消息
  • ❌ 批量删除消息
  • ❌ 编辑频道权限
  • ❌ 获取频道邀请
  • ❌ 创建频道邀请
  • ❌ 删除频道权限
  • ❌ 关注新闻频道
  • ❌ 触发打字指示器
  • ❌ 获取已钉住的消息
  • ❌ 钉住消息
  • ❌ 解钉消息
  • ❌ 添加群组DM接收者
  • ❌ 删除群组DM接收者
  • ❌ 从消息开始线程
  • ❌ 无消息开始线程
  • ❌ 加入线程
  • ❌ 添加线程成员
  • ❌ 离开线程
  • ❌ 删除线程成员
  • ❌ 获取线程成员
  • ❌ 列出线程成员
  • ❌ 列出活跃线程
  • ❌ 列出公共存档线程
  • ❌ 列出私人存档线程
  • ❌ 列出加入的私人存档线程

审计日志

  • ❌ 获取服务器审计日志

服务器计划事件

  • ❌ 列出服务器计划事件
  • ❌ 创建服务器计划事件
  • ❌ 获取服务器计划事件
  • ❌ 修改服务器计划事件
  • ❌ 删除服务器计划事件
  • ❌ 获取服务器计划事件用户
  • ❌ 服务器计划事件状态更新自动化
  • ❌ 服务器计划事件权限要求

服务器模板

  • ❌ 获取服务器模板
  • ❌ 从服务器模板创建服务器
  • ❌ 获取服务器模板
  • ❌ 创建服务器模板
  • ❌ 同步服务器模板
  • ❌ 修改服务器模板
  • ❌ 删除服务器模板

邀请

  • ❌ 获取邀请
  • ❌ 删除邀请

阶段实例

  • ❌ 创建阶段实例
  • ❌ 获取阶段实例
  • ❌ 修改阶段实例
  • ❌ 删除阶段实例

贴纸

  • ❌ 获取贴纸
  • ❌ 列出Nitro贴纸包
  • ❌ 列出服务器贴纸
  • ❌ 获取服务器贴纸
  • ❌ 创建服务器贴纸
  • ❌ 修改服务器贴纸
  • ❌ 删除服务器贴纸

语音

  • ❌ 列出语音区域

网络钩子

  • ❌ 创建网络钩子
  • ❌ 获取频道网络钩子
  • ❌ 获取服务器网络钩子
  • ❌ 获取网络钩子
  • ❌ 使用令牌获取网络钩子
  • ❌ 修改网络钩子
  • ❌ 使用令牌修改网络钩子
  • ❌ 删除网络钩子
  • ❌ 使用令牌删除网络钩子
  • ❌ 执行网络钩子
  • ❌ 执行兼容Slack的网络钩子
  • ❌ 执行兼容GitHub的网络钩子
  • ❌ 获取网络钩子消息
  • ❌ 编辑网络钩子消息
  • ❌ 删除网络钩子消息

OAuth2

  • ❌ 获取当前机器人应用信息
  • ❌ 获取当前授权信息

完整示例代码

以下是一个完整的示例代码,展示了如何使用 discord_api 包进行 Discord API 集成。

import 'package:flutter/material.dart';
import 'package:discord_api/discord_api.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';

import 'webview_page.dart';

const clientId = 'YOUR_CLIENT_ID';
const clientSecret = 'YOUR_CLIENT_SECRET';
const redirectUri = 'http://localhost:8080/callback';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Discord API Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(title: 'Discord API Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _discordClient = DiscordClient(
    clientId: clientId,
    clientSecret: clientSecret,
    redirectUri: redirectUri,
    discordHttpClient: DiscordDioProvider(clientId: clientId, clientSecret: clientSecret),
  );

  final _flutterWebviewPlugin = FlutterWebviewPlugin();

  void _urlListener(String url) {
    if (url.startsWith(redirectUri)) {
      final code = Uri.parse(url).queryParameters['code'];
      if (code != null) {
        _discordClient.getAccessToken(code).then((token) {
          _flutterWebviewPlugin.close();
          setState(() {});
        });
      }
    }
  }

  Future<DiscordToken?> _openConnectionPage({List<DiscordApiScope> scopes = const []}) {
    _flutterWebviewPlugin.onUrlChanged.listen(_urlListener);
    _flutterWebviewPlugin.onDestroy.listen((_) => Navigator.pop(context));

    final url = _discordClient.authorizeUri(scopes);

    return Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => WebViewPage(url.toString()),
      ),
    ).then((_) {
      if (_discordClient.discordHttpClient.discordToken != null) {
        debugPrint("TOKEN: ${_discordClient.discordHttpClient.discordToken?.accessToken}");
        return _discordClient.discordHttpClient.discordToken;
      }
      return null;
    });
  }

  [@override](/user/override)
  void initState() {
    super.initState();
    WidgetsBinding.instance?.scheduleFrameCallback((timeStamp) {
      _openConnectionPage(
        scopes: [
          DiscordApiScope.identify,
          DiscordApiScope.email,
          DiscordApiScope.guilds
        ],
      ).then((value) => setState(() {}));
    });
  }

  void _displayDataAlert({
    String? method,
    String? data,
    bool isImg = false,
    bool? isOnline,
  }) {
    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: Text(method ?? ''),
          content: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: [
              if (isOnline != null)
                Text(
                  isOnline ? 'Online' : 'Offline',
                  style: TextStyle(
                    color: isOnline ? Colors.green : Colors.red,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              if (!isImg && data != null) Text(data),
              if (isImg && data != null)
                Image.network(
                  data,
                  loadingBuilder: (_, __, ___) => const CircularProgressIndicator(),
                ),
            ],
          ),
        );
      },
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(
        children: <Widget>[
          Text(
            'Your Discord access token is: ${_discordClient.discordHttpClient.discordToken?.accessToken}',
          ),
          ElevatedButton(
            onPressed: () async {
              final user = await _discordClient.getCurrentUser();
              _displayDataAlert(
                method: 'getCurrentUser',
                data: user.toString(),
              );
            },
            child: const Text('Get Me'),
          ),
        ],
      ),
    );
  }
}

更多关于Flutter Discord API集成插件discord_api的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Discord API集成插件discord_api的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个使用 discord_api 插件在 Flutter 应用中集成 Discord API 的示例代码。这段代码将展示如何初始化客户端、获取用户信息以及发送消息到指定频道。

首先,确保你已经在 pubspec.yaml 文件中添加了 discord_api 依赖:

dependencies:
  flutter:
    sdk: flutter
  discord_api: ^最新版本号  # 请替换为实际可用的最新版本号

然后,运行 flutter pub get 来安装依赖。

接下来是具体的代码实现:

import 'package:flutter/material.dart';
import 'package:discord_api/discord_api.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Discord API Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DiscordApiExample(),
    );
  }
}

class DiscordApiExample extends StatefulWidget {
  @override
  _DiscordApiExampleState createState() => _DiscordApiExampleState();
}

class _DiscordApiExampleState extends State<DiscordApiExample> {
  final String clientId = '你的客户端ID';
  final String clientSecret = '你的客户端密钥';
  final String redirectUri = '你的重定向URI';
  final String botToken = '你的Bot Token';
  late DiscordClient discordClient;
  late DiscordUser? user;

  @override
  void initState() {
    super.initState();
    initializeDiscordClient();
  }

  void initializeDiscordClient() async {
    // Initialize Discord client with OAuth2 credentials
    discordClient = DiscordClient(
      clientId: clientId,
      clientSecret: clientSecret,
      redirectUri: redirectUri,
    );

    // Fetch the user info using the bot token
    try {
      var botClient = DiscordBotClient(token: botToken);
      var userInfoResponse = await botClient.getCurrentUser();
      setState(() {
        user = userInfoResponse.user;
      });
      print('User Info: ${userInfoResponse.user.toJson()}');
    } catch (e) {
      print('Error fetching user info: $e');
    }
  }

  void sendMessageToChannel(String channelId, String content) async {
    try {
      var botClient = DiscordBotClient(token: botToken);
      await botClient.sendMessage(channelId, content);
      print('Message sent successfully');
    } catch (e) {
      print('Error sending message: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Discord API Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text('User Info:', style: TextStyle(fontSize: 18)),
            if (user != null) {
              Text('Username: ${user!.username}#${user!.discriminator}'),
              Text('ID: ${user!.id}'),
            } else {
              Text('Loading...'),
            },
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                sendMessageToChannel('你的频道ID', 'Hello, Discord!');
              },
              child: Text('Send Message'),
            ),
          ],
        ),
      ),
    );
  }
}

注意事项:

  1. 替换占位符:将 你的客户端ID你的客户端密钥你的重定向URI你的Bot Token你的频道ID 替换为实际的 Discord API 凭证和频道 ID。

  2. OAuth2 流程:此示例仅展示了如何使用 Bot Token 获取用户信息和发送消息。如果你需要完整的 OAuth2 流程(例如登录和获取访问令牌),你还需要处理重定向 URI 并处理授权码。

  3. 错误处理:示例代码中仅简单打印了错误消息,实际开发中应添加更详细的错误处理和用户反馈。

  4. 权限:确保你的 Bot Token 和 OAuth2 应用具有足够的权限来执行这些操作。

  5. 安全性:不要在客户端代码中硬编码敏感信息(如 Bot Token)。考虑使用环境变量或安全的存储方式。

希望这个示例能帮助你集成 Discord API 到你的 Flutter 应用中。

回到顶部