rong_cloud_server 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|