跳到主要内容
版本:v4

快速接入

功能概述

  • TapTap 好友功能支持在游戏内引入 TapTap 好友关系,帮助游戏社交冷启动。支持拉取关系列表、查看用户信息(用户名片)、好友聊天、发送邀请消息(让好友一键打开游戏、进入指定组队/房间页面)等功能。
  • 用户名片、好友聊天和邀请功能由 TapTap 启动器客户端原生提供,游戏侧只需通过 SDK 激活对应窗口即可,无需自行实现。

服务优势

  • 快速建立游戏关系,支撑游戏玩法。
    • 直接将玩家在 TapTap 已结成的社交关系导入游戏,配合好友聊天和邀请消息,辅助多人联机组队玩法。
  • 便捷分享游戏,拉新促活。
    • 邀请消息可发送给未玩本游戏的 TapTap 好友,对方通过邀请消息可一键下载/启动游戏,社交传播带动增长与活跃。
  • 无需负担好友服务器成本。
    • 好友功能由 TapTap 提供服务端支持,开发者无需额外服务器成本。
  • 接入简单,功能全面
    • 基于 TapTap 启动器提供了好友管理、聊天、邀请、用户名片界面,无需游戏处理复杂的界面与程序逻辑。

集成步骤

  • 本文档以 C++ 为例演示好友模块集成步骤,其他语言可参考相应的 DLL 调用方式。
  • 在集成好友模块之前,请先阅读快速开始了解基本的集成流程,并完成 SDK 初始化与启动校验。
详细接口文档

本文仅介绍集成流程,接口的详细说明和枚举、结构体定义等,请阅读好友模块 API 参考

初始化要求

调用好友模块任何 API 函数前,必须先成功调用 TapSDK_Init 进行初始化。未初始化或初始化失败时,调用好友模块函数将返回错误或者非预期结果。

1. 准备工作

  • 开启 TapTap 好友服务。
    • 在开发者中心游戏的控制台,通过「游戏服务 - TapTap 好友」开启。
  • 申请授权。
  • 回调事件。
    • 好友模块涉及的回调事件为TapEventIDRelation前缀的事件。

2. 拉取关系列表

好友模块提供三组列表拉取接口,使用方式一致,仅事件 ID 与响应结构体不同:

  • 互相关注(互关好友):TapRelation_AsyncGetFriendList(),回调事件 RelationGetFriendList
  • 我关注的(关注列表):TapRelation_AsyncGetFollowingList(),回调事件 RelationGetFollowingList
  • 关注我的(粉丝列表):TapRelation_AsyncGetFanList(),回调事件 RelationGetFanList

分页拉取:首次请求时 continuation_tokenNULL,回调返回的 continuation_tokenNULL 时表示还有下一页,将其传给下一次请求即可。

#include <atomic>
#include <iostream>
#include <string>
#include <thread>

#include "taptap_relation.h"

using namespace std;

atomic<int64_t> gRequestID;

// 用于翻页:保存上一页回调返回的 continuation_token
// 注意:回调返回后 SDK 会释放 resp 及其引用的内存,token 必须拷贝一份再使用
string gFriendListNextToken;

// 拉取互关好友列表的回调函数
void getFriendListCallback(TapEventID eventID, void* data)
{
// 使用 TapRelationGetFriendListResponse* 强转 data 类型,获取互关好友列表
// 注意:data 及其里面引用的其他内存,在回调函数返回后会被 SDK 释放。如需长期使用,请开发者自行复制一份
auto resp = static_cast<TapRelationGetFriendListResponse*>(data);
if (resp->error != nullptr) { // 请求失败,处理错误
cout << "get friend list failed, code=" << resp->error->code
<< ", message=" << resp->error->message << endl;
return;
}

cout << "get friend list success: requestID=" << resp->request_id
<< ", friend_count=" << resp->friend_count << endl;
for (uint32_t i = 0; i < resp->friend_count; ++i) {
const auto& f = resp->friends[i];
// 注意:所有字符串字段(char*)均为 UTF-8 编码,请根据需要自行转换
cout << " - open_id=" << f.open_id
<< ", name=" << (f.name ? f.name : "")
<< ", alias=" << (f.alias ? f.alias : "")
<< ", following=" << f.follow_status.following
<< ", followed=" << f.follow_status.followed << endl;
}

// continuation_token 非 NULL 表示还有下一页;拷贝后用于下一次请求
if (resp->continuation_token != nullptr) {
gFriendListNextToken = resp->continuation_token;
} else {
gFriendListNextToken.clear(); // 已经是最后一页
}
}

int main()
{
// 这里省略 SDK 初始化和启动校验相关代码,假设已经正确完成
// 同时假设已经完成 user_friends 授权(参考"准备工作"章节)

// 1. 注册拉取互关好友列表回调函数,只需注册一次
TapSDK_RegisterCallback(TapEventID::RelationGetFriendList, getFriendListCallback);

// 2. 构建拉取请求(首页:continuation_token 传 NULL)
TapRelationGetFriendListRequest req{};
req.continuation_token = nullptr;

// 3. 发起异步请求
auto ret = TapRelation_AsyncGetFriendList(
TapRelation(), // 好友模块单例对象
++gRequestID, // 请求 ID,由开发者生成,用于在回调函数中对应到原始请求
&req);
if (ret != TapSDK_Result_OK) { // 请求发起失败,不会触发回调,请根据返回值做相应处理
cout << "TapRelation_AsyncGetFriendList failed, ret=" << ret << endl;
return -1;
}

// 请求发起成功,等待回调函数返回处理结果

// 4. 游戏主循环
bool running = true;
while (running) {
// 处理 SDK 回调事件
TapSDK_RunCallbacks();

// 示例:如果上次回调返回了 continuation_token,则继续拉取下一页
if (!gFriendListNextToken.empty()) {
TapRelationGetFriendListRequest nextReq{};
nextReq.continuation_token = gFriendListNextToken.c_str();
TapRelation_AsyncGetFriendList(TapRelation(), ++gRequestID, &nextReq);
gFriendListNextToken.clear(); // 避免重复发起
}

// 您的游戏逻辑
// ...

// 控制帧率,请按游戏实际需求调整
this_thread::sleep_for(chrono::milliseconds(100));
}

// 5. 清理资源
TapSDK_Shutdown();
return 0;
}

拉取关注、粉丝列表的方式相同,仅事件 ID 与响应结构体不同:

// 关注列表
TapSDK_RegisterCallback(TapEventID::RelationGetFollowingList, getFollowingListCallback);
TapRelationGetFollowingListRequest reqFollowing{};
TapRelation_AsyncGetFollowingList(TapRelation(), ++gRequestID, &reqFollowing);
// 回调中 data 强转为 TapRelationGetFollowingListResponse*

// 粉丝列表
TapSDK_RegisterCallback(TapEventID::RelationGetFanList, getFanListCallback);
TapRelationGetFanListRequest reqFan{};
TapRelation_AsyncGetFanList(TapRelation(), ++gRequestID, &reqFan);
// 回调中 data 强转为 TapRelationGetFanListResponse*

3. 同步好友关系

如果游戏自身已有好友体系(如游戏内好友、公会成员等),可通过 TapRelation_AsyncSyncRelationshipWithOpenID()TapRelation_AsyncSyncRelationshipWithUnionID() 把游戏内的好友关系同步给 TapTap。

// 同步回调
void syncRelationshipCallback(TapEventID eventID, void* data)
{
auto resp = static_cast<TapRelationSyncRelationshipResponse*>(data);
if (resp->error != nullptr) {
cout << "Sync relationship failed, code=" << resp->error->code
<< ", message=" << resp->error->message << endl;
return;
}
cout << "Sync relationship success, request_id=" << resp->request_id << endl;
}

// 注册回调(通常在 SDK 初始化后注册一次即可)
TapSDK_RegisterCallback(TapEventID::RelationSyncRelationshipWithOpenID, syncRelationshipCallback);

// 通过 OpenID 同步:新增一段好友关系
TapRelationSyncRelationshipWithOpenIDRequest req{};
// action: Add 表示新增好友关系,Remove 表示移除好友关系
req.action = TapRelation_SyncRelationshipActionType_Add;
// nickname / friend_nickname: 本人和对方在游戏内的昵称,不允许 NULL,不允许空字符串
req.nickname = "我的游戏昵称";
req.friend_nickname = "对方游戏昵称";
req.friend_open_id = "friend_open_id";

auto ret = TapRelation_AsyncSyncRelationshipWithOpenID(
TapRelation(), ++gRequestID, &req);
if (ret != TapSDK_Result_OK) {
// 请求发起失败
}

通过 UnionID 同步同理,将 TapRelation_AsyncSyncRelationshipWithOpenID 替换为 TapRelation_AsyncSyncRelationshipWithUnionID,对应字段 friend_open_id 替换为 friend_union_id,并注册 TapEventID::RelationSyncRelationshipWithUnionID 事件即可。

4. 未读消息数与新增粉丝数

为便于游戏内展示「TapTap 消息红点/粉丝红点」,好友模块同时提供:

  • 变化通知(推荐):注册监听事件后,会立刻通过消息通知返回当前未读消息数/新增粉丝数。变化时会实时收到事件通知。
  • 同步查询接口(不推荐):用于游戏内打开对应界面时一次性拉取或轮询拉取。
// 监听未读消息数变化通知
void onUnreadMessageCountChanged(TapEventID eventID, void* data)
{
auto n = static_cast<TapRelationUnreadMessageCountNotification*>(data);
cout << "unread message count changed: " << n->count << endl;
// 更新游戏内红点 UI
}
// 注册后,SDK 会立刻触发一次回调,返回当前未读消息数;后续未读消息数变化时会实时触发回调
TapSDK_RegisterCallback(TapEventID::RelationUnreadMessageCountChanged, onUnreadMessageCountChanged);

// 监听新增粉丝数变化通知
void onNewFanCountChanged(TapEventID eventID, void* data)
{
auto n = static_cast<TapRelationNewFanCountNotification*>(data);
cout << "new fan count changed: " << n->count << endl;
// 更新游戏内红点 UI
}
// 注册后,SDK 会立刻触发一次回调,返回当前新增粉丝数;后续新增粉丝数变化时会实时触发回调
TapSDK_RegisterCallback(TapEventID::RelationNewFanCountChanged, onNewFanCountChanged);

// 一次性查询当前未读消息数
uint32_t unreadCount = 0;
auto ret = TapRelation_GetUnreadMessageCount(TapRelation(), &unreadCount);
if (ret == TapSDK_Result_OK) {
cout << "current unread message count: " << unreadCount << endl;
}

// 一次性查询当前新增粉丝数
uint32_t newFanCount = 0;
ret = TapRelation_GetNewFanCount(TapRelation(), &newFanCount);
if (ret == TapSDK_Result_OK) {
cout << "current new fan count: " << newFanCount << endl;
}

5. 打开用户名片

激活 TapTap 启动器用户名片窗口,可执行关注、取关、邀上线操作。点击X会关闭窗口并回到游戏。

// 打开指定用户的名片窗口,open_id 与 union_id 二选一
TapRelationShowUserProfileRequest req{};
req.open_id = "target_open_id";
// req.union_id = "target_union_id"; // 与 open_id 同时传递会报错

auto ret = TapRelation_ShowUserProfile(TapRelation(), &req);
if (ret != TapSDK_Result_OK) {
cout << "TapRelation_ShowUserProfile failed, ret=" << ret << endl;
}

用户名片窗口会根据当前用户与对方的关注关系,展示不同的操作按钮:

关注关系界面示例操作说明
未关注未关注点“关注”可关注对方。
已关注已关注点“已关注”可取消关注。
被关注被关注点“回关”可成为互关好友。
互相关注互关点“邀上线”给对方发送邀请消息,同时关闭窗口并回到游戏。
点“互关好友”可取消关注。

给好友发“邀上线”消息后,对方聊天窗口收到的消息:

邀上线消息

6. 打开好友聊天窗口

激活 TapTap 启动器好友聊天窗口,与好友点对点私聊。点击X会关闭窗口并回到游戏。

// 打开 TapPC IM 主窗口,玩家可以在窗口内给好友发消息、管理好友等
TapRelation_ShowIM(TapRelation());

聊天窗口示例如下:

好友聊天

7. 邀请好友

  • 给好友发送邀上线/邀组队消息,好友点击消息即可一键启动游戏或进入指定组队/房间。
  • 详细接入方式请参考邀请好友

错误码

  • 接口调用返回值均为 TapSDK_Result,可根据该值做提示或重试。详见 TapSDK_Result
    • 返回值非 TapSDK_Result_OK 时,表示请求发起失败,后续不会触发回调。
  • 异步请求回调中 resp->error 非空时,表示请求失败,可根据 TapSDK_ErrorCode 做提示或重试。详见 TapSDK_ErrorCode