imwukong 0.1.4

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5f839e78ed7eb750f06fe3b23a20e9d2b2038b77
4
+ data.tar.gz: 2cb0f34fa327598e8e5f0da64b1829cf605b7bdf
5
+ SHA512:
6
+ metadata.gz: fb6fff8bdd2c0c775db24fdfbbcd018c5616ab3fe29c8b87fa6a241edd4cdaaf42cf5ce5078b237001485e5e1541686933c0f9d4b2ed3594b55465b5c48f54f2
7
+ data.tar.gz: 4c197d257bc8ea4217c268dfdf7600503885c43b61387bf6f4cd7c74fd346de7ae459fbfb44a9fed31e015d9e80cf9aaeadacf81f88eb7100297d860afb5043d
data/.gitignore ADDED
@@ -0,0 +1,37 @@
1
+ .idea/
2
+ .DS_Store
3
+ *.rbc
4
+ capybara-*.html
5
+ .rspec
6
+ /log
7
+ /tmp
8
+ /db/*.sqlite3
9
+ /db/*.sqlite3-journal
10
+ /public/system
11
+ /coverage/
12
+ /spec/tmp
13
+ **.orig
14
+ rerun.txt
15
+ pickle-email-*.html
16
+
17
+ # TODO Comment out these rules if you are OK with secrets being uploaded to the repo
18
+ config/initializers/secret_token.rb
19
+ config/secrets.yml
20
+
21
+ ## Environment normalisation:
22
+ /.bundle
23
+ /vendor/bundle
24
+
25
+ # these should all be checked in to normalise the environment:
26
+ # Gemfile.lock, .ruby-version, .ruby-gemset
27
+
28
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
29
+ .rvmrc
30
+
31
+ # if using bower-rails ignore default bower_components path bower.json files
32
+ /vendor/assets/bower_components
33
+ *.bowerrc
34
+ bower.json
35
+
36
+ # Ignore pow environment settings
37
+ .powenv
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in imwukong.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,53 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ imwukong (0.1.4)
5
+ activesupport (~> 4.2.0)
6
+ httparty (~> 0.13.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (4.2.1)
12
+ i18n (~> 0.7)
13
+ json (~> 1.7, >= 1.7.7)
14
+ minitest (~> 5.1)
15
+ thread_safe (~> 0.3, >= 0.3.4)
16
+ tzinfo (~> 1.1)
17
+ diff-lcs (1.2.5)
18
+ httparty (0.13.3)
19
+ json (~> 1.8)
20
+ multi_xml (>= 0.5.2)
21
+ i18n (0.7.0)
22
+ json (1.8.3)
23
+ minitest (5.8.2)
24
+ multi_xml (0.5.5)
25
+ rake (10.4.2)
26
+ rspec (3.3.0)
27
+ rspec-core (~> 3.3.0)
28
+ rspec-expectations (~> 3.3.0)
29
+ rspec-mocks (~> 3.3.0)
30
+ rspec-core (3.3.2)
31
+ rspec-support (~> 3.3.0)
32
+ rspec-expectations (3.3.1)
33
+ diff-lcs (>= 1.2.0, < 2.0)
34
+ rspec-support (~> 3.3.0)
35
+ rspec-mocks (3.3.2)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.3.0)
38
+ rspec-support (3.3.0)
39
+ thread_safe (0.3.5)
40
+ tzinfo (1.2.2)
41
+ thread_safe (~> 0.1)
42
+
43
+ PLATFORMS
44
+ ruby
45
+
46
+ DEPENDENCIES
47
+ bundler (~> 1.10)
48
+ imwukong!
49
+ rake (~> 10.0)
50
+ rspec
51
+
52
+ BUNDLED WITH
53
+ 1.10.6
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 xh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # Imwukong
2
+ :sunny:server APIs for [阿里悟空](https://imwukong.com)
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'imwukong', github: 'dannyxu2015/imwukong', branch: 'master'
10
+ ```
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install imwukong
19
+
20
+ ## Usage
21
+
22
+ ### Configuration
23
+
24
+ ```ruby
25
+ Imwukong.configure do |config|
26
+ config = {
27
+ env: 'development',
28
+ domain: 'your-domain',
29
+ android: {
30
+ app_key: 'android_app_key',
31
+ app_secret: 'android_app_secret'
32
+ },
33
+ ios: {
34
+ app_key: 'ios_app_key',
35
+ app_secret: 'ios_app_secret'
36
+ },
37
+ web: {
38
+ app_key: 'web_app_key',
39
+ app_secret: 'web_app_secret'
40
+ },
41
+ server: {
42
+ app_token: 'server_app_token'
43
+ }
44
+ }
45
+ end
46
+ ```
47
+
48
+ ### API info
49
+
50
+ ```ruby
51
+ wk = Imwukong::Base.new
52
+ wk.wk_api_list
53
+ => [:wk_api_info, :wk_api_list, :wk_conversation_add_members, :wk_conversation_clear, :wk_conversation_create, :wk_conversation_disband, :wk_conversation_info, :wk_conversation_members, :wk_conversation_page_group_infos, :wk_conversation_page_infos, :wk_conversation_profiles, :wk_conversation_query, :wk_conversation_quit, :wk_conversation_quit_silent, :wk_conversation_remove_members, :wk_conversation_role_list, :wk_conversation_set_top, :wk_conversation_unlimit_infos, :wk_conversation_update_ext, :wk_conversation_update_exts, :wk_conversation_update_icon, :wk_conversation_update_member_limit, :wk_conversation_update_notification, :wk_conversation_update_owner, :wk_conversation_update_status, :wk_conversation_update_super, :wk_conversation_update_tag, :wk_conversation_update_title, :wk_conversations_infos, :wk_conversations_newest, :wk_conversations_unread, :wk_message_query, :wk_message_recall, :wk_message_remove, :wk_message_send, :wk_message_set_read, :wk_message_unread_members, :wk_message_update_ext, :wk_message_update_member, :wk_push_to_user, :wk_relation_bi_follow_list, :wk_relation_follow, :wk_relation_follow_by_list, :wk_relation_follow_list, :wk_relation_list, :wk_relation_query, :wk_relation_unfollow, :wk_user_profile, :wk_user_profiles, :wk_user_update_profile, :wk_user_update_tag]
54
+
55
+ wk.wk_api_info(:wk_user_profile)
56
+ => ["wk_user_profile, GET v1/user/profile/get, [:openId] "]
57
+ ```
58
+
59
+ ### Reserverd extend methods
60
+
61
+ ```ruby
62
+ wk_post(api_group, api_url, api_prefix, params)
63
+ wk_get(api_group, api_url, api_prefix, params)
64
+ # default api_prefix is 'v1/im'
65
+
66
+ wk.wk_get('user','profile/get','v1',openId:1)
67
+ ```
68
+
69
+ ### Sample
70
+
71
+ ```ruby
72
+ # use default config
73
+ wk = Imwukong::Base.new
74
+
75
+ wk.wk_user_update_profile(avatar: "http://laiwang.wukong.com/tianpeng.png", birthday:651337200000,gender: 1, isActive: true, nick: "u1", nickPinyin: "testpinyin", openid: 1, ver: 1)
76
+
77
+ wk.wk_user_profile(1)
78
+
79
+ wk.wk_user_profiles([1,2,3,4])
80
+ ```
81
+
82
+ ## Development
83
+
84
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
85
+
86
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
87
+
88
+ ## Contributing
89
+
90
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dannyxu2015/imwukong.
91
+
92
+
93
+ ## License
94
+
95
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
96
+
97
+ # Todo
98
+
99
+ ## API
100
+
101
+ - [x] user
102
+ - [x] conversation
103
+ - [x] message
104
+ - [x] follow
105
+ - [ ] upload
106
+ - [x] push
107
+
108
+ ## Client
109
+
110
+ - [x] client signature
111
+
112
+
113
+
114
+
115
+
116
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
8
+ task :console do
9
+ exec "irb -r Imwukong -I ./lib"
10
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "imwukong"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/imwukong.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'imwukong/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "imwukong"
8
+ spec.version = Imwukong::VERSION
9
+ spec.authors = ["Danny Xu"]
10
+ spec.email = ["dannyxu@gmail.com"]
11
+
12
+ spec.summary = %q{I am Wukong!}
13
+ spec.description = %q{ruby server api for imwukong of alibaba}
14
+ spec.homepage = "https://github.com/dannyxu2015/imwukong"
15
+ spec.license = "MIT"
16
+
17
+ # # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # # delete this section to allow pushing this gem to any host.
19
+ # if spec.respond_to?(:metadata)
20
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
+ # else
22
+ # raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ # end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.10"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "rspec"
33
+ spec.add_dependency "httparty", "~> 0.13.0"
34
+ spec.add_dependency "activesupport", "~> 4.2.0"
35
+ end
@@ -0,0 +1,101 @@
1
+ module Imwukong
2
+ module Api
3
+ module Conversation
4
+ # refer to: https://imwukong.com/#doc/doc/server/index.htm??聊天会话
5
+ CONVERSATION = 'conversation'.freeze
6
+
7
+ 创建会话
8
+ def create(params)
9
+ wk_post(CONVERSATION, 'create', params)
10
+ end
11
+
12
+ # 查询会话概要信息
13
+ def profiles(open_id, conversation_ids)
14
+ params = {
15
+ openId: open_id,
16
+ conversationIds: conversation_ids
17
+ }
18
+ wk_post(CONVERSATION, 'profiles/get', params)
19
+ end
20
+
21
+ # 查询会话信息(包括会话最近的消息和消息状态)
22
+ def info(open_id, conversation_id)
23
+ params = {
24
+ openId: open_id,
25
+ conversationId: conversation_id
26
+ }
27
+ wk_post(CONVERSATION, 'get', params)
28
+ end
29
+
30
+ # 批量查询会话信息(包括会话最近的消息和消息状态)
31
+ def infos(open_id, conversation_ids)
32
+ params = {
33
+ openId: open_id,
34
+ conversationIds: conversation_ids
35
+ }
36
+ # what a weired thing ~
37
+ wk_post(CONVERSATION+'s', 'get', params)
38
+ end
39
+
40
+ # 无条件查询会话信息,首屏删除也可以取得(包括会话最近的消息和消息状态)
41
+ def unlimit_infos(open_id, conversation_id)
42
+ params = {
43
+ openId: open_id,
44
+ conversationId: conversation_id
45
+ }
46
+ wk_post(CONVERSATION, 'unlimited/get', params)
47
+ end
48
+
49
+ # 分页查询群聊会话列表
50
+ # @param open_id, integer, 用户id
51
+ # @param cursor, integer, 会话时间戳起始时间,第一次取值为0,之后取最后一个会话的createAt值
52
+ # @oaram count, 每次拉取的会话个数
53
+ def page_group_infos(open_id, cursor, count)
54
+ params = {
55
+ openId: open_id,
56
+ cursor: cursor,
57
+ count: count
58
+ }
59
+ wk_get(CONVERSATION, 'groups/get', params)
60
+ end
61
+
62
+ def page_infos(open_id, cursor, count)
63
+ params = {
64
+ openId: open_id,
65
+ cursor: cursor,
66
+ count: count
67
+ }
68
+ wk_get(CONVERSATION+'s', 'list', params)
69
+ end
70
+
71
+ def add_member(open_id, cid, members, message)
72
+ params = {
73
+ openId: open_id,
74
+ conversationId: cid,
75
+ members: members,
76
+ message: message
77
+ }
78
+ wk_post(CONVERSATION, 'member/add', params)
79
+ end
80
+
81
+ def remove_member(open_id, cid, members, message)
82
+ params = {
83
+ openId: open_id,
84
+ conversationId: cid,
85
+ members: members,
86
+ message: message
87
+ }
88
+ wk_post(CONVERSATION, 'member/remove', params)
89
+ end
90
+
91
+ def update_tag(open_id, cid, tag)
92
+ params = {
93
+ openId: open_id,
94
+ conversationId: cid,
95
+ tag: tag
96
+ }
97
+ wk_post(CONVERSATION, 'tag/update', params)
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,6 @@
1
+ module Imwukong
2
+ module Api
3
+ module Follow
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Imwukong
2
+ module Api
3
+ module Message
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Imwukong
2
+ module Api
3
+ module Push
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Imwukong
2
+ module Api
3
+ module Upload
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,40 @@
1
+ module Imwukong
2
+ module Api
3
+ module User
4
+ # wukong API documents: https://imwukong.com/#doc/doc/server/index.htm??用户
5
+
6
+ # @param open_id, integer, unique user identifier of wukong
7
+ # @return, i.e. {"birthday":651337200000,"nick":"tianpeng","gender":1,"openid":100078,
8
+ # "avatar":"http://laiwang.wukong.com/tianfeng.png"}
9
+ def profile(open_id)
10
+ params = {openId: open_id.to_i}
11
+ wk_get('user', 'profile/get', params)
12
+ end
13
+
14
+ # @param params, hash
15
+ # i.e. avatar: "http://laiwang.wukong.com/tianpeng.png", birthday:651337200000,gender: 1,
16
+ # isActive: true, nick: "u1", nickPinyin: "testpinyin", openid: 1, ver: 1
17
+ def update_profile(params)
18
+ wk_post('user', 'profile/update', params)
19
+ end
20
+
21
+ # @param open_ids, array, open ids array
22
+ # @return user profiles in an array
23
+ def profiles(open_ids)
24
+ fail 'Invalid [profiles get] parameters' unless open_ids.is_a?(Array)
25
+ params = {openIds: open_ids}
26
+ wk_post('user', 'profiles/get', params)
27
+ end
28
+
29
+ def update_tag(open_id, tag, op)
30
+ params = {
31
+ openId: open_id,
32
+ tag: tag,
33
+ op: op
34
+ }
35
+ wk_post('user', 'tag/update', params)
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ Dir["#{File.dirname(__FILE__)}/api/*.rb"].each do |path|
2
+ require path
3
+ end
@@ -0,0 +1,503 @@
1
+ require 'active_support/core_ext/string'
2
+ module Imwukong
3
+ class Base
4
+ STATUS_FOLLOW = 0 # 关注
5
+ STATUS_FOLLOW_BY = 1 # 被关注
6
+ STATUS_BI_FOLLOW = 2 # 双向关系
7
+
8
+ API_LIST = [
9
+ # 用户
10
+ {
11
+ method_group: 'user',
12
+ method_name: 'update_profile',
13
+ http_method: :post,
14
+ prefix: 'v1',
15
+ url: 'profile/update'
16
+ },
17
+ {
18
+ method_group: 'user',
19
+ method_name: 'profile',
20
+ http_method: :get,
21
+ prefix: 'v1',
22
+ url: 'profile/get',
23
+ args: [:openId]
24
+ },
25
+ {
26
+ method_group: 'user',
27
+ method_name: 'profiles',
28
+ http_method: :post,
29
+ prefix: 'v1',
30
+ url: 'profiles/get',
31
+ args: [:openIds]
32
+ },
33
+ {
34
+ method_group: 'user',
35
+ method_name: 'update_tag',
36
+ http_method: :post,
37
+ prefix: 'v1',
38
+ url: 'tag/update',
39
+ args: [:openId, :tag, :op]
40
+ },
41
+
42
+ # 聊天会话
43
+ {
44
+ # 创建聊天会话
45
+ method_group: 'conversation',
46
+ method_name: 'create',
47
+ method_pluralize: false,
48
+ http_method: :post,
49
+ url: 'create'
50
+ },
51
+ {
52
+ # 查询聊天会话的概要信息
53
+ method_group: 'conversation',
54
+ method_name: 'profiles',
55
+ http_method: :post,
56
+ url: 'profiles/get',
57
+ args: [:openId, :conversationIds]
58
+ },
59
+ {
60
+ # 查询会话信息(包括会话最近的消息和消息状态)
61
+ method_group: 'conversation',
62
+ method_name: 'info',
63
+ http_method: :get,
64
+ url: 'get',
65
+ args: [:openId, :conversationId]
66
+ },
67
+ {
68
+ # 批量查询会话信息(包括会话最近的消息和消息状态)
69
+ method_group: 'conversation',
70
+ method_name: 'infos',
71
+ method_pluralize: true,
72
+ http_method: :post,
73
+ url: 'get',
74
+ args: [:openId, :conversationIds]
75
+ },
76
+ {
77
+ # 无条件查询会话信息,首屏删除也可以取得(包括会话最近的消息和消息状态)
78
+ method_group: 'conversation',
79
+ method_name: 'unlimit_infos',
80
+ http_method: :post,
81
+ url: 'unlimited/get',
82
+ args: [:openId, :conversationId]
83
+ },
84
+ {
85
+ # 分页查询用户的群聊会话列表
86
+ method_group: 'conversation',
87
+ method_name: 'page_group_infos',
88
+ http_method: :get,
89
+ url: 'groups/get',
90
+ args: [:openId, :cursor, :count]
91
+ },
92
+ {
93
+ # 分页查询用户的会话列表
94
+ method_group: 'conversation',
95
+ method_name: 'page_infos',
96
+ http_method: :get,
97
+ url: 'list',
98
+ args: [:openId, :cursor, :count]
99
+ },
100
+ {
101
+ # 增加会话成员
102
+ method_group: 'conversation',
103
+ method_name: 'add_members',
104
+ http_method: :post,
105
+ url: 'member/add',
106
+ args: [:openId, :conversationId, :members, :message]
107
+ },
108
+ {
109
+ # 群主删除会话成员
110
+ method_group: 'conversation',
111
+ method_name: 'remove_members',
112
+ http_method: :post,
113
+ url: 'member/remove',
114
+ args: [:openId, :conversationId, :members, :message]
115
+ },
116
+ {
117
+ # 修改群聊会话tag,用于通知会话信息发生变化
118
+ method_group: 'conversation',
119
+ method_name: 'update_tag',
120
+ http_method: :post,
121
+ url: 'tag/update',
122
+ args: [:openId, :conversationId, :tag]
123
+ },
124
+ {
125
+ # 修改群聊会话自定义扩展字段extension
126
+ method_group: 'conversation',
127
+ method_name: 'update_ext',
128
+ http_method: :post,
129
+ url: 'extension/update',
130
+ args: [:openId, :conversationId, :extension]
131
+ },
132
+ {
133
+ # 修改会话名称
134
+ method_group: 'conversation',
135
+ method_name: 'update_title',
136
+ http_method: :post,
137
+ url: 'title/update',
138
+ args: [:openId, :conversationId, :extension]
139
+ },
140
+ {
141
+ # 修改会话头像
142
+ method_group: 'conversation',
143
+ method_name: 'update_icon',
144
+ http_method: :post,
145
+ url: 'icon/update',
146
+ args: [:openId, :conversationId, :newIcon, :message]
147
+ },
148
+ {
149
+ # 修改XPN状态
150
+ method_group: 'conversation',
151
+ method_name: 'update_notification',
152
+ http_method: :post,
153
+ url: 'notification/update',
154
+ # status 0 接收通知, 1 不接收通知
155
+ args: [:openId, :conversationId, :status]
156
+ },
157
+ {
158
+ # 解散群聊会话
159
+ method_group: 'conversation',
160
+ method_name: 'disband',
161
+ http_method: :post,
162
+ url: 'disband',
163
+ args: [:openId, :conversationId]
164
+ },
165
+ {
166
+ # 查询有未读消息的会话
167
+ method_group: 'conversation',
168
+ method_pluralize: true,
169
+ method_name: 'unread',
170
+ http_method: :get,
171
+ url: 'unread',
172
+ args: [:openId, :cursor, :count]
173
+ },
174
+ {
175
+ # 查询会话成员列表
176
+ method_group: 'conversation',
177
+ method_name: 'members',
178
+ http_method: :get,
179
+ url: 'members/get',
180
+ args: [:openId, :conversationId, :offset, :count]
181
+ },
182
+ {
183
+ # 修改会话最大人数
184
+ method_group: 'conversation',
185
+ method_name: 'update_member_limit',
186
+ http_method: :post,
187
+ url: 'member/limit/update',
188
+ args: [:openId, :conversationId, :memberLimit]
189
+ },
190
+ {
191
+ # 修改会话为大群
192
+ method_group: 'conversation',
193
+ method_name: 'update_super',
194
+ http_method: :post,
195
+ url: 'member/super/update',
196
+ args: [:openId, :conversationId, :superGroup]
197
+ },
198
+ {
199
+ # 成员主动退出会话
200
+ method_group: 'conversation',
201
+ method_name: 'quit',
202
+ http_method: :post,
203
+ url: 'quit',
204
+ args: [:openId, :conversationId, :message]
205
+ },
206
+ {
207
+ # 会话成员主动退出会话,只给群主发消息
208
+ method_group: 'conversation',
209
+ method_name: 'quit_silent',
210
+ http_method: :post,
211
+ url: 'quit/silent',
212
+ args: [:openId, :conversationId, :message]
213
+ },
214
+ {
215
+ # 查询会话成员角色。角色的取值 1是群主,3 普通用户。返回data为空表示不是群成员
216
+ method_group: 'conversation',
217
+ method_name: 'role_list',
218
+ http_method: :post,
219
+ url: 'list/role',
220
+ args: [:openId, :conversationId, :message]
221
+ },
222
+ {
223
+ # 修改会话群主
224
+ method_group: 'conversation',
225
+ method_name: 'update_owner',
226
+ http_method: :post,
227
+ url: 'owner/update',
228
+ args: [:openId, :conversationId, :message]
229
+ },
230
+ {
231
+ # 查询最新的会话列表
232
+ method_group: 'conversation',
233
+ method_pluralize: true,
234
+ method_name: 'newest',
235
+ http_method: :get,
236
+ url: 'newest/get',
237
+ args: [:openId, :count]
238
+ },
239
+ {
240
+ # 清空会话消息
241
+ method_group: 'conversation',
242
+ method_name: 'clear',
243
+ http_method: :post,
244
+ url: 'message/clear',
245
+ args: [:openId, :conversationId]
246
+ },
247
+ {
248
+ # 会话置顶
249
+ method_group: 'conversation',
250
+ method_name: 'set_top',
251
+ http_method: :post,
252
+ url: 'top/set',
253
+ args: [:openId, :conversationId, :toTop]
254
+ },
255
+ {
256
+ # 修改会话状态
257
+ method_group: 'conversation',
258
+ method_name: 'update_status',
259
+ http_method: :post,
260
+ url: 'status/update',
261
+ args: [:openId, :conversationIds, :status]
262
+ },
263
+ {
264
+ # 修改会话扩展信息的特定属性
265
+ method_group: 'conversation',
266
+ method_name: 'update_exts',
267
+ http_method: :post,
268
+ url: 'extension/keys/update',
269
+ args: [:openId, :conversationIds, :extension]
270
+ },
271
+
272
+ # 聊天消息
273
+ {
274
+ # 向会话中发送消息,目前支持文字消息、图片消息、语音消息、语音图片消息、 文件消息、自定义消息。
275
+ # 文本消息是直接发送
276
+ # 图片、语音、文件等多媒体类型消息则是先上传文件然后再发送message
277
+ method_group: 'message',
278
+ method_name: 'send',
279
+ http_method: :post,
280
+ url: 'send',
281
+ # content封装不同的消息内容,具体json格式参阅 https://imwukong.com/#doc/doc/server/index.htm??聊天消息
282
+ args: [:senderId, :conversationId, :receivers, :msgType, :content,
283
+ :extension, :tag, :XpnParam, :priority]
284
+ },
285
+ {
286
+ # 查询单条消息
287
+ method_group: 'message',
288
+ method_name: 'query',
289
+ http_method: :get,
290
+ url: 'query',
291
+ args: [:openId, :messageId]
292
+ },
293
+ {
294
+ # 其实应该属于'聊天会话'分组, 悟空文档这样放, 就这样放吧 ~
295
+ # 查询会话的消息
296
+ method_group: 'conversation',
297
+ method_name: 'query',
298
+ http_method: :get,
299
+ url: 'messages/query',
300
+ args: [:openId, :conversationId, :cursor, :forward, :count]
301
+ },
302
+ {
303
+ # 设置消息为已读状态
304
+ method_group: 'message',
305
+ method_name: 'set_read',
306
+ http_method: :post,
307
+ url: 'set/read',
308
+ args: [:openId, :messageIds]
309
+ },
310
+ {
311
+ # 消息撤回
312
+ method_group: 'message',
313
+ method_name: 'recall',
314
+ http_method: :post,
315
+ url: 'recall',
316
+ args: [:openId, :messageId]
317
+ },
318
+ # 暂未开通
319
+ # {
320
+ # # 短信邮件发送消息
321
+ # # 会话好友没有安装应用时,可以通过短信邮件发送聊天消息
322
+ # method_group: 'message',
323
+ # method_name: 'sms',
324
+ # http_method: :post,
325
+ # url: 'sms/notice',
326
+ # args: [:openId, :openIds, :contacts, :conversationId, :type]
327
+ # },
328
+ {
329
+ # 获取一条消息未读人的列表
330
+ method_group: 'message',
331
+ method_name: 'unread_members',
332
+ http_method: :get,
333
+ url: 'member/unread',
334
+ args: [:openId, :messageId]
335
+ },
336
+ {
337
+ # 删除消息
338
+ method_group: 'message',
339
+ method_name: 'remove',
340
+ http_method: :post,
341
+ url: 'remove',
342
+ args: [:openId, :messageIds]
343
+ },
344
+ {
345
+ # 修改用户消息的私有tag和扩展信息
346
+ method_group: 'message',
347
+ method_name: 'update_member',
348
+ http_method: :post,
349
+ url: 'member/update',
350
+ args: [:openId, :messageId, :receiverIds, :tag, :extension]
351
+ },
352
+ {
353
+ # 修改消息的扩展信息
354
+ method_group: 'message',
355
+ method_name: 'update_ext',
356
+ http_method: :post,
357
+ url: 'ext/update',
358
+ args: [:openId, :messageId, :extension]
359
+ },
360
+
361
+ # 关注
362
+ {
363
+ # 加关注
364
+ method_group: 'relation',
365
+ method_name: 'follow',
366
+ http_method: :post,
367
+ url: 'status/follow',
368
+ args: [:myOpenId, :tag, :openId]
369
+ },
370
+ {
371
+ # 取消关注
372
+ method_group: 'relation',
373
+ method_name: 'unfollow',
374
+ http_method: :post,
375
+ url: 'status/unfollow',
376
+ args: [:myOpenId, :tag, :openId]
377
+ },
378
+ {
379
+ # 分页获取自己的关注列表
380
+ method_group: 'relation',
381
+ method_name: 'follow_list',
382
+ http_method: :get,
383
+ url: 'following/query',
384
+ # cursor, 第一次查询是0 ,后续查询取返回的nextCursor, nextCursor为-1表示无更多数据
385
+ args: [:openId, :tag, :cursor,:count]
386
+ },
387
+ {
388
+ # 分页获取双向关注列表
389
+ method_group: 'relation',
390
+ method_name: 'bi_follow_list',
391
+ http_method: :get,
392
+ url: 'binfollow/query',
393
+ args: [:openId, :tag, :cursor,:count]
394
+ },
395
+ {
396
+ # 分页获取关注自己的人的列表
397
+ method_group: 'relation',
398
+ method_name: 'follow_by_list',
399
+ http_method: :get,
400
+ url: 'followers/query',
401
+ args: [:openId, :tag, :cursor,:count]
402
+ },
403
+ {
404
+ # 获取自己与其他用户的关系
405
+ method_group: 'relation',
406
+ method_name: 'query',
407
+ http_method: :get,
408
+ url: 'status/query',
409
+ args: [:myOpenId, :tag, :peerOpenId]
410
+ },
411
+ {
412
+ # 分页获取关注和被关注列表
413
+ method_group: 'relation',
414
+ method_name: 'list',
415
+ http_method: :get,
416
+ url: 'all/query',
417
+ args: [:openId, :tag, :cursor,:count]
418
+ },
419
+
420
+
421
+ # 推送
422
+ {
423
+ # 修改会话扩展信息的特定属性
424
+ method_group: 'push',
425
+ prefix: 'v1',
426
+ method_name: 'to_user',
427
+ http_method: :post,
428
+ url: 'message/user',
429
+ # NotifyDataModel, 用户不在线的情况下,通过IOS APN、华为、小米通道下发的消息内容, 长度不超过256字节
430
+ # {
431
+ # alertContent 可选,推送到APN的内容,适用于华为、小米、IOS设备。 string
432
+ # badge 可选,app角标的增量数字,适用于IOS。 integer
433
+ # params 可选, 自定义传输参数, key-value列表,key和value都为字符串类型,适用于IOS json map对象
434
+ # sound 可选,推送消息提醒声音,应用中的音频资源名,支持aiff、wav、caf格式,适用于IOS。 string
435
+ # timeToLive 可选,APN保持持续时间,单位秒,适用于IOS,建议不要设置,使用默认的值。 integer
436
+ # }
437
+ # PushDataModel, 通过悟空PUSH长连接发下去的消息
438
+ # {
439
+ # content 消息内容。不能为空 string
440
+ # toWeb 可选,是否只推送到web。默认是false,推送到所有终端,包括web。 boolean
441
+ # type 用户定义的消息类型。 integer
442
+ # persist 是否持久化存储,默认为持久化存储。 boolean
443
+ # }
444
+ args: [:receiverId, :NotifyModel, :PushModel]
445
+ }
446
+ # 多个用户消息推送, 暂未开放
447
+ ]
448
+
449
+ instance_eval do
450
+ API_LIST.each do |api|
451
+ method_group = api[:method_pluralize] ? api[:method_group].pluralize : api[:method_group]
452
+ method_name = "wk_#{method_group}_#{api[:method_name]}"
453
+ fail "Method #{method_name} already defined" if respond_to?(method_name)
454
+ define_method method_name do |params|
455
+ check_params(params, api[:args]||[])
456
+ self.send "wk_#{api[:http_method]}", method_group, api[:url], api[:prefix]||'v1/im', params
457
+ end
458
+ end
459
+ end
460
+
461
+ WK_API_FORMAT = /^wk_[a-zA-Z0-9]+_[a-zA-Z0-9]+/.freeze
462
+ # output all APIs, format: wk_group_action
463
+ def wk_api_list
464
+ methods.grep(WK_API_FORMAT).sort
465
+ end
466
+
467
+ # api detail info, include request url & arguments
468
+ # @param api_method, string, default output information of all api
469
+ # @return an array of match api info string, format: api_name, REQUEST url, arguments symbol array
470
+ def wk_api_info(api_method='')
471
+ api_method ||= ''
472
+ fail 'Invalid wukong api' unless api_method == '' || api_method =~ WK_API_FORMAT
473
+ if api_method.size > 0
474
+ m = api_method.to_s.match(/^wk_([a-zA-Z0-9]+)_(.+)/)
475
+ method_group = m[1].singularize
476
+ method_name = m[2]
477
+ end
478
+ apis = api_method.size > 0 ? API_LIST.select { |a| a[:method_group]==method_group && method_name==a[:method_name] } : API_LIST
479
+ fail 'api not found' unless apis.present?
480
+ apis.map do |api|
481
+ method_group = api[:method_pluralize] ? api[:method_group].pluralize : api[:method_group]
482
+ method_name = "wk_#{method_group}_#{api[:method_name]}"
483
+ "#{method_name}, #{api_url(api)}, #{api[:args].inspect} "
484
+ end
485
+ end
486
+
487
+ private
488
+
489
+ def api_url(api)
490
+ http_method = api[:http_method].to_s.upcase
491
+ prefix = api[:prefix] ? api[:prefix] : 'v1/im'
492
+ group = api[:method_pluralize] ? api[:method_group].pluralize : api[:method_group]
493
+ url = "#{prefix}/#{group}/#{api[:url]}"
494
+ "#{http_method} #{url}"
495
+ end
496
+
497
+ def check_params(params, check_list=[])
498
+ check_list.each do |key|
499
+ fail "argument required: #{key}" unless params.has_key?(key) || params.has_key?(key.to_sym)
500
+ end
501
+ end
502
+ end
503
+ end
@@ -0,0 +1,90 @@
1
+ require 'httparty'
2
+ require 'digest'
3
+
4
+ module Imwukong
5
+ class Base
6
+ include HTTParty
7
+ # include Api::User
8
+ # include Api::Conversation
9
+ # include Api::Message
10
+ # include Api::Follow
11
+ # include Api::Upload
12
+ # include Api::Push
13
+
14
+ DEFAULT_OPTIONS = { api_version: 'v1' }
15
+ DEV_HOST = 'https://sandbox-wkapi.laiwang.com'.freeze
16
+ PRODUCTION_HOST = "https://wkapi.laiwang.com"
17
+
18
+ def initialize(app_domain = Imwukong.config[:domain],
19
+ app_token = Imwukong.config[:server][:app_token])
20
+ fail 'app domain/token is invalid' unless app_domain.present? && app_token.present?
21
+ @app_domain = app_domain.strip
22
+ @app_token = app_token.strip
23
+ @options = DEFAULT_OPTIONS
24
+ end
25
+
26
+ def wk_post(type, method, prefix='v1/im', params)
27
+ options = {
28
+ body: params.to_json,
29
+ headers: wukong_header
30
+ }
31
+ prefix ||= 'v1/im'
32
+ result = self.class.send(:post, get_request_url(type, method, prefix), options) rescue nil
33
+ handle_response(result)
34
+ end
35
+
36
+ def wk_get(type, method, prefix='v1/im', params)
37
+ options = {
38
+ query: params,
39
+ headers: wukong_header
40
+ }
41
+ prefix ||= 'v1/im'
42
+ result = self.class.send(:get, get_request_url(type, method, prefix), options) rescue nil
43
+ handle_response(result)
44
+ end
45
+
46
+ # def safe_json_parse(data)
47
+ # warn data.inspect
48
+ # JSON.parse(data)
49
+ # # rescue TypeError which will cause 'no implicit conversion of HTTParty::Response into String'
50
+ # rescue JSON::ParserError, TypeError
51
+ # {}
52
+ # end
53
+
54
+ private
55
+
56
+ def handle_response(result)
57
+ fail 'No respond from server' if result.nil?
58
+ warn ">>> Code: #{result.code}, " + result.inspect
59
+ r = result.parsed_response
60
+ fail result.inspect unless result.code == 200
61
+ fail "#{r['errorCode']}, #{r['errorMessage']}" if r['success'] == false
62
+ r['data']
63
+ end
64
+
65
+ def wukong_host
66
+ Imwukong.config[:env] == 'production' ? PRODUCTION_HOST : DEV_HOST
67
+ end
68
+
69
+ def get_request_url(type, method, prefix='v1/im')
70
+ warn "#{wukong_host}/#{prefix}/#{type}/#{method}"
71
+ "#{wukong_host}/#{prefix}/#{type}/#{method}"
72
+ end
73
+
74
+ def wukong_sign(token = @app_token)
75
+ @timestamp = Time.now.to_i.to_s
76
+ @nonce = rand(100000..200000).to_s
77
+ array = [token, @timestamp, @nonce].sort
78
+ sign = Digest::SHA1.hexdigest(array.join)
79
+ warn "Sign: #{sign}"
80
+ sign
81
+ end
82
+
83
+ def wukong_header
84
+ {
85
+ 'Authorization' => %Q(Wukong signature_method="sha1", domain="#{@app_domain}", signature="#{wukong_sign}", timestamp="#{@timestamp}", nonce="#{@nonce}", version="1.0"),
86
+ 'Content-Type' => 'application/json'
87
+ }
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,35 @@
1
+ require 'digest/sha2'
2
+ module Imwukong
3
+ # implement 阿里悟空支持的免导入登录方式
4
+ # 根据客户端类型(ios, android, web)返回 signature、domain、appkey、timestamp 等数据给客户端
5
+ # 客户端调用阿里悟空的SDK接口完成登录鉴权
6
+ # 目前采用openid就是用户应用的userid, 其唯一性由用户应用系统保障
7
+ class Client
8
+ def signature(open_id, dev_type)
9
+ fail %Q(unknown device type "#{dev_type}") unless %w(ios android).include?(dev_type)
10
+ begin
11
+ app_token = Imwukong.config[:server][:app_token]
12
+ app_key = Imwukong.config[dev_type.to_sym][:app_key]
13
+ app_secret = Imwukong.config[dev_type.to_sym][:app_secret]
14
+ rescue
15
+ raise 'Please check you configuration of imwukong'
16
+ end
17
+ nonce = rand(100000..200000)
18
+ timestamp = Time.now.to_i
19
+ {
20
+ signature: gen_signature(open_id, app_token, app_secret, nonce, timestamp),
21
+ domain: Imwukong.config[:domain],
22
+ open_id: open_id,
23
+ app_key: app_key,
24
+ nonce: nonce,
25
+ timestamp: timestamp
26
+ }
27
+ end
28
+
29
+ private
30
+
31
+ def gen_signature(open_id, app_token, app_secret, nonce, timestamp)
32
+ Digest::SHA256.hexdigest([app_token, app_secret, open_id.to_s, nonce.to_s, timestamp.to_s].sort.join(''))
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,30 @@
1
+ module Imwukong
2
+
3
+ @config = {
4
+ env: 'development',
5
+ domain: 'test-sjll',
6
+ android: {
7
+ app_key: 'c3a2bdb574663c955f5bceeb95ad4eec',
8
+ app_secret: 'Snnmp8aepflORdsWdTjuNLXHPv4FpJki'
9
+ },
10
+ ios: {
11
+ app_key: '1f49803aa33122c8ed11df493f8d843f',
12
+ app_secret: 'Sn0NwAYBIeUT8DPoR9IP9hhqTD1SBf0o'
13
+ },
14
+ web: {
15
+ app_key: 'c26cf651de1ef9f583677e73271c7396',
16
+ app_secret: 'S0Iq3cBlJd91v0VvwiqziYmQx5hcsdIV'
17
+ },
18
+ server: {
19
+ app_token: 'SpBzEmucvdmCYbzHJJ0js7MhVIlJsm00'
20
+ }
21
+ }
22
+
23
+ class << self
24
+ attr_accessor :config
25
+
26
+ def configure
27
+ yield @config if block_given?
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module Imwukong
2
+ VERSION = "0.1.4"
3
+ end
data/lib/imwukong.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'imwukong/version'
2
+ require 'imwukong/config'
3
+ require 'imwukong/base'
4
+ require 'imwukong/api'
5
+ require 'imwukong/client'
6
+ module Imwukong
7
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: imwukong
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Danny Xu
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-12-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: httparty
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.13.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.13.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 4.2.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 4.2.0
83
+ description: ruby server api for imwukong of alibaba
84
+ email:
85
+ - dannyxu@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - Gemfile
92
+ - Gemfile.lock
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - bin/console
97
+ - bin/setup
98
+ - imwukong.gemspec
99
+ - lib/imwukong.rb
100
+ - lib/imwukong/api-obsolete.rb
101
+ - lib/imwukong/api-obsolete/conversation.rb
102
+ - lib/imwukong/api-obsolete/follow.rb
103
+ - lib/imwukong/api-obsolete/message.rb
104
+ - lib/imwukong/api-obsolete/push.rb
105
+ - lib/imwukong/api-obsolete/upload.rb
106
+ - lib/imwukong/api-obsolete/user.rb
107
+ - lib/imwukong/api.rb
108
+ - lib/imwukong/base.rb
109
+ - lib/imwukong/client.rb
110
+ - lib/imwukong/config.rb
111
+ - lib/imwukong/version.rb
112
+ homepage: https://github.com/dannyxu2015/imwukong
113
+ licenses:
114
+ - MIT
115
+ metadata: {}
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubyforge_project:
132
+ rubygems_version: 2.4.8
133
+ signing_key:
134
+ specification_version: 4
135
+ summary: I am Wukong!
136
+ test_files: []