跳到主要内容

Discord 社交 SDK

系统版本要求

最低兼容系统版本:INTLDiscord 插件支持的最低版本

  • Android 5
  • iOS 11
  • Windows 10

最低支持系统版本:Discord 相关功能启用的最低版本

  • Android 7
  • iOS 15.1
  • Windows 10

当系统版本位于两者之间时,可以集成 INTLDiscord 插件,但是 Discord 相关的功能将被屏蔽。

说明

本功能仅提供对数据的访问,不提供任何UI,游戏需根据 Discord UI设计规范 自行进行设计。

Discord 社交 SDK 可让您在游戏中构建社交功能,实现玩家在游戏内与游戏外的 Discord 好友进行 跨平台互动,以增强游戏的社交体验。

Discord 社交功能登录功能 互相独立。您可以登录 Discord 渠道,绑定 Discord 好友关系,也可以登录其他渠道,绑定 Discord 好友关系。

主要功能包含:

  • 好友列表、好友关系管理
  • 文字聊天
  • 通过设置游戏状态(Rich Presence)来更新游戏内的活动信息
  • 通过创建大厅以发起游戏邀请
  • 语音聊天(Player Network 暂未集成,如有使用需求,请联系我们)

接入流程

图片:接入流程

功能说明

注意

当前暂未支持 Discord 临时账号(Provisional Account)授权。游戏内使用 Discord 社交功能,需先引导玩家绑定 Discord 账号、授权社交 SDK 相关 OAuth2 Scope。

好友列表

接入好友列表功能后,即可在游戏内展示玩家的 Discord 好友列表,包含平台好友、同玩好友。

在列表中,支持展示玩家好友的基本信息(ID、用户名、展示名称、头像、账户类型、关系类型、在线状态等)、管理好友(添加、删除、屏蔽)、管理好友请求等。

说明

Discord 返回的列表没有排序规则,Player Network 可返回玩家 OpenID 最近在线时间,供游戏调整排序规则。

好友列表示例:
图片:好友列表1
图片:好友列表2

管理好友示例:
图片:管理好友1
图片:管理好友2

文字聊天

注意

应 Discord 平台要求,接入此功能,需在游戏上线前额外说明,以开启现网权限。

接入文字聊天功能后,玩家即可在游戏内向游戏外的 Discord 好友发送 Discord 消息,方便与游戏不在线的好友进行互动。

说明

Discord 不提供敏感词过滤功能,需游戏自行实现。

设置游戏状态

说明

此功能在 Discord 称为 Rich Presence,又名“Activity”,可以理解为“用户的当前活动”。

此功能可让您显示玩家在游戏中活动的详细信息,比如当前游戏状态、进度、自定义图标及互动按钮。玩家可以在自己的 Discord 个人资料和好友列表中查看这些信息,并使用游戏邀请的互动按钮,加入好友的游戏。

集成 Rich Presence 时,请先在 Discord 平台应用设置中上传 Rich Presence 相关的自定义美术资源。

设置界面如图:
图片:创建应用

用户示例如图:
图片:创建应用

好友邀请

允许玩家在游戏内向好友发送 Discord 邀请消息,邀请其加入游戏活动、语音频道或特定会话。通过设置游戏状态及大厅功能,可实现游戏与 Discord 间的跨平台好友邀请。

说明

大厅是一个虚拟空间,指可以通过文本和语音相互交流的用户群组,玩家可以同时加入多个大厅。

用户流程示例:

  1. 玩家开始玩游戏时,自动创建一个带有随机密钥的大厅
  2. 玩家发布 Rich Presence,并将加入密钥设置为大厅密钥
  3. 其他玩家可以在 Discord 上看到 Rich Presence 并请求加入
  4. 请求被接受,新玩家加入大厅

步骤1:在 Discord 开发者平台上配置应用

说明

请先在 Player Network 完成 Discord 登录配置,如果您已完成 ,可跳过步骤1.1。

1. 创建 Discord 应用
  1. Discord 官方网站 上注册一个账号,并根据提示完成账号认证。

  2. 进入 Discord 开发者平台Applications 页面右上角,点击 New Application图片:创建应用

  3. 在弹出的应用程序创建窗口中,输入应用程序名称,然后点击 Create

  4. General Information 页面,查看 APPLICATION ID
    用户必须在 INTLConfig.ini 文件中配置 DIscord App ID。 图片:获取 ID

2. 申请 Discord SDK 访问权限
  1. 进入 Discord 开发者平台
  2. Applications 页面,单击您的应用程序。
  3. 点击左侧导航栏中的 Getting Started,填写表单信息,点击 Submit,即可开启接入权限。 图片:填写表单信息 图片:完成表单信息
警告

注意:游戏正式上线前,仍需提前告知 Discord 团队,以便开启现网调用权限。

3. 配置应用
  1. 进入 Discord 开发者平台

  2. Applications 页面,单击要配置的应用程序。

  3. 点击左侧导航栏中的 OAuth2

  4. 打开 PUBLIC CLIENT 开关。 图片:打开 PUBLIC CLIENT 开关

  5. Redirects 下配置重定向 URI,用于在 Discord 网页进行授权后接收回调,可点击 Add Another 增加单元格。

    • Android/iOS - discord-{YOUR_APP_ID}:/authorize/callback
      • {YOUR_APP_ID} 替换为应用程序的 ID。
    • PC - http://127.0.0.1/callback

    图片:配置 Redirect

    注意

    如果移动端需要从 Discord App 点击邀请链接跳转到游戏客户端的功能,还需要配置deeplink,请在 General Information 页 Deep Link URL部分添加跳转到应用程序的DeepLink URL。 图片:移动端deeplink

  6. 点击左侧导航栏中的 Rich Presence,进入 Rich Presence Art Assets 页面。

  7. 点击 Add Image(s),配置应用程序的图片资源。 图片:配置资源

步骤2:注册回调

开发人员可以根据需要注册以下回调函数,以接收相关事件的通知。

一般函数回调

// 添加回调函数
INTLAPI.AddDiscordBaseResultObserver(OnDiscordBaseResult);

// 移除回调函数
INTLAPI.RemoveDiscordBaseResultObserver(OnDiscordBaseResult);

// 处理 DiscordBaseResult 回调事件
private void OnDiscordBaseResult(INTLBaseResult baseRet)
{
string methodTag = "";

if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_AUTHORIZE) {
methodTag = "DiscordAuthorize";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_CREATE_LOBBY) {
methodTag = "DiscordCreateLobby";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_LEAVE_LOBBY) {
methodTag = "DiscordLeaveLobby";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_SET_RICH_PRESENCE) {
methodTag = "DiscordSetRichPresence";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_SEND_MESSAGE) {
methodTag = "DiscordSendMessage";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_REMOVE_FRIEND) {
methodTag = "DiscordRemoveFriend";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_ADD_FRIEND_BY_ID) {
methodTag = "DiscordAddFriendByID";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_ADD_FRIEND_BY_NAME) {
methodTag = "DiscordAddFriendByName";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_ACCEPT_FRIEND_REQUEST) {
methodTag = "DiscordAcceptFriendRequest";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_SEND_INVITE_TO_FREIND) {
methodTag = "DiscordSendInviteToFriend";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_ACCEPT_INVITE_FROM_FRIEND) {
methodTag = "DiscordAcceptInviteFromFriend";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_ON_RELATIONSHIP_CHANGED) {
methodTag = "DISCORD_ON_RELATIONSHIP_CHANGED";
} else if (baseRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_ON_LOBBY_MEMBER_CHANGED) {
methodTag = "DISCORD_ON_LOBBY_MEMBER_CHANGED";
}
}

个人信息回调

// 添加回调函数
INTLAPI.AddDiscordUserResultObserver(OnDiscordUserResult);

// 移除回调函数
INTLAPI.RemoveDiscordUserResultObserver(OnDiscordUserResult);

// 处理 OnDiscordUserResult 回调事件
private void OnDiscordUserResult(INTLDiscordUserResult userRet)
{
string methodTag = "";
if (userRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_GET_CONNECTED_USER)
{
methodTag = "DiscordGetConnectedUser";
}
}

好友列表回调

// 添加回调函数
INTLAPI.AddDiscordFriendsResultObserver(OnDiscordFriendResult);

// 移除回调函数
INTLAPI.RemoveDiscordFriendsResultObserver(OnDiscordFriendResult);

// 处理 OnDiscordFriendResult 回调事件
private void OnDiscordFriendResult(INTLDiscordFriendResult friendRet)
{
string methodTag = "";
if (friendRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_QUERY_FRIENDS)
{
methodTag = "DiscordQueryFriends";
}
}

文字消息回调

// 添加回调函数
INTLAPI.AddDiscordMessageResultObserver(OnDiscordMessageResult);

// 移除回调函数
INTLAPI.RemoveDiscordMessageResultObserve(OnDiscordMessageResult);

// 处理 OnDiscordMessageResult 回调事件
private void OnDiscordMessageResult(INTLDiscordMessageResult messageRet)
{
string methodTag = "";
if (messageRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_ON_MESSAGE_CHANGED)
{
methodTag = "DISCORD_ON_MESSAGE_CHANGED";
}
}

大厅邀请回调

// 添加回调函数
INTLAPI.AddDiscordInviteResultObserver(OnDiscordInviteResult);

// 移除回调函数
INTLAPI.RemoveDiscordInviteResultObserver(OnDiscordInviteResult);

// 处理 OnDiscordInviteResult 回调事件
private void OnDiscordInviteResult(INTLDiscordInviteResult inviteRet)
{
string methodTag = "";
if (inviteRet.MethodId == (int)INTLMethodID.INTL_FRIEND_DISCORD_ON_INVITE_ACCEPTED)
{
methodTag = "DISCORD_ON_INVITE_ACCEPTED";
}
}
注意

强烈建议在游戏程序的启动功能中注册回调。

步骤3:函数

DiscordAuthorize

需要用户完成 Discord 账号绑定并授予好友权限才能使用以下功能,授予好友权限的 Scope 与授予登录权限的 Scope 并不相同。

首次绑定 : 在移动端绑定时,将通过浏览器拉起 Discord 授权页;在 PC 端绑定时,若已安装 Discord 桌面应用,则拉起应用完成授权,若未安装,则通过浏览器拉起 Discord 授权页。用户输入 Discord 用户名与密码、同意授权后,将完成该 Discord 账号将与游戏账号的绑定。

再次绑定 : 使用缓存直接绑定。同一用户更换物理设备或卸载重装后会重新拉起授权页绑定。

解除绑定 : 如需解除与 Discord 账号的绑定,用户需在游戏侧(如:LI PASS 账号中心)操作。仅在 Discord 平台取消账号授权,将无法解除游戏账号与 DIsord 账号的绑定关系;当用户再次尝试绑定时,若绑定的是与之前不同的 Discord 账号,会返回冲突错误。

说明

应在每次登录之后且调用其他 Discord 接口前调用本函数,在回调结果返回 SUCCESS 之后再调用其他函数。

授权页样式参考: 图片:授权页

// 函数定义
public static void DiscordAuthorize();

// 代码示例
INTLAPI.DiscordAuthorize();

回调处理接口:DiscordBaseResultObserver

DiscordGetConnectedUser

查询与Discord绑定的用户信息,通过回调返回DiscordUserResult,用户数据结构详见DiscordUserInfo

// 函数定义
public static void DiscordGetConnectedUser();

// 代码示例
INTLAPI.DiscordGetConnectedUser();

回调处理接口:DiscordUserResultObserver

DiscordSetRichPresence

在 Discord 客户端上设置的绑定用户的游戏状态,输入参数 presence 可参考:DiscordRichPresence

// 函数定义
public static void DiscordSetRichPresence(INTLDiscordRichPresence presence);

// 代码示例
INTLDiscordRichPresence richPresence = new INTLDiscordRichPresence();

richPresence.GameName = "Sample";
richPresence.State = "HappyTime";
richPresence.Details = "This is INTL Sample Game";
richPresence.LargeText = "largeText";
richPresence.LargeImage = "http://mat1.gtimg.com/www/qq2018/imgs/qq_logo_2018x2.png";
richPresence.SmallText = "smallText";
richPresence.SmallImage = "http://mat1.gtimg.com/www/qq2018/imgs/qq_logo_2018x2.png";
richPresence.StartTime = 0;
richPresence.EndTime = 0;
richPresence.PartyMaxSize = 5;
richPresence.SupportedPlatforms = 1 | 8 | 16;

INTLAPI.DiscordSetRichPresence(richPresence);

回调处理接口:DiscordBaseResultObserver

DiscordQueryFriends

获取当前绑定用户的Discord好友列表,包括发送好友申请的好友以及收到好友申请的好友,好友数据结构详见DiscordUserInfo

函数定义

public static void DiscordQueryFriends(int page, int count);

入参说明

参数类型说明是否必填格式要求
pageint页数>0
countint每页好友数量>0

代码示例

INTLAPI.INTLDiscordQueryFriends(1, 10);

回调处理接口:DiscordFriendsResultObserver

DiscordAddFriendByName

通过用户名发送好友申请,发送好友申请后,被申请人可以通过 DiscordQueryFriends 查询到。

被申请人同意后,会收到好友列表发生变动的回调。

// 函数定义
public static void DiscordAddFriendByName(string username);

// 代码示例
INTLAPI.DiscordAddFriendByName("xiaoming");

回调处理接口:DiscordBaseResultObserver

DiscordAddFriendByID

通过 uid 发送好友申请,发送好友申请后,被申请人可以通过 DiscordQueryFriends 查询到。

被申请人同意后,会收到好友列表发生变动的回调。

// 函数定义
public static void DiscordAddFriendById(string userId);

// 代码示例
INTLAPI.DiscordAddFriendById("123456789");

回调处理接口:DiscordBaseResultObserver

DiscordRemoveFriend

直接删除好友,无须对方同意。

删除方和被删除方都会收到好友列表发生变动的回调。

// 函数定义
public static void DiscordRemoveFriend(string userId);

// 代码示例
INTLAPI.DiscordRemoveFriend("123456789");

回调处理接口:DiscordBaseResultObserver

DiscordAcceptFriendRequest

通过userid接受其他人的Discord好友申请。

通过后,申请方和被申请方都可以收到好友列表发生变动的回调。

// 函数定义
public static void DiscordAcceptFriendRequest(string userId);

// 代码示例
INTLAPI.DiscordAcceptFriendRequest("123456789");

回调处理接口:DiscordBaseResultObserver

注意

无论调用 DiscordAddFriendByName DiscordAddFriendByID DiscordRemoveFriend 还是 DiscordAcceptFriendRequest,若成功,那么好友列表就会发生变动,发送方和接受方都会收到回调。

可通过监听 id 为 kMethodIDFriendDiscordOnRelationshipChanged 的 DiscordBaseResult 收到回调,回调没有userid信息,只是通知该用户的好友列表发生变动。若要得知详细信息,可通过DiscordQueryFriends查询。

DiscordSendMessage

向指定的Discord好友发送纯文字消息。

发送后,发送方和接收方都可以收到信息内容的回调。

警告

发送消息可能涉及用户隐私,游戏侧需要自行进行用户须知披露。

// 函数定义
public static void DiscordSendMessage(string recipientId, string content);

// 代码示例
INTLAPI.DiscordSendMessage("123456789", "hello world!");

回调处理接口:DiscordBaseResultObserver

关于发送消息,存在以下几种情况:

  • 用户A和用户B是好友 : A给B发送消息成功。
  • 用户A和用户B从未加过好友 : A给B发送消息失败。
  • 用户A和用户B曾经是好友,但是B被已被A删除
    • 如果B处于在线状态,那么DiscordSendMessage函数回调成功但是Discord客户端不显示该条消息。
    • 如果B处于离线状态,DiscordSendMessage函数回调报错50007。
说明

设置 DiscordMessageResultObserver 回调后即可监听来自Discord好友的消息变动,消息中可能包含emoji等非文字内容,游戏需自行处理。消息可分为创建、编辑、删除三种类型,可通过type成员判断。

DiscordCreateLobby

加入指定的大厅,如果大厅不存在则创建一个。

目前,一个用户在同一时间只能存在于一个大厅中,如果已经在一个大厅内,请先调用 DiscordLeaveLobby 离开当前大厅,才能加入一个新的大厅。退出游戏不会自动退出大厅,需主动调用。

注意,大厅并不是持久存在的,当成员都退出后,如果几分钟内没有一个用户存在于该大厅中,已创建的大厅将自动失效。

secret : 每个大厅由此字符串唯一标识,有效期约为 30 天。该字符串的值应该很难被用户猜到,所有使用相同 secret 加入大厅的用户将被置于同一大厅。推荐加密处理,防止不知情用户加入同一大厅。

// 函数定义
public static void DiscordCreateLobby(string secret);

// 代码示例
INTLAPI.DiscordCreateLobby("testsecret");

回调处理接口:DiscordBaseResultObserver

DiscordLeaveLobby

离开用户所在的大厅。

// 函数定义
public static void DiscordLeaveLobby();

// 代码示例
INTLAPI.DiscordLeaveLobby();

回调处理接口:DiscordBaseResultObserver

说明

任一成员加入或离开大厅时,大厅内的每一个成员都会收到来自 DiscordBaseResultObserver 的回调。

DiscordSendInviteToFriend

向好友发送大厅组队邀请。

严格遵循下列步骤才能成功发送游戏邀请:

  1. 创建游戏大厅
  2. 设置游戏状态
  3. 发送游戏邀请

如果受邀方接受了邀请,发送方可以接收到大厅成员发生变动的回调。

// 函数定义
public static void DiscordSendInviteToFriend(string userId, string content);


// 代码示例
INTLAPI.DiscordSendInviteToFriend("123456789", "hi,come to play with me");

回调处理接口:DiscordBaseResultObserver

DiscordAcceptInviteFromFriend

两种方式可以接受来自Discord游戏邀请:
方法一:函数定义方式
注册 DiscordInviteResultObserver ,游戏内监听到来自Discord好友邀请,可在回调里调用接受邀请的函数。
方法二:Discord客户端点击 join 按钮
在Discord客户端点击join按钮后,如果该邀请是有效的,PC端会自动加入邀请者所在的大厅,移动端则会通过deeplink拉起app,请根据设置在 Discord developer portal 上的 deeplink 进行解析,获得链接里的大厅joinsecret,然后调用DiscordCreateLobby函数,使受邀玩家加入邀请者在的大厅。

// 函数定义
public static void DiscordAcceptFriendRequest(string userId);


// 代码示例
INTLAPI.DiscordAcceptInviteFromFriend("123456789");

回调处理接口:DiscordBaseResultObserver