社交信息流
查看此篇文档前,请先查看并了解好友关系文档中的单向关注关系。信息流是关注关系中,被关注者发布的状态信息汇集而成的「时间线」或者「朋友圈」内容。
基本概念
状态(Status)
指用户发出来的即时状态,例如微博中的一个帖子,微信朋友圈中的一段文字,就是这里所说的「状态」,我们用 Status
表示。
社交组件中的 Status
是指一条广义上的「状态」,它不仅可以表示某个用户更新了状态,还可以表示任意的一个事件,比如某人发布了一篇文章,对某张图片点赞等等。在控制台中对应的表名称为 _Status
。
时间线
在社交类产品中,用户 A 关注了一些人之后,他就可以按照时间顺序查看到那些人发布的各种「状态」信息(这里我们暂且把这些信息称为「时间线」);同样,A 发布了某一条「状态」之后,一般就会马上被关注 ta 的其他人看到,但是也有例外(就是接下来的「私信」)。
私信
是状态中的一类特殊信息,只发给特定的用户,不会进入关注者的时间线来公开展示,例如微博里面的「私信」即是如此。
信息流 API
我们的信息流 API 主要提供以下功能:
- 用户 A 给用户 B 发送私信(发私信);
- 用户 A 给关注 ta 的用户群体发送公开的状态信息(发推和转推,等);
- 用户 B 可以查看别人给他发送的私信(私信列表);
- 用户 B 可以查看 ta 关注的用户群体发出来的状态信息(查看时间线);
- 用户 C 可以公开查看用户 A 发出去的所有公开的状态信息(查看单个用户的公开状态);
- 用户 A 可以删除自己已经发布的状态,此时所有接收者的收件箱也会自动删除该状态数据;
- 用户 A 可以删除/屏蔽自己时间线上其他人发出来的状态(只在自己时间线上不显示,发布者和其他关注者依然可以看到);
以下的功能我们无法在基础 API 层面提供支持:
- 用户 B 根据用户关系中的分组设置来查看不同的人发出来的状态信息;
- 状态发出之后无法修改(可以通过删除 + 发布来实现);
同时,信息流 API 是与用户账号系统绑定以及好友关系 API 绑定的,如果不使用这些内置组件,将无法正常使用信息流功能。接下来我们通过一些例子,看看如何使用信息流 API 来完成产品开发。
特别提示:
发了一条状态,并不代表会自动发送了一条推送消息,开发者可以自由控制是否使用推送。更多信息请参考《推送通知服务总览》。
JavaScript SDK
状态
关注了用户之后(也就是成为他的粉丝),你就会接收到该用户发送给他的粉丝的状态信息。例如,我喜欢了某个视频,我可以发送这条信息「我喜欢了视频 xxxx」给我的粉丝。我的粉丝就可以在他们的收件箱(inbox)里收到这条状态信息。
发布状态
当前登录用户发送一条状态给关注他的粉丝:
var status = new AV.Status('视频url', '我喜欢了视频xxxx.');
status.set('sound', 'sound.wmv');
AV.Status.sendStatusToFollowers(status).then(function(status){
//发布状态成功,返回状态信息
console.dir(status);
}, function(err){
//发布失败
console.dir(err);
});
发布状态成功,粉丝的收件箱不一定马上能看到,因为发布过程是一个异步的过程,会有一定的延迟,通常这个延迟都在几秒之内。发送状态必须处于用户登录状态,使用 AV.Status.sendStatusToFollowers
将发送给登录用户的粉丝。
AV.Status 对象包含下列属性:
属性 | 说明 |
---|---|
id | 对象的objectId |
messageId | 状态在某个用户收件箱的消息编号,发件箱返回的 status 则没有此属性,messageId 可用于 收件箱的分页查询。 |
inboxType | 收件箱类型,默认是 timeline 收件箱,也就是 default。SDK 默认提供 private(私信),default 表示 timeline,你也可以自定义。 |
data | 状态属性,一个 JSON 对象,可通过 get 和 set 方法获取和设置。 |
createdAt | 消息的创建时间 |
其中 data.source 属性是保留属性,默认指向状态的发布者。
发送私信给某个用户
我还可以发送一条私信给单独某个用户:
var status = new AV.Status(null, '机密消息');
AV.Status.sendPrivateStatus(status,'52f9be45e4b035debf88b6e2').
then(function(status){
//发送成功
console.dir(status);
}, function(err){
//发布失败
console.dir(err);
});
AV.Status.sendPrivateStatus
的第二个参数指定私信接收的用户或者用户的 objectId。
发送给自定义收件箱
通过 send
方法还可以自定义 inboxType:
var status = new AV.Status(null, '我读了《clojure 编程乐趣》');
//定义一个 book 收件箱
status.inboxType = 'book';
status.send().then(function(status){
//发送成功
});
查询收件箱
查询我的 timeline 收件箱,可以通过 AV.Status.inboxQuery
方法:
var query = AV.Status.inboxQuery(AV.User.current());
query.find().then(function(statuses){
//查询成功,返回状态列表,每个对象都是 AV.Status
}, function(err){
//查询失败
console.dir(err);
});
收件箱返回的 status 列表,每个 status 都有 messageId 属性,表示这条 status 在这个收件箱里的唯一编号,AV.InboxQuery
有两个方法用于限制 messageId 的范围:
- sinceId:设定查询返回的 status 的 messageId 必须大于传入的 messageId。
- maxId:限定查询返回的 status 的 messageId 必须小于等于传入的 messageId。
通过 sinceId 和 maxId 可以实现分页查询:
查询本次查询之后新增的 status(向后翻页刷新):
//假设 messageId 是上次查询返回的 status 的最大 messageId 编号
var messageId = ...
var query = AV.Status.inboxQuery(AV.User.current());
query.sinceId(messageId);
//查询从上次查询返回结果之后的更新 status
query.find().then(function(statuses){
//查询成功,返回状态列表,每个对象都是 AV.Status
}, function(err){
//查询失败
console.dir(err);
});
查询本次查询的前一页(也就是更老的 status,向前翻页):
//假设 messageId 是上次查询返回的 status 的最大 messageId 编号
var messageId = ...
var query = AV.Status.inboxQuery(AV.User.current());
query.maxId(messageId);
AV.Status.inboxQuery
还可以指定收件箱的类型,默认是查询 timeline 收件箱,也可以查询私信收件箱:
var query = AV.Status.inboxQuery(AV.User.current(), 'private');
查询收件箱未读状态数目
使用 AV.Status.countUnreadStatuses
可以查询某个收件箱的未读状态数目和总数目:
AV.Status.countUnreadStatuses(AV.User.current()).then(function(result){
console.dir(result);
var total = result.total;
var unread = result.unread;
}, function(err){
//查询失败
});
同样的,你可以这样查询当前登录用户未读私信的未读数目和总数目:
AV.Status.countUnreadStatuses(AV.User.current(),'private').then(function(result){
console.dir(result);
var total = result.total;
var unread = result.unread;
}, function(err){
//查询失败
});
查询发件箱
查询我发出去的状态信息,可以通过 statusQuery
方法:
var query = AV.Status.statusQuery(AV.User.current());
query.find().then(function(statuses){
//查询成功,返回状态列表,每个对象都是 AV.Object
}, function(err){
//查询失败
console.dir(err);
});
AV.Status.statusQuery
返回的是一个普通的 AV.Query 对象,本质上是查询数据管理平台的 _Status
表。你可以自主添加更多查询条件。
iOS SDK
SDK 的安装参考 Objective-C 安装指南。
状态
发布状态
发布一条时间线状态,即发一条我的粉丝可以看到的状态:
AVStatus *status=[[AVStatus alloc] init];
status.data=@{@"text":@"data type change"};
[AVUser logInWithUsername:@"travis" password:@"123456"];
[AVStatus sendStatusToFollowers:status andCallback:^(BOOL succeeded, NSError *error) {
NSLog(@"============ Send %@", [status debugDescription]);
}];
其中 status.data
可以任意指定 NSDictionary 数据。注意,这个字典中的 source 为系统保留字段,不可使用。
发私信
给某个用户发私信也非常简单:
AVStatus *status=[[AVStatus alloc] init];
status.data=@{@"text":@"this is a private message"};
NSString *userObjectId=@"XXXXXXXXXXXXX";
[AVStatus sendPrivateStatus:status toUserWithID:userObjectId andCallback:^(BOOL succeeded, NSError *error) {
NSLog(@"============ Send %@", [status debugDescription]);
}];
自定义状态
除了上面常见两种场景,自定义状态可以通过设置受众群体和发送者来实现更加灵活的功能。
AVStatus *status=[[AVStatus alloc] init];
[status setData:@{@"text":@"we have new website, take a look!",@"link":@"http://leancloud.cn"}];
status.type=@"system";
AVQuery *query=[AVUser query];
[query whereKey:@"age" equalTo:@(20)];
[status setQuery:query];
[status sendInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
}];
上面是系统广播的基本实现。因为指定了一个 AVUser 查询,所以会发送给所有 age=20
的用户,指定了 type
是 system 或者任意字符串,则所有用户会在查询这个类型的状态中看到这一条。
获取状态
下面代码会获取用户时间线上的 50 条状态:
AVStatusQuery *query=[AVStatus inboxQuery:kAVStatusTypeTimeline];
//限制50条
query.limit=50;
//限制 1397 这个 messageId 上次查询的最大 messageId,如果不设置,默认为最新的
query.maxId=1397;
//需要同时附带发送者的数据
[query includeKey:@"source"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
//获得 AVStatus 数组
}];
同理,可以获得用户的私信,只要把参数改为 kAVStatusTypePrivateMessage
。返回的 AVStatus 对象有一个 messageId 属性,用于唯一表示这条 Status 在这个 inbox 里的标示符。可以用这个 id 结合 query 做分页查询。
AVStatusQuery 可以设置 sinceId 和 maxId:
- sinceId:设定查询返回的 status 的 messageId 必须大于传入的 messageId。
- maxId:限定查询返回的 status 的 messageId 必须小于等于传入的 messageId。
使用这两个 Id 就可以做分页查询。AVStatusQuery 查询不支持 skip。
获取收件箱的未读 status 数目(从上次访问收件箱最新 status 到现在的未读 status 数目)可以使用 [AVStatus getUnreadStatusesCountWithType:andCallback]
方法。
下面的代码是某个用户发送出去的状态。查询发送出去的状态,是无法用 messageId(sinceId,maxId)
来做分片查询的。因为 messageId 只是相对于某个用户的 Inbox 才有意义, 同时返回的状态中也没有 messageId 的数据。
AVStatusQuery *query=[AVStatus statusQuery];
//设置查询某个用户,默认是查询当前用户
[query whereKey:@"source" equalTo:<AVUser>];
//限制条数
query.limit=20;
//设置消息类型
query.inboxType=kAVStatusTypeTimeline;
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
//获得 AVStatus 数组
}];
Android SDK
SDK 的安装参考 Android 安装指南。
信息流 API
假设我们要开发一个类似微博的产品,其中有用户 A 已经关注了 2 个用户(B 和 C),同时他有 3 个关注者(D、E、F)。
注意:以下示例代码基于 6.1.1 及以后版本开发。感兴趣的开发者可以参考我们的完整 demo: funny feed。
发布状态
第一步,我们来看看用户 A 如何发布一条公开的「状态」。
构造 Status
开发者在 Status 中可以加入任意的数据,由应用层来对这些数据进行解析。信息流 API 提供了多种方式来构造一个 Status 实例:
class AVStatus {
// 完全空的 Status
AVStatus()
// 默认的支持图文混合的 Status
AVStatus(String imageUrl, String message)
// 附带其他自定义属性的 Status
AVStatus(Map<String, Object> customData)
// 设置与获取自定义属性
void put(String key, Object value)
Object get(String key)
// 删除某个自定义属性
void remove(String key)
}
使用方法在类的声明中应该可以一目了然。假如用户 A 想分享一下他中午吃的美食,那么可以按照如下方法来构造一条状态信息:
AVStatus status = new AVStatus("https://ww4.sinaimg.cn/bmiddle/691c275bgy1g9cdxpw3f4j21hc1hc4qq.jpg", "北京烤鸭,贼拉好吃");
status.put("location", "铁岭市赵大胡同");
这一条 Status 如果以公开的方式发送出去,所有关注 A 的用户都会看到这条信息。如果 A 只想发送给用户 D ,他可以选择私信的方式来发送,那就只有用户 D 可以查看到了(这两种方式下一节会说明)。
AVStatus 类中有如下属性被系统保留了:
- inboxType,String,表示发布时指定的访问类型,目前有
private
和default
两种类型。private
表示是私信,不会公开显示;default
表示是公开信息,会进入到关注者的时间线;- 默认值为
default
; - 开发者可以在应用层面扩展这个 inboxType。例如,微博上就有「系统通知」这一类消息,我们可以增加一种「notification」的 inboxType,来实现这一类消息的收发展示。
- source,Pointer,指向状态发布者(AVUser)的指针
- messageId,Integer,LeanCloud 服务端在将状态插入目标用户的接收队列时,生成的一个序列号,主要用于状态流的分页遍历(这在后面会说明)。
- updatedAt, createdAt, objectId,这些 AVObject 通用属性。
这些属性都可以通过 getter/setter 方法进行访问。
发送 Status
我们提供了三种方式来发送 Status:
class Status {
public Observable<AVStatus> sendToFollowersInBackground();
public Observable<AVStatus> sendToFollowersInBackground(String inboxType);
public Observable<AVStatus> sendToUsersInBackground(AVQuery query);
public Observable<AVStatus> sendToUsersInBackground(String inboxType, AVQuery query);
public Observable<AVStatus> sendPrivatelyInBackground(final String receiverObjectId);
}
分别对应不同的使用场景:
- 直接发布给用户自己的关注者(
sendToFollowersInBackground()
)。
这是最常见的方式,用户 A 完成 Status 的构造之后,直接就公开发布出去。这条 Status 就会自动进入关注 ta 的用户的时间线。
另外,考虑到应用层对 inboxType 扩展的需要,我们还提供了一个指定 inboxType 的公开发布 Status 的方法:sendToFollowersInBackground(String inboxType)
,供开发者按需选择使用。
- 选择性的发布给某些用户(
sendToUsersInBackground(AVQuery query)
)。
用户 A 可能会有这样的需求,希望自己发布的 Status 只被一部分好友看到,这时候就可以在发布 Status 的时候,指定一个 AVQuery 实例来圈定目标用户。这是一种比较高阶的做法,具体细节后面会进行详细说明。
- 以私信的形式单独发送给某个用户(
sendPrivatelyInBackground(final String receiverObjectId)
)。
这也是比较常见的需求,某条 Status 只定向发送给某个好友,这时候默认就转变成了「私信」。
我们还是回头来看用户 A 发送美食帖子的实现方法。假设 A 就是公开发布给所有的关注者,那么只需要一次调用就可以完成目的:
status.sendToFollowersInBackground()
.subscribe(new Observer<AVStatus>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(AVStatus avNull) {
// succeed
}
@Override
public void onError(Throwable throwable) {
// failed
throwable.printStackTrace();
}
@Override
public void onComplete() {
}
});
当然,这里有一个前提是用户 A 已经完成了登录,就是 AVUser.currentUser
必须存在且是登录状态,否则发送会失败。
查看 Status
用户 A 发布了状态之后,关注 ta 的用户 D 该如何查看这些信息呢?我们提供了多种方法,可以来查询和展示 Status。
查看自己的时间线
假设用户 D 要查看自己的时间线,他首先需要登录,然后可以调用如下方法来查询自己的时间线状态:
AVUser userD = AVUser.currentUser();
String defaultInbox = AVStatus.INBOX_TYPE.TIMELINE.toString(); // "default"
AVStatusQuery statusQuery = AVStatus.inboxQuery(userD, defaultInbox);
statusQuery.findInBackground().subscribe(new Observer<List<AVStatus>>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(List<AVStatus> avStatuses) {
// succeed
// 这时候每一个 AVStatus 实例都会有 source,messageId,objectId,createdAt,inboxType 等预留属性,也会有开发者自定义设置的所有属性值。
}
@Override
public void onError(Throwable throwable) {
// failed.
throwable.printStackTrace();
}
@Override
public void onComplete() {
}
});
查看私信
用户 D 要查看自己的私信列表,其方法与查看时间线类似,只需要把 inboxType 变为 AVStatus.INBOX_TYPE.PRIVATE
即可,示例代码如下:
AVUser userD = AVUser.currentUser();
String inboxType = AVStatus.INBOX_TYPE.PRIVATE.toString(); // "private"
AVStatusQuery statusQuery = AVStatus.inboxQuery(userD, inboxType);
statusQuery.findInBackground().blockingLast();
查看单个用户的公开 Status
查询时间线和私信都需要当前用户是登录状态,且只能查询当前登录用户能接收到状态流。有时候我们产品里还需要展示单个用户发布的所有公开状态,例如微博的个人主页上会展示 ta 发布的所有帖子。
要查看目标用户的公开 Status,并不要求该用户当前是登录状态,我们只需要知道目标用户的 objectId(AVUser 的基本属性之一) 就可以查看 ta 的公开状态了。
示例代码如下:
AVUser targetUser = AVObject.createWithoutData(AVUser.class, targetUserObjectId);
AVStatus.statusQuery(targetUser)
.findInBackground()
.subscribe(new Observer<List<AVStatus>>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(List<AVStatus> avStatuses) {
// succeed
// 这时候每一个 AVStatus 实例都会有 source,messageId,objectId,createdAt,inboxType
// 等预留属性,也会有开发者自定义设置的所有属性值。
}
@Override
public void onError(Throwable throwable) {
// failed
throwable.printStackTrace();
}
@Override
public void onComplete() {
}
});
Status 的分页展示
从上面的示例代码可以看到,我们可以通过 StatusQuery 实例来完成多种 Status 数据查询,查询结果里所有 Status 实例按照发布时间从新到旧的顺序进行排列。不过如果 Status 数据量较大,无法一次查询(默认 100 条)获取全部数据,这时候就需要进行分页查询,我们该如何做呢?
StatusQuery 还提供了分页获取结果的方法:nextInBackground
,它可以在当前查询的基础上,继续往后获取结果数据。例如,用户 D 使用前述的接口获取了头 100 条结果之后,要继续拉取时间线数据,可以这样做:
// AVStatusQuery statusQuery = AVStatus.inboxQuery(userD, defaultInbox);
statusQuery.nextInBackground().subscribe(new Observer<List<AVStatus>>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(List<AVStatus> avStatuses) {
// succeed
// 这时候每一个 AVStatus 实例都会有 source,messageId,objectId,createdAt,inboxType 等预留属性,也会有开发者自定义设置的所有属性值。
}
@Override
public void onError(Throwable throwable) {
// failed.
throwable.printStackTrace();
}
@Override
public void onComplete() {
}
});
nextInBackground()
可以一直调用,直到没有新的结果返回为止。
分页查询的其他参数设置
StatusQuery 默认都是按照从新到旧的顺序来查询结果,并且每次查询默认的结果集大小为 100。实际上,StatusQuery 还允许开发者来设置多种查询参数,如:
- 查询方向。可以通过
setDirection(PaginationDirection direct)
方法来设置是从新往旧查询(最近发布的 Status 会最先返回),还是从旧到新查询 Status 数据(最早发布的 Status 会最先返回)。 - 分页大小。可以通过
setPageSize(int pageSize)
方法来设置分页的大小,允许的页面大小区间为 (0,1000)(不包含两个端点)。 - 查询的起点和终点。在对时间线进行分页查询的时候,还允许开发者设置查询起点和终点 Status 的 MessageId(查询结果中不会包含两个端点的数据)。
setSinceId(long sinceId)
用来设置结果集中最小的 messageId,返回的所有 Status 的 messageId 都会比 sinceId 大。setMaxId(long maxId)
用来设置结果集中最大的 messageId,返回的所有 Status 的 messageId 都会比 maxId 小。
如果用户 D 需要按照从旧到新的顺序浏览时间线 Status,并且每次只希望看 20 条数据,那么可以这样实现:
AVUser userD = AVUser.currentUser();
String defaultInbox = AVStatus.INBOX_TYPE.TIMELINE.toString(); // "default"
AVStatusQuery statusQuery = AVStatus.inboxQuery(userD, defaultInbox);
statusQuery.setPageSize(20);
statusQuery.setDirection(PaginationDirection.OLD_TO_NEW);
List<AVStatus> first20Statuses = statusQuery.findInBackground().blockingLast();
List<AVStatus> second20Statuses = statusQuery.nextInBackground().blockingLast();
状态流的计数信息
与 Query 类似,StatusQuery 提供以下方法:
Observable<Integer> countInBackground()
来查询符合条件的 Status 数量,这可以用来查询单个用户的公开 Status 总数。
对于时间线的计数,就不能使用上面的方法了。对于时间线中 Status 的计数信息,因为后端的查询方式不一样,同时也由于产品层对查询结果的要求不一样(需要返回总数和未读数两个维度的统计信息),StatusQuery 提供了新的方法来查询计数信息:
Observable<JSONObject> unreadCountInBackground()
该函数的返回值是一个 JSONObject,包含 total
和 unread
两个计数值。
例如,用户 D 要查看自己收到的私信的计数信息,可以按照如下办法来查询:
AVUser userD = AVUser.currentUser();
AVStatus.inboxQuery(userD, AVStatus.INBOX_TYPE.PRIVATE.toString())
.unreadCountInBackground()
.subscribe(new Observer<JSONObject>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(JSONObject jsonObject) {
// succeed.
}
@Override
public void onError(Throwable throwable) {
// failed.
}
@Override
public void onComplete() {
}
});
要展示用户 A 发布的状态总数,可以按照如下办法来查询:
AVUser targetUser = AVObject.createWithoutData(AVUser.class, userAObjectId);
AVStatus.statusQuery(targetUser)
.countInBackground()
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(Integer integer) {
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
}
});
删除 Status
我们提供删除 Status 的接口,但是只在以下条件满足的时候调用才会成功:
- 当前用户必须是登录状态。
- 当前登录用户可以删除自己发布的 Status,此时 Status 会从源头上被删除,当前用户的关注者时间线上就不会再出现这条 Status。
- 当前登录用户可以删除自己时间线上他人发布的 Status,此时 Status 不会从源头上被删除,其他关注者在自己的时间线上依然可以看到这条 Status。
Status 的删除接口如下:
Observable<AVNull> deleteInBackground();
删除自己发布的 Status
假设用户 A 发出那条美食的帖子之后,觉得图片不够精美,想删除它,那么在客户端可以这样执行删除:
// AVStatus target = ...;
target.deleteInBackground()
.subscribe(new Observer<AVNull>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(AVNull v) {
// succeed
}
@Override
public void onError(Throwable throwable) {
// failed
}
@Override
public void onComplete() {
}
})
屏蔽别人发布的 Status
假设用户 A 发出那条美食的帖子之后,ta 自己没有删除,但是 ta 的关注者 D 在时间线上看到之后,想屏蔽这一条 Status,那么在客户端可以这样执行删除:
// AVStatus target = ...;
target.deleteInBackground()
.subscribe(new Observer<AVNull>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(AVNull v) {
// succeed
}
@Override
public void onError(Throwable throwable) {
// failed
}
@Override
public void onComplete() {
}
})
可以看到,Status 的删除方式都是一样的,区别只在于当前登录用户是否拥有所有权:
- 如果是当前用户自己发布的 Status,会从源头上进行删除;
- 如果只是存在于当前用户的时间线上,则只会从当前用户的时间线上进行删除;
- 其他情况下,当前用户无权进行删除操作,调用会报错;
REST API
再次解释下术语定义:
- status:一条状态,包含两个预定义属性
messageId
和inboxType
,其他属性都可自定义。 - target:状态的目标接收者,也就是 inbox 的 owner。
- inbox:target 的收件箱,有 owner(所有者)和 inboxType(收件箱类型)两个属性。
发布 Status API
调用 API 如下:
POST /statuses
接受的 JSON 对象参数:
属性 | 说明 |
---|---|
query | 查询 target 的条件,包括下列属性:
|
data | status 的 数据 JSON 对象,用户自定义。如果包含 source(指向发送者的 Pointer),并且 inboxType 设为 default,该 status 会同时往发送者的 inbox 投递。 |
inboxType | 字符串,指定接收这条 status 的 inbox 类型,可为空,默认为 default 。 |
【示例一】往 dennis 的粉丝群体发送一条状态:
curl -X POST \
-H "X-LC-Id: {{appid}}" \
-H "X-LC-Key: {{appkey}}" \
-H "Content-Type: application/json" \
-d '{
"data": {
"image": "paas-files.qiniudn.comwQUf3WohbJpyuXutPjKHPmkSj4gbiYMeNJmTulNo.jpg",
"message": "AVOS Cloud is great!"
},
"inboxType": "default",
"query": {
"className": "_Follower",
"keys": "follower",
"where": {
"user": {
"__type": "Pointer",
"className": "_User",
"objectId": "dennis'id"
}
}
}
}' \
https://{{host}}/1.1/statuses
这条状态的内容是 data 指定的,并且设定 inboxType 是 default
:
{
"image": "paas-files.qiniudn.comwQUf3WohbJpyuXutPjKHPmkSj4gbiYMeNJmTulNo.jpg",
"message": "LeanCloud is great!"
}
这条状态的目标用户群体是 query 指定的查询条件,查询的是 _Follower
表中 dennis 的粉丝用户。
【示例二】dennis 向 catty 发送私信的请求类似:
{
"data": {
"message": "hello catty!"
},
"inboxType": "private",
"query": {
"className": "_User",
"where": {
"objectId": "catty's id"
}
}
}
查询发出的状态 API
GET /statuses
跟查询其他对象一样。知道 objectId,查询单条状态:
GET /statuses/:status_id
删除状态 API
DELETE /statuses/:status_id
查询已经关注的用户的状态聚合列表 API
查询我关注的用户发出来的状态聚合而成的列表,也就是查询自己的收件箱,通过:
GET /subscribe/statuses
接收参数(参数都必须要 URL encoded):
参数 | 说明 |
---|---|
owner | JSON 序列化后的 owner 字符串,表示 inbox 所有者。 |
inboxType | inbox 的类型,默认为 default ,可为空。 |
where | 用于过滤 status 的 where 条件,也是 JSON 序列化后的字符串。 |
sinceId | 查询返回的 status 的 messageId 必须大于 sinceId,默认为 0。 |
maxId | 查询返回的 status 的 messageId 必须小于等于 maxId,默认为 0。 |
limit | 最多返回多少条 status,默认 100,最大 100。 |
count | 默认为空,设置为 "1" 表示在结果中带上 status 的 count 计数。 |
【示例一】查询我的主页 timeline:
curl -X GET \
-H "X-LC-Id: {{appid}}" \
-H "X-LC-Key: {{appkey}}" \
-H "Content-Type: application/json" \
-G \
--data-urlencode 'owner={"__type":"Pointer","className":"_User","objectId":"51c3ba67e4b0f0e851c16221"}' \
https://{{host}}/1.1/subscribe/statuses
【示例二】查询我的最新私信列表:
--data-urlencode 'owner={"__type":"Pointer","className":"_User","objectId":"51c3ba67e4b0f0e851c16221"}' \
--data-urlencode 'inboxType=private'
【示例三】假设上次返回的最大 messageId 是 99,查询从 mesageId = 99 开始最新的 status:
--data-urlencode 'owner={"__type":"Pointer", "className":"_User","objectId":"51c3ba67e4b0f0e851c16221"}' \
--data-urlencode 'sinceId=99'
【示例四】查询 messageId 在 99 到 199 之间的 status:
--data-urlencode 'owner={"__type":"Pointer","className":"_User","objectId":"51c3ba67e4b0f0e851c16221"}' \
--data-urlencode 'sinceId=99' \
--data-urlencode 'maxId=199'
【示例五】查询最新的 status,并且 status 的 image 属性存在,也就是查询包含图片的最新 status:
--data-urlencode 'owner={"__type":"Pointer","className":"_User","objectId":"51c3ba67e4b0f0e851c16221"}' \
--data-urlencode 'where={"image":{"$exists":true }}'
删除收件箱里的消息
可以根据 messageId 来删除收件箱的消息:
curl -X DELETE \
-H "X-LC-Id: {{appid}}" \
-H "X-LC-Key: {{appkey}}" \
-H "Content-Type: application/json" \
-G \
--data-urlencode 'owner={"__type":"Pointer","className":"_User","objectId":"51c3ba67e4b0f0e851c16221"}' \
--data-urlencode 'inboxType=default' \
--data-urlencode 'messageId=99' \
https://{{host}}/1.1/subscribe/statuses/inbox
参数 | 说明 |
---|---|
owner | JSON 序列化后的 owner 字符串,表示 inbox 所有者。 |
inboxType | inbox 的类型,默认为 default ,可为空。 |
messageId | 想要删除的 status 的 messageId |
查询状态计数 API
查询 inbox 总消息数目和未读消息数目:
GET "/subscribe/statuses/count
可指定的条件:
- owner:JSON 序列化后的 owner 字符串,表示 inbox 所有者。
- inboxType:inbox 类型,默认为
default
,可为空。
【示例一】查询我的未读消息数目:
curl -X GET \
-H "X-LC-Id: {{appid}}" \
-H "X-LC-Key: {{appkey}}" \
-H "Content-Type: application/json" \
-G \
--data-urlencode 'owner={"__type":"Pointer","className":"_User","objectId":"51c3ba67e4b0f0e851c16221"}' \
https://{{host}}/1.1/subscribe/statuses/count
返回:
{ "total": 100, "unread":20}
【示例二】查询私信消息数目:
curl -X GET \
-H "X-LC-Id: {{appid}}" \
-H "X-LC-Key: {{appkey}}" \
-H "Content-Type: application/json" \
-G \
--data-urlencode 'owner={"__type":"Pointer","className":"_User","objectId":"51c3ba67e4b0f0e851c16221"}' \
--data-urlencode 'inboxType=private' \
https://{{host}}/1.1/subscribe/statuses/count
重置未读消息数
如果想将某个收件箱的未读消息数设置为 0,也就是通常看到的将全部消息设为「已读」的功能,可以通过 resetUnreadCount
API 来实现:
curl -X POST \
-H "X-LC-Id: {{appid}}" \
-H "X-LC-Key: {{appkey}}" \
-H "Content-Type: application/json" \
-G \
--data-urlencode 'owner={"__type":"Pointer","className":"_User","objectId":"51c3ba67e4b0f0e851c16221"}' \
--data-urlencode 'inboxType=private' \
https://{{host}}/1.1/subscribe/statuses/resetUnreadCount
接收的参数与 查询状态计数 API 是一致的。