rong_cloud_server 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/README.md +41 -0
- data/config.example.yml +3 -0
- data/lib/rong_cloud/configuration.rb +30 -0
- data/lib/rong_cloud/errors.rb +39 -0
- data/lib/rong_cloud/request.rb +69 -0
- data/lib/rong_cloud/service.rb +17 -0
- data/lib/rong_cloud/services/group.rb +73 -0
- data/lib/rong_cloud/services/message/message_channel.rb +45 -0
- data/lib/rong_cloud/services/message.rb +58 -0
- data/lib/rong_cloud/services/user.rb +70 -0
- data/lib/rong_cloud/services/wordfilter.rb +26 -0
- data/lib/rong_cloud/signature.rb +39 -0
- data/lib/rong_cloud.rb +12 -0
- data/rong_cloud.gemspec +13 -0
- data/run_tests.sh +1 -0
- data/test/rong_cloud/configuration_test.rb +33 -0
- data/test/rong_cloud/request_test.rb +56 -0
- data/test/rong_cloud/service_test.rb +19 -0
- data/test/rong_cloud/services/group_test.rb +102 -0
- data/test/rong_cloud/services/message/message_channel_test.rb +82 -0
- data/test/rong_cloud/services/message_test.rb +83 -0
- data/test/rong_cloud/services/user_test.rb +144 -0
- data/test/rong_cloud/services/wordfilter_test.rb +30 -0
- data/test/rong_cloud/signature_test.rb +39 -0
- data/test/rong_cloud_test.rb +15 -0
- data/test/test_helper.rb +14 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c0a792a26e83b1a5420aa834459d44f62be0ec8c
|
4
|
+
data.tar.gz: 50b3157736cff25fa9937cd99a002d7fa5a62134
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9a77797344c9ad396fc0f8b8586d68c061944abac3932cac51445470c2f21d28d4e9544a4ec8524bf21899d2c50a24703b51005ac3b8257b7edf4bf61fdd1ad1
|
7
|
+
data.tar.gz: 72ae4a709051e62499d409c103feb9c106e6f4d1f49b4cbd30cde0f506c3f8ee4d10c4cde46b9495e9f9fe89386ecd99be40e1372b15d1d29c7c45e678cf88fa
|
data/.gitignore
ADDED
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
融云 Server SDK
|
2
|
+
===
|
3
|
+
|
4
|
+
此 gem 实现了[融云 Server API](http://www.rongcloud.cn/docs/server.html)的大部分接口的 Ruby 实现。
|
5
|
+
|
6
|
+
### Getting Started
|
7
|
+
1. 安装此 gem;
|
8
|
+
2. 在项目中添加配置:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
RongCloud.configure do |config|
|
12
|
+
config.app_key = "APP_KEY"
|
13
|
+
config.secret_key = "SECRET_KEY"
|
14
|
+
config.host = "http://api.cn.ronghub.com" # default: https://api.cn.ronghub.com, use http is convenient for debugging
|
15
|
+
end
|
16
|
+
```
|
17
|
+
3. 通过 service 对象使用:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
service = RongCloud::Service.new
|
21
|
+
|
22
|
+
# 更多方法,请查看测试用例 https://github.com/Martin91/rong_cloud/tree/master/test/rong_cloud/services
|
23
|
+
service.get_token(..., ..., ...)
|
24
|
+
```
|
25
|
+
|
26
|
+
### 特点
|
27
|
+
1. **轻量**:无其他依赖;
|
28
|
+
2. **简洁**:不过分封装,仅做必要的请求实现,使用方自行处理响应的 JSON 解析后的 Hash 对象,各字段释义请自行查阅融云文档;
|
29
|
+
3. **丰富的异常类型**:针对不同的 HTTP 状态码,抛出相对应的异常类型,同时可以通过异常对象的 `business_code` 方法获取错误业务码,可以参考[request test 的代码](https://github.com/Martin91/rong_cloud/blob/master/test/rong_cloud/request_test.rb)。
|
30
|
+
|
31
|
+
### TODOs
|
32
|
+
1. 私聊与系统模板消息;
|
33
|
+
2. 聊天室其他服务以及高级接口实现;
|
34
|
+
3. 实时消息路由;
|
35
|
+
4. 消息历史记录;
|
36
|
+
5. 在线状态订阅。
|
37
|
+
|
38
|
+
### How to contribute
|
39
|
+
1. Fork this repo;
|
40
|
+
2. Write your code and test;
|
41
|
+
3. Open a new Pull Request.
|
data/config.example.yml
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "logger"
|
2
|
+
|
3
|
+
module RongCloud
|
4
|
+
# 管理融云 SDK 连接配置信息
|
5
|
+
#
|
6
|
+
module Configuration
|
7
|
+
# 默认 API 服务器,使用 https
|
8
|
+
DEFAULT_HOST = "https://api.cn.ronghub.com".freeze
|
9
|
+
|
10
|
+
module ModuleMethods
|
11
|
+
attr_accessor :app_key, :app_secret, :host, :logger
|
12
|
+
|
13
|
+
# 获取目标主机,默认为 https://api.cn.ronghub.com
|
14
|
+
#
|
15
|
+
def host
|
16
|
+
@host || DEFAULT_HOST
|
17
|
+
end
|
18
|
+
|
19
|
+
# 获取日志文件对象,默认日志文件为标准输出
|
20
|
+
def logger
|
21
|
+
@logger || default_logger
|
22
|
+
end
|
23
|
+
|
24
|
+
def default_logger
|
25
|
+
@default_logger ||= ::Logger.new(STDOUT)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
extend ModuleMethods
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module RongCloud
|
2
|
+
# 不支持的消息类型错误
|
3
|
+
class UnsupportedMessageChannelName < ::StandardError;end
|
4
|
+
# 与融云接口请求相关的基本错误类型,其他错误类型继承此类型
|
5
|
+
class RequestError < ::StandardError
|
6
|
+
# @!attribute [rw] business_code
|
7
|
+
# 接口错误时的业务返回码,详见:http://www.rongcloud.cn/docs/server.html#API_方法返回值说明
|
8
|
+
attr_accessor :business_code
|
9
|
+
end
|
10
|
+
|
11
|
+
# 错误请求
|
12
|
+
class BadRequest < RequestError;end
|
13
|
+
# 验证错误
|
14
|
+
class AuthenticationFailed < RequestError;end
|
15
|
+
# 被拒绝
|
16
|
+
class RequestForbidden < RequestError;end
|
17
|
+
# 资源不存在
|
18
|
+
class ResourceNotFound < RequestError;end
|
19
|
+
# 群上限
|
20
|
+
class ExceedLimit < RequestError;end
|
21
|
+
# 过多的请求
|
22
|
+
class TooManyRequests < RequestError;end
|
23
|
+
# 内部服务器错误
|
24
|
+
class InternalServerError < RequestError;end
|
25
|
+
# 内部服务器响应超时
|
26
|
+
class Timeout < RequestError;end
|
27
|
+
|
28
|
+
# 融云服务器响应状态码到 Ruby 错误类型的映射
|
29
|
+
HTTP_CODE_TO_ERRORS_MAP = {
|
30
|
+
"400" => BadRequest,
|
31
|
+
"401" => AuthenticationFailed,
|
32
|
+
"403" => RequestForbidden,
|
33
|
+
"404" => ResourceNotFound,
|
34
|
+
"405" => ExceedLimit,
|
35
|
+
"429" => TooManyRequests,
|
36
|
+
"500" => InternalServerError,
|
37
|
+
"504" => Timeout
|
38
|
+
}.freeze
|
39
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
require 'rong_cloud/signature'
|
4
|
+
|
5
|
+
module RongCloud
|
6
|
+
# 请求封装类,所有请求基于 Net::HTTP,自动支持 http 或者 https
|
7
|
+
#
|
8
|
+
module Request
|
9
|
+
include Signature
|
10
|
+
|
11
|
+
# 拼接请求的接口的路径
|
12
|
+
#
|
13
|
+
# @param path [String] 接口的相对路径,e.g. "/user/getToken" 或者 "user/getToken",代码中自动处理开头的斜杠
|
14
|
+
# @return [URI] 请求全路径生成的 URI 对象,自动追加 .json 格式扩展名
|
15
|
+
#
|
16
|
+
def get_uri(path)
|
17
|
+
url = "#{RongCloud::Configuration.host}/#{path.gsub(/^\//, "")}"
|
18
|
+
URI(url.end_with?(".json") ? url : "#{url}.json")
|
19
|
+
end
|
20
|
+
|
21
|
+
# 实例化请求对象
|
22
|
+
#
|
23
|
+
# @param uri [URI] 请求路径对象
|
24
|
+
# @param params [Hash] 请求的参数,所有参数通过 form encoded data 方式发送
|
25
|
+
# @return [Net::HTTP::Post] 请求的实例
|
26
|
+
#
|
27
|
+
def initialize_request(uri, params)
|
28
|
+
req = Net::HTTP::Post.new(uri)
|
29
|
+
req.set_form_data(params) if params.respond_to?(:map)
|
30
|
+
signed_headers.each { |header, value| req[header] = value }
|
31
|
+
|
32
|
+
req
|
33
|
+
end
|
34
|
+
|
35
|
+
# 解析响应数据,包含错误检测
|
36
|
+
#
|
37
|
+
# @param res [HTTPResponse] 响应结果的实例
|
38
|
+
# @return [Hash] JSON 解析后的响应正文
|
39
|
+
# @raise [RongCloud::BadRequest] 请求参数有误,缺失或者不正确等,详见官方文档
|
40
|
+
#
|
41
|
+
def handle_response(res)
|
42
|
+
json = JSON.parse(res.body)
|
43
|
+
case res
|
44
|
+
when Net::HTTPOK
|
45
|
+
json
|
46
|
+
else
|
47
|
+
error = (HTTP_CODE_TO_ERRORS_MAP[res.code] || RequestError).new(json["errorMessage"])
|
48
|
+
error.business_code = json["code"]
|
49
|
+
raise error
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# 执行请求
|
54
|
+
# @param path [String] 请求 API 的相对路径
|
55
|
+
# @param params [Hash] 请求的参数
|
56
|
+
# @return [Hash] JSON 解析后的响应数据
|
57
|
+
# @raise [RongCloud::BadRequest] 请求参数有误,缺失或者不正确等,详见官方文档
|
58
|
+
def request(path, params = nil)
|
59
|
+
uri = get_uri(path)
|
60
|
+
req = initialize_request(uri, params)
|
61
|
+
use_ssl = uri.scheme == 'https'
|
62
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: use_ssl) do |http|
|
63
|
+
http.request(req)
|
64
|
+
end
|
65
|
+
|
66
|
+
handle_response(res)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rong_cloud/request'
|
2
|
+
require 'rong_cloud/services/user'
|
3
|
+
require 'rong_cloud/services/message'
|
4
|
+
require 'rong_cloud/services/wordfilter'
|
5
|
+
require 'rong_cloud/services/group'
|
6
|
+
|
7
|
+
module RongCloud
|
8
|
+
# 封装所有接口的 Service 类,所有业务接口通过 Service 的实例完成调用
|
9
|
+
#
|
10
|
+
class Service
|
11
|
+
include RongCloud::Request
|
12
|
+
include RongCloud::Services::User
|
13
|
+
include RongCloud::Services::Message
|
14
|
+
include RongCloud::Services::Wordfilter
|
15
|
+
include RongCloud::Services::Group
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module RongCloud
|
2
|
+
module Services
|
3
|
+
# 群组服务相关接口 http://www.rongcloud.cn/docs/server.html#群组服务
|
4
|
+
module Group
|
5
|
+
# 同步用户所属群组
|
6
|
+
#
|
7
|
+
# @param user_id [String] 用户在融云的 id
|
8
|
+
# @param groups [Hash] 用户需要同步的群组信息,以群组 id 为键,以群组名称为值
|
9
|
+
#
|
10
|
+
def sync_group(user_id, groups)
|
11
|
+
params = {userId: user_id}
|
12
|
+
groups.each do |id, name|
|
13
|
+
params["group[#{id}]"] = name
|
14
|
+
end
|
15
|
+
|
16
|
+
request("/group/sync", params)
|
17
|
+
end
|
18
|
+
|
19
|
+
# 创建群组
|
20
|
+
#
|
21
|
+
def create_group(user_id, group_id, group_name)
|
22
|
+
request("/group/create", userId: user_id, groupId: group_id, groupName: group_name)
|
23
|
+
end
|
24
|
+
|
25
|
+
# 加入群组
|
26
|
+
#
|
27
|
+
def join_group(user_id, group_id, group_name)
|
28
|
+
request("/group/join", userId: user_id, groupId: group_id, groupName: group_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
# 退出群组
|
32
|
+
#
|
33
|
+
def quit_group(user_id, group_id)
|
34
|
+
request("/group/quit", userId: user_id, groupId: group_id)
|
35
|
+
end
|
36
|
+
|
37
|
+
# 解散群组
|
38
|
+
#
|
39
|
+
def dismiss_group(user_id, group_id)
|
40
|
+
request("/group/dismiss", userId: user_id, groupId: group_id)
|
41
|
+
end
|
42
|
+
|
43
|
+
# 刷新群组信息
|
44
|
+
def refresh_group(group_id, group_name)
|
45
|
+
request("/group/refresh", groupId: group_id, groupName: group_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
# 查询群成员
|
49
|
+
#
|
50
|
+
def group_members(group_id)
|
51
|
+
request("/group/user/query", groupId: group_id)
|
52
|
+
end
|
53
|
+
|
54
|
+
# 添加禁言群成员
|
55
|
+
#
|
56
|
+
def block_group_member(user_id, group_id, minute)
|
57
|
+
request("/group/user/gag/add", userId: user_id, groupId: group_id, minute: minute)
|
58
|
+
end
|
59
|
+
|
60
|
+
# 移除禁言群成员
|
61
|
+
#
|
62
|
+
def unblock_group_member(user_id, group_id)
|
63
|
+
request("/group/user/gag/rollback", userId: user_id, groupId: group_id)
|
64
|
+
end
|
65
|
+
|
66
|
+
# 查询被禁言群成员
|
67
|
+
#
|
68
|
+
def blocked_group_members(group_id)
|
69
|
+
request("/group/user/gag/list", groupId: group_id)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module RongCloud
|
2
|
+
module Services
|
3
|
+
module Message
|
4
|
+
# 消息发送渠道,区分私信、系统消息、群组消息、讨论组消息、聊天室消息以及广播消息
|
5
|
+
class MessageChannel
|
6
|
+
# 各消息渠道各自对应请求路径以及特殊参数名
|
7
|
+
#
|
8
|
+
CHANNEL_TO_REQUEST_DETAILS_MAP = {
|
9
|
+
'private': { target_param_name: "toUserId", api_path: "/message/private/publish" },
|
10
|
+
system: { target_param_name: "toUserId", api_path: "/message/system/publish" },
|
11
|
+
group: { target_param_name: 'toGroupId', api_path: "/message/group/publish" },
|
12
|
+
discussion: { target_param_name: "toDiscussionId", api_path: "/message/discussion/publish" },
|
13
|
+
chatroom: { target_param_name: "toChatroomId", api_path: "/message/chatroom/publish" },
|
14
|
+
broadcast: { api_path: "/message/broadcast" }
|
15
|
+
}.freeze
|
16
|
+
# 支持的消息渠道的列表
|
17
|
+
#
|
18
|
+
VALID_CHANNEL_NAMES = CHANNEL_TO_REQUEST_DETAILS_MAP.keys.map(&:to_s).freeze
|
19
|
+
|
20
|
+
# 实例化消息渠道对象
|
21
|
+
#
|
22
|
+
# @param channel_name [String] 渠道名称
|
23
|
+
# @return [RongCloud::Services::Message::MessageChannel] 消息渠道实例
|
24
|
+
# @raise [RongCloud::UnsupportedMessageChannelName] 消息渠道不支持
|
25
|
+
#
|
26
|
+
def initialize(channel_name)
|
27
|
+
if VALID_CHANNEL_NAMES.include?(channel_name.to_s)
|
28
|
+
@channel_name = channel_name.to_s.to_sym
|
29
|
+
else
|
30
|
+
raise UnsupportedMessageChannelName,
|
31
|
+
"support only channels: #{VALID_CHANNEL_NAMES}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def target_param_name
|
36
|
+
CHANNEL_TO_REQUEST_DETAILS_MAP[@channel_name][:target_param_name]
|
37
|
+
end
|
38
|
+
|
39
|
+
def api_path
|
40
|
+
CHANNEL_TO_REQUEST_DETAILS_MAP[@channel_name][:api_path]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rong_cloud/services/message/message_channel'
|
2
|
+
|
3
|
+
module RongCloud
|
4
|
+
module Services
|
5
|
+
# 消息发送相关接口 http://www.rongcloud.cn/docs/server.html#消息发送服务
|
6
|
+
module Message
|
7
|
+
# 通用的发送消息方法
|
8
|
+
# @param from_user_id [String] 消息发起人 id
|
9
|
+
# @param target_id [String, Integer] 消息接收方,用户 id、群组 id、讨论组 id、聊天室 id 等
|
10
|
+
# @param channel_name [String] 消息通道,表示单聊、系统、群组、讨论组、聊天室或者广播消息
|
11
|
+
# @param object_name [String] 消息类型名称,内置消息类型或者自定义消息类型名称
|
12
|
+
# @param [Hash] content 消息体,更多消息请看 http://www.rongcloud.cn/docs/server.html#内置消息类型表
|
13
|
+
# @option content [Object] :content 消息体中的正文,如果为自定义消息,由消息消费方自行解析
|
14
|
+
# @option content [Object] :extra 消息体中的附加信息,传递时为字符串,由消息消费方自行解析
|
15
|
+
#
|
16
|
+
# @param [Hash] options 额外选项,包含 pushContent 以及 pushData 等配置,所有支持选项根据各消息类型确定
|
17
|
+
# @option options [String] :pushContent 推送通知显示的 Push 内容
|
18
|
+
# @option options [Hash] :pushData 推送 payload
|
19
|
+
#
|
20
|
+
def send_message(from_user_id, target_id, channel_name, object_name, content, options = {})
|
21
|
+
message_channel = MessageChannel.new(channel_name)
|
22
|
+
params = { fromUserId: from_user_id, objectName: object_name, content: content.to_json }
|
23
|
+
if message_channel.target_param_name
|
24
|
+
params.merge!(message_channel.target_param_name => target_id)
|
25
|
+
end
|
26
|
+
|
27
|
+
params.merge!(options)
|
28
|
+
request(message_channel.api_path, params)
|
29
|
+
end
|
30
|
+
|
31
|
+
# 发送单聊消息 http://www.rongcloud.cn/docs/server.html#发送单聊消息_方法
|
32
|
+
#
|
33
|
+
def send_private_message(from_user_id, to_user_id, object_name, content, options = {})
|
34
|
+
send_message(from_user_id, to_user_id, :private, object_name, content, options)
|
35
|
+
end
|
36
|
+
|
37
|
+
# 发送系统消息 http://www.rongcloud.cn/docs/server.html#发送系统消息_方法
|
38
|
+
def send_system_message(from_user_id, to_user_id, object_name, content, options = {})
|
39
|
+
send_message(from_user_id, to_user_id, :system, object_name, content, options)
|
40
|
+
end
|
41
|
+
|
42
|
+
# 发送群组消息 http://www.rongcloud.cn/docs/server.html#发送群组消息_方法
|
43
|
+
def send_group_message(from_user_id, to_group_id, object_name, content, options = {})
|
44
|
+
send_message(from_user_id, to_group_id, :group, object_name, content, options)
|
45
|
+
end
|
46
|
+
|
47
|
+
# 发送讨论组消息 http://www.rongcloud.cn/docs/server.html#发送讨论组消息_方法
|
48
|
+
def send_discussion_message(from_user_id, to_discussion_id, object_name, content, options = {})
|
49
|
+
send_message(from_user_id, to_discussion_id, :discussion, object_name, content, options)
|
50
|
+
end
|
51
|
+
|
52
|
+
# 发送广播消息 http://www.rongcloud.cn/docs/server.html#发送广播消息_方法
|
53
|
+
def send_broadcast_message(from_user_id, object_name, content, options = {})
|
54
|
+
send_message(from_user_id, nil, :broadcast, object_name, content, options)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module RongCloud
|
2
|
+
module Services
|
3
|
+
# 用户相关接口 http://www.rongcloud.cn/docs/server.html#用户服务
|
4
|
+
module User
|
5
|
+
# 获取 Token,即创建融云用户
|
6
|
+
#
|
7
|
+
# @param user_id [String] 用户 Id,最大长度 64 字节。是用户在 App 中的唯一标识码,必须保证在同一个 App 内不重复,重复的用户 Id 将被当作是同一用户
|
8
|
+
# @param name [String] 用户名称,最大长度 128 字节。用来在 Push 推送时显示用户的名称。
|
9
|
+
# @param portrait_uri [String] 用户头像 URI,最大长度 1024 字节。用来在 Push 推送时显示用户的头像。
|
10
|
+
# @return [Hash] 请求响应结果数据
|
11
|
+
#
|
12
|
+
def get_token(user_id, name, portrait_uri)
|
13
|
+
request("/user/getToken", {userId: user_id, name: name, portraitUri: portrait_uri})
|
14
|
+
end
|
15
|
+
|
16
|
+
# 刷新用户信息
|
17
|
+
#
|
18
|
+
def refresh_user(user_id, name = nil, portrait_uri = nil)
|
19
|
+
params = { userId: user_id, name: name, portraitUri: portrait_uri }
|
20
|
+
params.reject!{|key, value| value.nil?}
|
21
|
+
|
22
|
+
request("/user/refresh", params)
|
23
|
+
end
|
24
|
+
|
25
|
+
# 检查用户在线状态
|
26
|
+
#
|
27
|
+
def check_online(user_id)
|
28
|
+
request("/user/checkOnline", { userId: user_id })
|
29
|
+
end
|
30
|
+
|
31
|
+
# 封禁用户
|
32
|
+
# @param user_id [String] 用户在融云的用户 id
|
33
|
+
# @param minute [Integer] 封禁时长
|
34
|
+
#
|
35
|
+
def block_user(user_id, minute)
|
36
|
+
request("/user/block", { userId: user_id, minute: minute })
|
37
|
+
end
|
38
|
+
|
39
|
+
# 解除用户封禁
|
40
|
+
#
|
41
|
+
def unblock_user(user_id)
|
42
|
+
request("/user/unblock", userId: user_id)
|
43
|
+
end
|
44
|
+
|
45
|
+
# 查询被封禁用户列表
|
46
|
+
#
|
47
|
+
def blocked_users
|
48
|
+
request("/user/block/query")
|
49
|
+
end
|
50
|
+
|
51
|
+
# 添加用户到黑名单
|
52
|
+
#
|
53
|
+
def blacklist_add(user_id, black_user_id)
|
54
|
+
request("/user/blacklist/add", userId: user_id, blackUserId: black_user_id)
|
55
|
+
end
|
56
|
+
|
57
|
+
# 从黑名单中移除用户
|
58
|
+
#
|
59
|
+
def blacklist_remove(user_id, black_user_id)
|
60
|
+
request("/user/blacklist/remove", userId: user_id, blackUserId: black_user_id)
|
61
|
+
end
|
62
|
+
|
63
|
+
# 获取某用户的黑名单列表
|
64
|
+
#
|
65
|
+
def blacklisted_users(user_id)
|
66
|
+
request("/user/blacklist/query", userId: user_id)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RongCloud
|
2
|
+
module Services
|
3
|
+
# 敏感词相关接口 http://www.rongcloud.cn/docs/server.html#敏感词服务
|
4
|
+
module Wordfilter
|
5
|
+
# 添加敏感词
|
6
|
+
#
|
7
|
+
# @param word [String] 敏感词
|
8
|
+
#
|
9
|
+
def add_wordfilter(word)
|
10
|
+
request("/wordfilter/add", { word: word })
|
11
|
+
end
|
12
|
+
|
13
|
+
# 移除敏感词
|
14
|
+
#
|
15
|
+
def delete_wordfilter(word)
|
16
|
+
request("/wordfilter/delete", { word: word })
|
17
|
+
end
|
18
|
+
|
19
|
+
# 查询已有敏感词的列表
|
20
|
+
#
|
21
|
+
def wordfilter_list
|
22
|
+
request("/wordfilter/list")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module RongCloud
|
4
|
+
# 签名算法相关模块
|
5
|
+
# http://www.rongcloud.cn/docs/server.html#通用_API_接口签名规则
|
6
|
+
#
|
7
|
+
module Signature
|
8
|
+
# 生成签名串
|
9
|
+
#
|
10
|
+
# @param nonce [String] 参与签名的随机字串,无长度限制
|
11
|
+
# @param timestamp [String] 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的秒数
|
12
|
+
# @return [String] 签名完成之后的结果字串
|
13
|
+
#
|
14
|
+
def signature(nonce, timestamp)
|
15
|
+
str = "#{RongCloud::Configuration.app_secret}#{nonce}#{timestamp}"
|
16
|
+
Digest::SHA1.hexdigest(str)
|
17
|
+
end
|
18
|
+
|
19
|
+
# API 调用签名所需的请求头,包含签名等
|
20
|
+
# @note 包含以下请求头:
|
21
|
+
# App-Key
|
22
|
+
# Nonce
|
23
|
+
# Timestamp
|
24
|
+
# Signature
|
25
|
+
# @return [Hash] 签名所需请求头
|
26
|
+
def signed_headers
|
27
|
+
nonce = rand(10**6)
|
28
|
+
timestamp = Time.now.to_i
|
29
|
+
signature = signature(nonce, timestamp)
|
30
|
+
|
31
|
+
{
|
32
|
+
'App-Key' => RongCloud::Configuration.app_key,
|
33
|
+
'Nonce' => nonce,
|
34
|
+
'Timestamp' => timestamp,
|
35
|
+
'Signature' => signature
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/rong_cloud.rb
ADDED
data/rong_cloud.gemspec
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'rong_cloud_server'
|
3
|
+
s.platform = Gem::Platform::RUBY
|
4
|
+
s.require_path = 'lib'
|
5
|
+
s.summary = '融云 Server API SDK'
|
6
|
+
s.description = '融云服务器端接口 API,http://www.rongcloud.cn/docs/server.html'
|
7
|
+
s.version = '0.0.1'
|
8
|
+
s.files = `git ls-files`.split("\n")
|
9
|
+
s.authors = ['Martin Hong']
|
10
|
+
s.email = 'hongzeqin@gmail.com'
|
11
|
+
s.homepage = 'http://blog.hackerpie.com/rong_cloud/'
|
12
|
+
s.license = 'MIT'
|
13
|
+
end
|
data/run_tests.sh
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
echo "Dir.glob('./test/**/*_test.rb').each { |file| require file}" | ruby -Itest -Ilib
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module RongCloud
|
4
|
+
class ConfigurationTest < Minitest::Test
|
5
|
+
def setup
|
6
|
+
RongCloud.configure do |config|
|
7
|
+
config.host = nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_app_key_settings_and_reading
|
12
|
+
RongCloud::Configuration.app_key = "test_key"
|
13
|
+
assert_equal "test_key", RongCloud::Configuration.app_key
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_app_secret_settings_and_reading
|
17
|
+
RongCloud::Configuration.app_secret = "test_secret"
|
18
|
+
assert_equal "test_secret", RongCloud::Configuration.app_secret
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_logger_setting_and_reading
|
22
|
+
logger = ::Logger.new("rong_cloud.log")
|
23
|
+
RongCloud::Configuration.logger = logger
|
24
|
+
assert_equal logger, RongCloud::Configuration.logger
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_default_host_and_setting_and_reading
|
28
|
+
assert_equal "https://api.cn.ronghub.com", RongCloud::Configuration.host
|
29
|
+
RongCloud::Configuration.host = "http://other.host.com"
|
30
|
+
assert_equal "http://other.host.com", RongCloud::Configuration.host
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module RongCloud
|
4
|
+
class RequestTest < Minitest::Test
|
5
|
+
include RongCloud::Request
|
6
|
+
|
7
|
+
def setup
|
8
|
+
rong_cloud_configure_with_settings
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_get_uri_path_end_with_json_format
|
12
|
+
uri = get_uri("users.json")
|
13
|
+
assert_equal "/users.json", uri.path
|
14
|
+
assert_equal "api.cn.ronghub.com", uri.host
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_get_uri_path_not_end_with_json_format
|
18
|
+
uri = get_uri("users")
|
19
|
+
assert_equal "/users.json", uri.path
|
20
|
+
assert_equal "api.cn.ronghub.com", uri.host
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_request_with_invalid_app_key
|
24
|
+
RongCloud::Configuration.app_key = "xxx"
|
25
|
+
error = assert_raises RongCloud::BadRequest do
|
26
|
+
request("/user/getToken", {userId: 'user', name: "User"})
|
27
|
+
end
|
28
|
+
assert_equal "invalid App-Key.", error.message
|
29
|
+
assert_equal 1002, error.business_code
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_request_with_invalid_app_secret
|
33
|
+
RongCloud::Configuration.app_secret = "xxx"
|
34
|
+
error = assert_raises RongCloud::AuthenticationFailed do
|
35
|
+
request("/user/getToken", {userId: 'user', name: "User"})
|
36
|
+
end
|
37
|
+
assert_equal "签名错误,请检查。", error.message
|
38
|
+
assert_equal 1004, error.business_code
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_request_with_missing_required_field
|
42
|
+
error = assert_raises RongCloud::BadRequest do
|
43
|
+
request("/user/getToken")
|
44
|
+
end
|
45
|
+
assert_equal "userId is required.", error.message
|
46
|
+
assert_equal 1002, error.business_code
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_request_with_valid_params
|
50
|
+
response = request("/user/getToken", { userId: 'user', name: "User", portraitUri: "uri" })
|
51
|
+
assert_equal 200, response["code"]
|
52
|
+
assert_equal "user", response["userId"]
|
53
|
+
assert response["token"]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'rong_cloud/services/user_test'
|
3
|
+
require 'rong_cloud/services/message_test'
|
4
|
+
require 'rong_cloud/services/wordfilter_test'
|
5
|
+
require 'rong_cloud/services/group_test'
|
6
|
+
|
7
|
+
module RongCloud
|
8
|
+
class ServiceTest < Minitest::Test
|
9
|
+
include RongCloud::Services::UserTest
|
10
|
+
include RongCloud::Services::MessageTest
|
11
|
+
include RongCloud::Services::WordfilterTest
|
12
|
+
include RongCloud::Services::GroupTest
|
13
|
+
|
14
|
+
def setup
|
15
|
+
rong_cloud_configure_with_settings
|
16
|
+
@service = RongCloud::Service.new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module RongCloud
|
2
|
+
module Services
|
3
|
+
module GroupTest
|
4
|
+
def test_sync_group
|
5
|
+
response = @service.sync_group('user1', '1' => 'group1', '2' => 'group2')
|
6
|
+
assert_equal 200, response['code']
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_create_group_with_single_user_id
|
10
|
+
response = @service.create_group('user1', '3', 'group3')
|
11
|
+
assert_equal 200, response['code']
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_create_group_with_multiple_user_id
|
15
|
+
response = @service.create_group(%w(user1 user2 user3), '4', 'group4')
|
16
|
+
assert_equal 200, response['code']
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_create_group_without_group_id
|
20
|
+
error = assert_raises RongCloud::BadRequest do
|
21
|
+
@service.create_group('user1', nil, 'group3')
|
22
|
+
end
|
23
|
+
assert_equal 'groupId is required.', error.message
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_create_group_without_group_name
|
27
|
+
response = @service.create_group('user1', '5', nil)
|
28
|
+
assert_equal 200, response['code']
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_join_group_with_single_user_id
|
32
|
+
response = @service.join_group('user1', '3', 'group3')
|
33
|
+
assert_equal 200, response['code']
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_join_group_with_multiple_user_id
|
37
|
+
response = @service.join_group(%w(user1 user2 user3), '4', 'group4')
|
38
|
+
assert_equal 200, response['code']
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_join_group_without_group_id
|
42
|
+
error = assert_raises RongCloud::BadRequest do
|
43
|
+
@service.join_group('user1', nil, 'group3')
|
44
|
+
end
|
45
|
+
assert_equal 'groupId is required.', error.message
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_join_group_without_group_name
|
49
|
+
response = @service.join_group('user1', '5', nil)
|
50
|
+
assert_equal 200, response['code']
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_quit_group
|
54
|
+
response = @service.quit_group('user', 'group1')
|
55
|
+
assert_equal 200, response['code']
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_dismiss_group
|
59
|
+
response = @service.dismiss_group('user', 'group1')
|
60
|
+
assert_equal 200, response['code']
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_refresh_group
|
64
|
+
response = @service.refresh_group('group1', "测试群组1")
|
65
|
+
assert_equal 200, response['code']
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_group_members
|
69
|
+
@service.create_group("user1", "group6", "测试群组成员")
|
70
|
+
@service.join_group("user2", "group6", "测试群组成员")
|
71
|
+
response = @service.group_members("group6")
|
72
|
+
user_ids = response['users'].map{|user| user['id'] }
|
73
|
+
|
74
|
+
assert_equal 2, user_ids.count
|
75
|
+
assert_includes user_ids, 'user1'
|
76
|
+
assert_includes user_ids, 'user2'
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_block_group_member
|
80
|
+
response = @service.block_group_member("user1", "group1", 600)
|
81
|
+
assert_equal 200, response['code']
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_unblock_group_member
|
85
|
+
response = @service.unblock_group_member("user1", "group1")
|
86
|
+
assert_equal 200, response['code']
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_blocked_group_members
|
90
|
+
@service.create_group("user1", "group1", "测试群组禁言服务")
|
91
|
+
@service.join_group("user2", "group1", "测试群组禁言服务")
|
92
|
+
@service.block_group_member("user2", "group1", 60000)
|
93
|
+
|
94
|
+
response = @service.blocked_group_members('group1')
|
95
|
+
user_ids = response['users'].map{|user| user['userId']}
|
96
|
+
|
97
|
+
assert_equal 1, user_ids.count
|
98
|
+
assert_includes user_ids, "user2"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'rong_cloud/services/message/message_channel'
|
2
|
+
|
3
|
+
module RongCloud
|
4
|
+
module Services
|
5
|
+
module Message
|
6
|
+
class MessageChannelTest < Minitest::Test
|
7
|
+
def test_initialize_with_supported_channel_name
|
8
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:private)
|
9
|
+
assert channel
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_initialize_with_unsupported_channel_name
|
13
|
+
error = assert_raises RongCloud::UnsupportedMessageChannelName do
|
14
|
+
RongCloud::Services::Message::MessageChannel.new(:nothing)
|
15
|
+
end
|
16
|
+
expected_error = "support only channels: [\"private\", \"system\", \"group\", \"discussion\", \"chatroom\", \"broadcast\"]"
|
17
|
+
assert_equal expected_error, error.message
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_target_param_name_for_private
|
21
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:private)
|
22
|
+
assert_equal "toUserId", channel.target_param_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_target_param_name_for_system
|
26
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:system)
|
27
|
+
assert_equal "toUserId", channel.target_param_name
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_target_param_name_for_group
|
31
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:group)
|
32
|
+
assert_equal "toGroupId", channel.target_param_name
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_target_param_name_for_discussion
|
36
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:discussion)
|
37
|
+
assert_equal "toDiscussionId", channel.target_param_name
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_target_param_name_for_chatroom
|
41
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:chatroom)
|
42
|
+
assert_equal "toChatroomId", channel.target_param_name
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_target_param_name_for_broadcast
|
46
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:broadcast)
|
47
|
+
assert_nil channel.target_param_name
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_api_path_for_private
|
51
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:private)
|
52
|
+
assert_equal "/message/private/publish", channel.api_path
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_api_path_for_system
|
56
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:system)
|
57
|
+
assert_equal "/message/system/publish", channel.api_path
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_api_path_for_group
|
61
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:group)
|
62
|
+
assert_equal "/message/group/publish", channel.api_path
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_api_path_for_discussion
|
66
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:discussion)
|
67
|
+
assert_equal "/message/discussion/publish", channel.api_path
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_api_path_for_chatroom
|
71
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:chatroom)
|
72
|
+
assert_equal "/message/chatroom/publish", channel.api_path
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_api_path_for_broadcast
|
76
|
+
channel = RongCloud::Services::Message::MessageChannel.new(:broadcast)
|
77
|
+
assert_equal "/message/broadcast", channel.api_path
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module RongCloud
|
2
|
+
module Services
|
3
|
+
module MessageTest
|
4
|
+
def test_send_private_message_with_single_to_user_id
|
5
|
+
response = @service.send_private_message(1, 2, "RC:TxtMsg", { content: "hello world", extra: "nothing" })
|
6
|
+
assert_equal 200, response["code"]
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_send_private_message_with_multiple_to_user_ids
|
10
|
+
response = @service.send_private_message(1, [2, 3, 4], "RC:TxtMsg", { content: "hello world", extra: "nothing" })
|
11
|
+
assert_equal 200, response["code"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_send_private_message_with_options
|
15
|
+
options = { pushContent: "hello", pushData: { shouldBeTrue: "true" } }
|
16
|
+
response = @service.send_private_message(1, [2, 3, 4], "RC:TxtMsg", { content: "hello world", extra: "nothing" }, options)
|
17
|
+
assert_equal 200, response["code"]
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_send_system_message_with_single_to_user_id
|
21
|
+
response = @service.send_system_message(1, 2, "RC:TxtMsg", { content: "hello world", extra: "nothing" })
|
22
|
+
assert_equal 200, response["code"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_send_system_message_with_multiple_to_user_ids
|
26
|
+
response = @service.send_system_message(1, [2, 3, 4], "RC:TxtMsg", { content: "hello world", extra: "nothing" })
|
27
|
+
assert_equal 200, response["code"]
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_send_system_message_with_options
|
31
|
+
options = { pushContent: "hello", pushData: { shouldBeTrue: "true" } }
|
32
|
+
response = @service.send_system_message(1, [2, 3, 4], "RC:TxtMsg", { content: "hello world", extra: "nothing" }, options)
|
33
|
+
assert_equal 200, response["code"]
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_send_group_message_with_single_to_group_id
|
37
|
+
response = @service.send_group_message(1, 2, "RC:TxtMsg", { content: "hello world", extra: "nothing" })
|
38
|
+
assert_equal 200, response["code"]
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_send_group_message_with_multiple_to_group_ids
|
42
|
+
response = @service.send_group_message(1, [2, 3, 4], "RC:TxtMsg", { content: "hello world", extra: "nothing" })
|
43
|
+
assert_equal 200, response["code"]
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_send_group_message_with_multiple_to_too_many_group_ids
|
47
|
+
error = assert_raises RongCloud::BadRequest do
|
48
|
+
@service.send_group_message(1, [2, 3, 4, 5], "RC:TxtMsg", { content: "hello world", extra: "nothing" })
|
49
|
+
end
|
50
|
+
|
51
|
+
assert_equal "the number of toUserId should less than 3.", error.message
|
52
|
+
assert_equal 1002, error.business_code
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_send_group_message_with_options
|
56
|
+
options = { pushContent: "hello", pushData: { shouldBeTrue: "true" } }
|
57
|
+
response = @service.send_group_message(1, [2, 3, 4], "RC:TxtMsg", { content: "hello world", extra: "nothing" }, options)
|
58
|
+
assert_equal 200, response["code"]
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_send_discussion_message_with_single_to_discussion_id
|
62
|
+
response = @service.send_discussion_message(1, 2, "RC:TxtMsg", { content: "hello world", extra: "nothing" })
|
63
|
+
assert_equal 200, response["code"]
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_send_discussion_message_with_multiple_to_discussion_ids
|
67
|
+
response = @service.send_discussion_message(1, [2, 3, 4], "RC:TxtMsg", { content: "hello world", extra: "nothing" })
|
68
|
+
assert_equal 200, response["code"]
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_send_discussion_message_with_options
|
72
|
+
options = { pushContent: "hello", pushData: { shouldBeTrue: "true" } }
|
73
|
+
response = @service.send_discussion_message(1, [2, 3, 4], "RC:TxtMsg", { content: "hello world", extra: "nothing" }, options)
|
74
|
+
assert_equal 200, response["code"]
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_send_broadcast_message
|
78
|
+
response = @service.send_broadcast_message(1, "RC:TxtMsg", { content: "hello world", extra: "nothing" })
|
79
|
+
assert_equal 200, response["code"]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
module RongCloud
|
2
|
+
module Services
|
3
|
+
module UserTest
|
4
|
+
def test_get_token_without_user_id
|
5
|
+
error = assert_raises RongCloud::BadRequest do
|
6
|
+
@service.get_token(nil, nil, nil)
|
7
|
+
end
|
8
|
+
assert_equal 1002, error.business_code
|
9
|
+
assert_equal "userId is required.", error.message
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_get_token_without_name
|
13
|
+
response = @service.get_token("user", nil, nil)
|
14
|
+
assert response["token"]
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_get_token_without_portrait_url
|
18
|
+
response = @service.get_token("user", "User", nil)
|
19
|
+
assert response["token"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_get_token_with_all_params
|
23
|
+
response = @service.get_token("user", "User", "fake_url")
|
24
|
+
assert response["token"]
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_get_token_with_chinese_name
|
28
|
+
response = @service.get_token("user", "王二狗", "fake_url")
|
29
|
+
assert response["token"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_refresh_user_without_user_id
|
33
|
+
error = assert_raises RongCloud::BadRequest do
|
34
|
+
@service.refresh_user(nil, nil, nil)
|
35
|
+
end
|
36
|
+
assert_equal 1002, error.business_code
|
37
|
+
assert_equal "userId is required.", error.message
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_refresh_user_with_unexisted_user_id
|
41
|
+
error = assert_raises RongCloud::BadRequest do
|
42
|
+
@service.refresh_user("unexistedUserId", nil, nil)
|
43
|
+
end
|
44
|
+
assert_equal "userIdunexistedUserId is not exist.", error.message
|
45
|
+
assert_equal 1002, error.business_code
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_refresh_user_without_portrait_url
|
49
|
+
response = @service.refresh_user("user", "User", nil)
|
50
|
+
assert_equal 200, response["code"]
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_refresh_user_with_all_params
|
54
|
+
response = @service.refresh_user("user", "User", "fake_url")
|
55
|
+
assert_equal 200, response["code"]
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_refresh_user_with_chinese_name
|
59
|
+
response = @service.refresh_user("user", "小李子", nil)
|
60
|
+
assert_equal 200, response["code"]
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_check_online_without_user_id
|
64
|
+
error = assert_raises RongCloud::BadRequest do
|
65
|
+
@service.check_online(nil)
|
66
|
+
end
|
67
|
+
assert_equal "userId is required.", error.message
|
68
|
+
assert_equal 1002, error.business_code
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_check_online_with_unexisted_user_id
|
72
|
+
response = @service.check_online("unexistedUserId")
|
73
|
+
assert_equal "0", response["status"]
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_check_online_with_existed_user_id
|
77
|
+
response = @service.check_online("user")
|
78
|
+
assert_equal "0", response["status"]
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_block_user_without_user_id
|
82
|
+
error = assert_raises RongCloud::BadRequest do
|
83
|
+
@service.block_user(nil, nil)
|
84
|
+
end
|
85
|
+
assert_equal "userId is required.", error.message
|
86
|
+
assert_equal 1002, error.business_code
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_block_user_without_minute
|
90
|
+
@service.get_token("blocked_user", "Blocked", "fake_url")
|
91
|
+
error = assert_raises RongCloud::BadRequest do
|
92
|
+
@service.block_user("blocked_user", nil)
|
93
|
+
end
|
94
|
+
|
95
|
+
assert_equal "minute is required.", error.message
|
96
|
+
assert_equal 1002, error.business_code
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_block_user_without_unexisted_user_id
|
100
|
+
response = @service.block_user("unexistedUserId", 3)
|
101
|
+
assert_equal 200, response["code"]
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_block_user_and_blocked_users_and_unblock_user
|
105
|
+
@service.get_token("blocked_user2", "Blocked", "fake_url")
|
106
|
+
response = @service.block_user("blocked_user2", 10)
|
107
|
+
assert_equal 200, response["code"]
|
108
|
+
|
109
|
+
users = @service.blocked_users["users"]
|
110
|
+
user = users.detect{|object| object["userId"] == "blocked_user2"}
|
111
|
+
assert user["blockEndTime"]
|
112
|
+
|
113
|
+
response = @service.unblock_user("blocked_user2")
|
114
|
+
assert 200, response["code"]
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_blacklist_add_for_unexisted_user_id
|
118
|
+
response = @service.blacklist_add("unexisted", "blacklisted_user")
|
119
|
+
assert_equal 200, response["code"]
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_blacklist_add_for_existed_user_with_multiple_black_user_id
|
123
|
+
response = @service.blacklist_add("user", %w(blu blu2 blu3))
|
124
|
+
assert_equal 200, response["code"]
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_blacklist_remove_for_unexisted_user_id
|
128
|
+
response = @service.blacklist_remove("unexisted_user", "blacklisted_user")
|
129
|
+
assert_equal 200, response["code"]
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_blacklist_remove_for_unblacklisted_user_id
|
133
|
+
response = @service.blacklist_remove("user", "unexisted_user")
|
134
|
+
assert_equal 200, response["code"]
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_blacklisted_users
|
138
|
+
@service.blacklist_add("user", %w(user2 user3))
|
139
|
+
response = @service.blacklisted_users("user")
|
140
|
+
assert %w(user2 user3) & response["users"] == %w(user2 user3)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RongCloud
|
2
|
+
module Services
|
3
|
+
module WordfilterTest
|
4
|
+
def test_add_wordfilter_with_single_word
|
5
|
+
response = @service.add_wordfilter("敏感词")
|
6
|
+
assert_equal 200, response["code"]
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_delete_exist_wordfilter
|
10
|
+
@service.add_wordfilter("hello")
|
11
|
+
response = @service.delete_wordfilter("hello")
|
12
|
+
assert_equal 200, response["code"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_delete_unexist_wordfilter
|
16
|
+
response = @service.delete_wordfilter("unexistedWord")
|
17
|
+
assert_equal 500, response["code"] # TODO: 500 非期待,后边修复
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_wordfilter_list
|
21
|
+
@service.add_wordfilter("乱")
|
22
|
+
response = @service.wordfilter_list
|
23
|
+
words = response["words"].map{|word| word["word"]}
|
24
|
+
assert_includes words, "乱"
|
25
|
+
|
26
|
+
@service.delete_wordfilter("乱")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module RongCloud
|
4
|
+
class SignatureTest < Minitest::Test
|
5
|
+
include RongCloud::Signature
|
6
|
+
|
7
|
+
def setup
|
8
|
+
RongCloud.configure do |config|
|
9
|
+
config.app_key = "uwd1c0sxdlx2"
|
10
|
+
config.app_secret = "Y1W2MeFwwwRxa0"
|
11
|
+
|
12
|
+
@nonce = 14314
|
13
|
+
@timestamp = 1408706337
|
14
|
+
@expected_sign = "e107e3819638b81a00383951d1d871197910ffe6"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_signature
|
19
|
+
signature = signature(@nonce, @timestamp)
|
20
|
+
assert_equal @expected_sign, signature
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_signed_headers
|
24
|
+
Time.stub :now, Time.at(@timestamp) do
|
25
|
+
def rand(args)
|
26
|
+
@nonce
|
27
|
+
end
|
28
|
+
|
29
|
+
expected_headers = {
|
30
|
+
'App-Key' => RongCloud::Configuration.app_key,
|
31
|
+
'Nonce' => @nonce,
|
32
|
+
'Timestamp' => @timestamp,
|
33
|
+
'Signature' => @expected_sign
|
34
|
+
}
|
35
|
+
assert_equal expected_headers, signed_headers
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RondCloudTest < Minitest::Test
|
4
|
+
def test_configure
|
5
|
+
RongCloud.configure do |app|
|
6
|
+
app.app_key = "KEY"
|
7
|
+
app.app_secret = "SECRET"
|
8
|
+
app.host = "HOST"
|
9
|
+
end
|
10
|
+
|
11
|
+
assert_equal "KEY", RongCloud::Configuration.app_key
|
12
|
+
assert_equal "SECRET", RongCloud::Configuration.app_secret
|
13
|
+
assert_equal "HOST", RongCloud::Configuration.host
|
14
|
+
end
|
15
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'byebug'
|
3
|
+
require 'rong_cloud'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
$settings = YAML.load_file("./config.yml")
|
7
|
+
|
8
|
+
def rong_cloud_configure_with_settings
|
9
|
+
RongCloud.configure do |config|
|
10
|
+
$settings.each do |setting, value|
|
11
|
+
config.send("#{setting}=", value)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rong_cloud_server
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Martin Hong
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-09 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: 融云服务器端接口 API,http://www.rongcloud.cn/docs/server.html
|
14
|
+
email: hongzeqin@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- ".gitignore"
|
20
|
+
- README.md
|
21
|
+
- config.example.yml
|
22
|
+
- lib/rong_cloud.rb
|
23
|
+
- lib/rong_cloud/configuration.rb
|
24
|
+
- lib/rong_cloud/errors.rb
|
25
|
+
- lib/rong_cloud/request.rb
|
26
|
+
- lib/rong_cloud/service.rb
|
27
|
+
- lib/rong_cloud/services/group.rb
|
28
|
+
- lib/rong_cloud/services/message.rb
|
29
|
+
- lib/rong_cloud/services/message/message_channel.rb
|
30
|
+
- lib/rong_cloud/services/user.rb
|
31
|
+
- lib/rong_cloud/services/wordfilter.rb
|
32
|
+
- lib/rong_cloud/signature.rb
|
33
|
+
- rong_cloud.gemspec
|
34
|
+
- run_tests.sh
|
35
|
+
- test/rong_cloud/configuration_test.rb
|
36
|
+
- test/rong_cloud/request_test.rb
|
37
|
+
- test/rong_cloud/service_test.rb
|
38
|
+
- test/rong_cloud/services/group_test.rb
|
39
|
+
- test/rong_cloud/services/message/message_channel_test.rb
|
40
|
+
- test/rong_cloud/services/message_test.rb
|
41
|
+
- test/rong_cloud/services/user_test.rb
|
42
|
+
- test/rong_cloud/services/wordfilter_test.rb
|
43
|
+
- test/rong_cloud/signature_test.rb
|
44
|
+
- test/rong_cloud_test.rb
|
45
|
+
- test/test_helper.rb
|
46
|
+
homepage: http://blog.hackerpie.com/rong_cloud/
|
47
|
+
licenses:
|
48
|
+
- MIT
|
49
|
+
metadata: {}
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 2.6.6
|
67
|
+
signing_key:
|
68
|
+
specification_version: 4
|
69
|
+
summary: 融云 Server API SDK
|
70
|
+
test_files: []
|