slack-ruby-client 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.gitmodules +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +6 -0
- data/.rubocop_todo.yml +34 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +4 -0
- data/CONTRIBUTING.md +139 -0
- data/Gemfile +3 -0
- data/LICENSE.md +22 -0
- data/README.md +123 -0
- data/RELEASING.md +67 -0
- data/Rakefile +19 -0
- data/examples/hi_real_time/Gemfile +3 -0
- data/examples/hi_real_time/hi.gif +0 -0
- data/examples/hi_real_time/hi.rb +27 -0
- data/examples/hi_real_time_and_web/Gemfile +3 -0
- data/examples/hi_real_time_and_web/hi.gif +0 -0
- data/examples/hi_real_time_and_web/hi.rb +24 -0
- data/examples/hi_web/Gemfile +3 -0
- data/examples/hi_web/hi.gif +0 -0
- data/examples/hi_web/hi.rb +14 -0
- data/lib/slack-ruby-client.rb +23 -0
- data/lib/slack.rb +1 -0
- data/lib/slack/config.rb +17 -0
- data/lib/slack/real_time/api/message.rb +20 -0
- data/lib/slack/real_time/api/message_id.rb +14 -0
- data/lib/slack/real_time/api/ping.rb +16 -0
- data/lib/slack/real_time/api/typing.rb +17 -0
- data/lib/slack/real_time/client.rb +91 -0
- data/lib/slack/real_time/socket.rb +41 -0
- data/lib/slack/version.rb +3 -0
- data/lib/slack/web/api/endpoints.rb +39 -0
- data/lib/slack/web/api/endpoints/api.rb +25 -0
- data/lib/slack/web/api/endpoints/auth.rb +21 -0
- data/lib/slack/web/api/endpoints/channels.rb +216 -0
- data/lib/slack/web/api/endpoints/chat.rb +78 -0
- data/lib/slack/web/api/endpoints/emoji.rb +21 -0
- data/lib/slack/web/api/endpoints/files.rb +76 -0
- data/lib/slack/web/api/endpoints/groups.rb +229 -0
- data/lib/slack/web/api/endpoints/im.rb +82 -0
- data/lib/slack/web/api/endpoints/oauth.rb +32 -0
- data/lib/slack/web/api/endpoints/presence.rb +24 -0
- data/lib/slack/web/api/endpoints/rtm.rb +21 -0
- data/lib/slack/web/api/endpoints/search.rb +68 -0
- data/lib/slack/web/api/endpoints/stars.rb +23 -0
- data/lib/slack/web/api/endpoints/users.rb +70 -0
- data/lib/slack/web/api/error.rb +8 -0
- data/lib/slack/web/api/schema/method.json +45 -0
- data/lib/slack/web/api/tasks/generate.rake +37 -0
- data/lib/slack/web/api/templates/endpoints.erb +17 -0
- data/lib/slack/web/api/templates/method.erb +39 -0
- data/lib/slack/web/client.rb +17 -0
- data/lib/slack/web/config.rb +36 -0
- data/lib/slack/web/faraday/connection.rb +25 -0
- data/lib/slack/web/faraday/request.rb +39 -0
- data/lib/slack/web/faraday/response/raise_error.rb +14 -0
- data/lib/slack_ruby_client.rb +1 -0
- data/screenshots/register-bot.png +0 -0
- data/slack-ruby-client.gemspec +28 -0
- data/spec/fixtures/slack/web/auth_test_error.yml +48 -0
- data/spec/fixtures/slack/web/auth_test_success.yml +57 -0
- data/spec/fixtures/slack/web/rtm_start.yml +73 -0
- data/spec/slack/config_spec.rb +14 -0
- data/spec/slack/real_time/api/message_spec.rb +15 -0
- data/spec/slack/real_time/api/ping_spec.rb +15 -0
- data/spec/slack/real_time/api/typing_spec.rb +15 -0
- data/spec/slack/real_time/client_spec.rb +51 -0
- data/spec/slack/real_time/socket_spec.rb +42 -0
- data/spec/slack/version_spec.rb +7 -0
- data/spec/slack/web/api/endpoints/auth_spec.rb +15 -0
- data/spec/slack/web/client_spec.rb +31 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/real_time/connected_client.rb +13 -0
- data/spec/support/vcr.rb +8 -0
- metadata +287 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module Slack
|
2
|
+
module Web
|
3
|
+
module Faraday
|
4
|
+
module Connection
|
5
|
+
private
|
6
|
+
|
7
|
+
def connection
|
8
|
+
options = {
|
9
|
+
headers: { 'Accept' => 'application/json; charset=utf-8', 'User-Agent' => user_agent },
|
10
|
+
url: endpoint
|
11
|
+
}
|
12
|
+
|
13
|
+
::Faraday::Connection.new(options) do |connection|
|
14
|
+
connection.use ::Faraday::Request::Multipart
|
15
|
+
connection.use ::Faraday::Request::UrlEncoded
|
16
|
+
connection.use ::Faraday::Response::RaiseError
|
17
|
+
connection.use ::Slack::Web::Faraday::Response::RaiseError
|
18
|
+
connection.use ::FaradayMiddleware::ParseJson
|
19
|
+
connection.adapter(::Faraday.default_adapter)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Slack
|
2
|
+
module Web
|
3
|
+
module Faraday
|
4
|
+
module Request
|
5
|
+
def get(path, options = {})
|
6
|
+
request(:get, path, options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def post(path, options = {})
|
10
|
+
request(:post, path, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def put(path, options = {})
|
14
|
+
request(:put, path, options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def delete(path, options = {})
|
18
|
+
request(:delete, path, options)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def request(method, path, options)
|
24
|
+
options = options.merge(token: Slack.config.token)
|
25
|
+
response = connection.send(method) do |request|
|
26
|
+
case method
|
27
|
+
when :get, :delete
|
28
|
+
request.url(path, options)
|
29
|
+
when :post, :put
|
30
|
+
request.path = path
|
31
|
+
request.body = options unless options.empty?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
response.body
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Slack
|
2
|
+
module Web
|
3
|
+
module Faraday
|
4
|
+
module Response
|
5
|
+
class RaiseError < ::Faraday::Response::Middleware
|
6
|
+
def on_complete(env)
|
7
|
+
body = env.body
|
8
|
+
fail Slack::Web::Api::Error, body['error'] unless body['ok']
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'slack-ruby-client'
|
Binary file
|
@@ -0,0 +1,28 @@
|
|
1
|
+
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
2
|
+
require 'slack/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'slack-ruby-client'
|
6
|
+
s.version = Slack::VERSION
|
7
|
+
s.authors = ['Daniel Doubrovkine']
|
8
|
+
s.email = 'dblock@dblock.org'
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.required_rubygems_version = '>= 1.3.6'
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
13
|
+
s.require_paths = ['lib']
|
14
|
+
s.homepage = 'http://github.com/dblock/slack-ruby-client'
|
15
|
+
s.licenses = ['MIT']
|
16
|
+
s.summary = 'Slack Web and RealTime API client.'
|
17
|
+
s.add_dependency 'faraday'
|
18
|
+
s.add_dependency 'faraday_middleware'
|
19
|
+
s.add_dependency 'faye-websocket'
|
20
|
+
s.add_dependency 'eventmachine'
|
21
|
+
s.add_development_dependency 'erubis'
|
22
|
+
s.add_development_dependency 'json-schema'
|
23
|
+
s.add_development_dependency 'rake'
|
24
|
+
s.add_development_dependency 'rspec'
|
25
|
+
s.add_development_dependency 'vcr'
|
26
|
+
s.add_development_dependency 'webmock'
|
27
|
+
s.add_development_dependency 'rubocop', '0.32.1'
|
28
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://slack.com/api/auth.test
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: token=
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- application/json; charset=utf-8
|
12
|
+
User-Agent:
|
13
|
+
- Slack Ruby Client 0.1.0
|
14
|
+
Content-Type:
|
15
|
+
- application/x-www-form-urlencoded
|
16
|
+
Accept-Encoding:
|
17
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Access-Control-Allow-Origin:
|
24
|
+
- "*"
|
25
|
+
Content-Type:
|
26
|
+
- application/json; charset=utf-8
|
27
|
+
Date:
|
28
|
+
- Sat, 25 Jul 2015 14:42:07 GMT
|
29
|
+
Server:
|
30
|
+
- Apache
|
31
|
+
Strict-Transport-Security:
|
32
|
+
- max-age=31536000; includeSubDomains; preload
|
33
|
+
Vary:
|
34
|
+
- Accept-Encoding
|
35
|
+
X-Content-Type-Options:
|
36
|
+
- nosniff
|
37
|
+
X-Xss-Protection:
|
38
|
+
- '0'
|
39
|
+
Content-Length:
|
40
|
+
- '53'
|
41
|
+
Connection:
|
42
|
+
- keep-alive
|
43
|
+
body:
|
44
|
+
encoding: UTF-8
|
45
|
+
string: '{"ok":false,"error":"not_authed"}'
|
46
|
+
http_version:
|
47
|
+
recorded_at: Sat, 25 Jul 2015 14:42:08 GMT
|
48
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,57 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://slack.com/api/auth.test
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: token=token
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- application/json; charset=utf-8
|
12
|
+
User-Agent:
|
13
|
+
- Slack Ruby Gem 1.1.1
|
14
|
+
Content-Type:
|
15
|
+
- application/x-www-form-urlencoded
|
16
|
+
Accept-Encoding:
|
17
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Access-Control-Allow-Origin:
|
24
|
+
- '*'
|
25
|
+
Cache-Control:
|
26
|
+
- private, no-cache, no-store, must-revalidate
|
27
|
+
Content-Type:
|
28
|
+
- application/json; charset=utf-8
|
29
|
+
Date:
|
30
|
+
- Tue, 28 Apr 2015 12:55:23 GMT
|
31
|
+
Expires:
|
32
|
+
- Mon, 26 Jul 1997 05:00:00 GMT
|
33
|
+
Pragma:
|
34
|
+
- no-cache
|
35
|
+
Server:
|
36
|
+
- Apache
|
37
|
+
Strict-Transport-Security:
|
38
|
+
- max-age=31536000; includeSubDomains; preload
|
39
|
+
Vary:
|
40
|
+
- Accept-Encoding
|
41
|
+
X-Accepted-Oauth-Scopes:
|
42
|
+
- identify
|
43
|
+
X-Content-Type-Options:
|
44
|
+
- nosniff
|
45
|
+
X-Oauth-Scopes:
|
46
|
+
- identify,read,post,client
|
47
|
+
X-Xss-Protection:
|
48
|
+
- '0'
|
49
|
+
Content-Length:
|
50
|
+
- '128'
|
51
|
+
Connection:
|
52
|
+
- keep-alive
|
53
|
+
body:
|
54
|
+
encoding: UTF-8
|
55
|
+
string: '{"ok":true,"url":"https:\/\/rubybot.slack.com\/","team":"team_name","user":"user_name","team_id":"TDEADBEEF","user_id":"UBAADFOOD"}'
|
56
|
+
http_version:
|
57
|
+
recorded_at: Tue, 28 Apr 2015 12:55:22 GMT
|
@@ -0,0 +1,73 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://slack.com/api/rtm.start
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: token=xoxb-7171717171-ABCDEFGhIJ2lZifrEaQP5vF4
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- application/json; charset=utf-8
|
12
|
+
User-Agent:
|
13
|
+
- Slack Ruby Client 0.1.0
|
14
|
+
Content-Type:
|
15
|
+
- application/x-www-form-urlencoded
|
16
|
+
Accept-Encoding:
|
17
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Access-Control-Allow-Origin:
|
24
|
+
- "*"
|
25
|
+
Cache-Control:
|
26
|
+
- private, no-cache, no-store, must-revalidate
|
27
|
+
Content-Type:
|
28
|
+
- application/json; charset=utf-8
|
29
|
+
Date:
|
30
|
+
- Sat, 25 Jul 2015 16:10:31 GMT
|
31
|
+
Expires:
|
32
|
+
- Mon, 26 Jul 1997 05:00:00 GMT
|
33
|
+
Pragma:
|
34
|
+
- no-cache
|
35
|
+
Server:
|
36
|
+
- Apache
|
37
|
+
Strict-Transport-Security:
|
38
|
+
- max-age=31536000; includeSubDomains; preload
|
39
|
+
Vary:
|
40
|
+
- Accept-Encoding
|
41
|
+
X-Accepted-Oauth-Scopes:
|
42
|
+
- client
|
43
|
+
X-Content-Type-Options:
|
44
|
+
- nosniff
|
45
|
+
X-Oauth-Scopes:
|
46
|
+
- identify,read,post,client
|
47
|
+
X-Xss-Protection:
|
48
|
+
- '0'
|
49
|
+
Content-Length:
|
50
|
+
- '3681'
|
51
|
+
Connection:
|
52
|
+
- keep-alive
|
53
|
+
body:
|
54
|
+
encoding: UTF-8
|
55
|
+
string: '{"ok":true,"self":{"id":"U07518DTL","name":"rubybot","prefs":{"highlight_words":"","user_colors":"","color_names_in_list":true,"growls_enabled":true,"tz":null,"push_dm_alert":true,"push_mention_alert":true,"push_everything":true,"push_idle_wait":2,"push_sound":"b2.mp3","push_loud_channels":"","push_mention_channels":"","push_loud_channels_set":"","email_alerts":"instant","email_alerts_sleep_until":0,"email_misc":true,"email_weekly":true,"welcome_message_hidden":false,"all_channels_loud":true,"loud_channels":"","never_channels":"","loud_channels_set":"","show_member_presence":true,"search_sort":"timestamp","expand_inline_imgs":true,"expand_internal_inline_imgs":true,"expand_snippets":false,"posts_formatting_guide":true,"seen_welcome_2":false,"seen_ssb_prompt":false,"seen_spaces_new_xp_tooltip":false,"spaces_new_xp_banner_dismissed":false,"search_only_my_channels":false,"emoji_mode":"default","emoji_use":"","has_invited":false,"has_uploaded":false,"has_created_channel":false,"search_exclude_channels":"","messages_theme":"default","webapp_spellcheck":true,"no_joined_overlays":false,"no_created_overlays":false,"dropbox_enabled":false,"seen_domain_invite_reminder":false,"seen_member_invite_reminder":false,"mute_sounds":false,"arrow_history":false,"tab_ui_return_selects":true,"obey_inline_img_limit":true,"new_msg_snd":"knock_brush.mp3","collapsible":false,"collapsible_by_click":true,"require_at":false,"ssb_space_window":"","mac_ssb_bounce":"","mac_ssb_bullet":true,"expand_non_media_attachments":true,"show_typing":true,"pagekeys_handled":true,"last_snippet_type":"","display_real_names_override":0,"time24":false,"enter_is_special_in_tbt":false,"graphic_emoticons":false,"convert_emoticons":true,"autoplay_chat_sounds":true,"ss_emojis":true,"sidebar_behavior":"","seen_onboarding_start":false,"onboarding_cancelled":false,"seen_onboarding_slackbot_conversation":false,"seen_onboarding_channels":false,"seen_onboarding_direct_messages":false,"seen_onboarding_invites":false,"seen_onboarding_search":false,"seen_onboarding_recent_mentions":false,"seen_onboarding_starred_items":false,"seen_onboarding_private_groups":false,"onboarding_slackbot_conversation_step":0,"mark_msgs_read_immediately":true,"start_scroll_at_oldest":true,"snippet_editor_wrap_long_lines":false,"ls_disabled":false,"sidebar_theme":"default","sidebar_theme_custom_values":"","f_key_search":false,"k_key_omnibox":true,"speak_growls":false,"mac_speak_voice":"com.apple.speech.synthesis.voice.Alex","mac_speak_speed":250,"comma_key_prefs":false,"at_channel_suppressed_channels":"","push_at_channel_suppressed_channels":"","prompted_for_email_disabling":false,"full_text_extracts":false,"no_text_in_notifications":false,"muted_channels":"","no_macssb1_banner":false,"no_winssb1_banner":false,"no_omnibox_in_channels":false,"k_key_omnibox_auto_hide_count":0,"privacy_policy_seen":true,"search_exclude_bots":false,"fuzzy_matching":false,"load_lato_2":false,"fuller_timestamps":false,"last_seen_at_channel_warning":0,"flex_resize_window":false,"msg_preview":false,"msg_preview_displaces":true,"msg_preview_persistent":true,"emoji_autocomplete_big":false,"winssb_run_from_tray":true,"two_factor_auth_enabled":false,"two_factor_type":null,"mentions_exclude_at_channels":true,"confirm_clear_all_unreads":true,"confirm_user_marked_away":true,"box_enabled":false,"seen_single_emoji_msg":false,"confirm_sh_call_start":true},"created":1435864712,"manual_presence":"active"},"team":{"id":"T04KB5WQH","name":"dblock","email_domain":"dblock.org","domain":"dblockdotorg","msg_edit_window_mins":-1,"prefs":{"default_channels":["C04KB5X4D","C04KB5X4Z"],"msg_edit_window_mins":-1,"allow_message_deletion":true,"hide_referers":true,"display_real_names":false,"who_can_at_everyone":"regular","who_can_at_channel":"ra","warn_before_at_channel":"always","who_can_create_channels":"regular","who_can_archive_channels":"regular","who_can_create_groups":"ra","who_can_post_general":"ra","who_can_kick_channels":"admin","who_can_kick_groups":"regular","retention_type":0,"retention_duration":0,"group_retention_type":0,"group_retention_duration":0,"dm_retention_type":0,"dm_retention_duration":0,"file_retention_type":0,"file_retention_duration":0,"require_at_for_mention":0,"compliance_export_start":0,"auth_mode":"normal"},"icon":{"image_34":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4657218807_d480d2ee610d2e8aacfe_34.jpg","image_44":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4657218807_d480d2ee610d2e8aacfe_44.jpg","image_68":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4657218807_d480d2ee610d2e8aacfe_68.jpg","image_88":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4657218807_d480d2ee610d2e8aacfe_88.jpg","image_102":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4657218807_d480d2ee610d2e8aacfe_102.jpg","image_132":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4657218807_d480d2ee610d2e8aacfe_132.jpg","image_original":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4657218807_d480d2ee610d2e8aacfe_original.jpg"},"over_storage_limit":false,"plan":""},"latest_event_ts":"1437840032.000000","channels":[{"id":"C06JKEMJ8","name":"demo","is_channel":true,"created":1434735992,"creator":"U04KB5WQR","is_archived":false,"is_general":false,"has_pins":false,"is_member":false},{"id":"C06JKF1QQ","name":"example","is_channel":true,"created":1434736136,"creator":"U04KB5WQR","is_archived":false,"is_general":false,"has_pins":false,"is_member":false},{"id":"C04KB5X4D","name":"general","is_channel":true,"created":1430222230,"creator":"U04KB5WQR","is_archived":false,"is_general":true,"has_pins":false,"is_member":true,"last_read":"1435863302.000026","latest":{"type":"message","user":"U04KB5WQR","text":"aws
|
56
|
+
typing","ts":"1437675919.000050"},"unread_count":161,"unread_count_display":159,"members":["U04JPQ0JS","U04JZBDQQ","U04KB5WQR","U06JGTU5V","U07518DTL","U07KECJ77"],"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This
|
57
|
+
channel is for team-wide communication and announcements. All team members
|
58
|
+
are in this channel.","creator":"","last_set":0}},{"id":"C06JH25U4","name":"math","is_channel":true,"created":1434733062,"creator":"U04KB5WQR","is_archived":false,"is_general":false,"has_pins":false,"is_member":false},{"id":"C04M42N6Z","name":"mattz","is_channel":true,"created":1430514740,"creator":"U04KB5WQR","is_archived":false,"is_general":false,"has_pins":false,"is_member":false},{"id":"C04KB5X4Z","name":"random","is_channel":true,"created":1430222230,"creator":"U04KB5WQR","is_archived":false,"is_general":false,"has_pins":false,"is_member":false},{"id":"C0751A9HC","name":"rubybot-demo","is_channel":true,"created":1435864859,"creator":"U04KB5WQR","is_archived":false,"is_general":false,"has_pins":false,"is_member":true,"last_read":"1435864859.000002","latest":{"type":"message","user":"U04KB5WQR","text":"<@U04JPQ0JS>
|
59
|
+
hi","ts":"1436471528.000006"},"unread_count":4,"unread_count_display":3,"members":["U04KB5WQR","U07518DTL"],"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"","creator":"","last_set":0}},{"id":"C07S5SGGN","name":"weather","is_channel":true,"created":1437323916,"creator":"U04KB5WQR","is_archived":false,"is_general":false,"has_pins":false,"is_member":true,"last_read":"1437323916.000002","latest":{"type":"message","user":"U07518DTL","text":"The
|
60
|
+
weather in Moscow is nice.","ts":"1437323954.000005"},"unread_count":3,"unread_count_display":1,"members":["U04KB5WQR","U07518DTL"],"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"","creator":"","last_set":0}}],"groups":[],"ims":[{"id":"D07519J57","is_im":true,"user":"USLACKBOT","created":1435864712,"last_read":"0000000000.000000","latest":null,"unread_count":0,"unread_count_display":0,"is_open":true},{"id":"D0751GYBD","is_im":true,"user":"U04KB5WQR","created":1435864712,"last_read":"0000000000.000000","latest":{"type":"message","user":"U07518DTL","text":"The
|
61
|
+
weather in Moscow is nice.","ts":"1437323749.000013"},"unread_count":11,"unread_count_display":8,"is_open":true}],"users":[{"id":"U07KECJ77","name":"aws","deleted":false,"status":null,"color":"e96699","real_name":"AWS
|
62
|
+
Cloud","tz":null,"tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"bot_id":"B07KECJ6R","image_24":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-14\/7660472085_4755a86e204c9706c84f_24.jpg","image_32":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-14\/7660472085_4755a86e204c9706c84f_32.jpg","image_48":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-14\/7660472085_4755a86e204c9706c84f_48.jpg","image_72":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-14\/7660472085_4755a86e204c9706c84f_48.jpg","image_192":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-14\/7660472085_4755a86e204c9706c84f_48.jpg","image_original":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-14\/7660472085_4755a86e204c9706c84f_original.jpg","first_name":"AWS","last_name":"Cloud","real_name":"AWS
|
63
|
+
Cloud","real_name_normalized":"AWS Cloud"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"has_files":false,"presence":"away"},{"id":"U04KB5WQR","name":"dblock","deleted":false,"status":null,"color":"9f69e7","real_name":"","tz":"America\/Indiana\/Indianapolis","tz_label":"Eastern
|
64
|
+
Daylight Time","tz_offset":-14400,"profile":{"real_name":"","real_name_normalized":"","email":"dblock@dblock.org","image_24":"https:\/\/secure.gravatar.com\/avatar\/3d925b45ac07ec0ae5bd04888f6c5b61.jpg?s=24&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F3654%2Fimg%2Favatars%2Fava_0015-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/3d925b45ac07ec0ae5bd04888f6c5b61.jpg?s=32&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F3654%2Fimg%2Favatars%2Fava_0015-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/3d925b45ac07ec0ae5bd04888f6c5b61.jpg?s=48&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F3654%2Fimg%2Favatars%2Fava_0015-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/3d925b45ac07ec0ae5bd04888f6c5b61.jpg?s=72&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F3654%2Fimg%2Favatars%2Fava_0015-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/3d925b45ac07ec0ae5bd04888f6c5b61.jpg?s=192&d=https%3A%2F%2Fslack.global.ssl.fastly.net%2F272a%2Fimg%2Favatars%2Fava_0015.png"},"is_admin":true,"is_owner":true,"is_primary_owner":true,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"has_files":false,"presence":"active"},{"id":"U04JZBDQQ","name":"foo","deleted":true,"profile":{"bot_id":"B04JZBDQC","image_24":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4645387956_44604ca32e800d947f22_24.jpg","image_32":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4645387956_44604ca32e800d947f22_32.jpg","image_48":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4645387956_44604ca32e800d947f22_48.jpg","image_72":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4645387956_44604ca32e800d947f22_72.jpg","image_192":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4645387956_44604ca32e800d947f22_192.jpg","image_original":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4645387956_44604ca32e800d947f22_original.jpg","real_name":"","real_name_normalized":""},"is_bot":true,"has_files":false,"presence":"away"},{"id":"U04JPQ0JS","name":"gamebot","deleted":false,"status":null,"color":"4bbe2e","real_name":"Game
|
65
|
+
Bot","tz":null,"tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"bot_id":"B04JPQ0JE","image_24":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4635825662_28d3661bf00dc6013442_24.jpg","image_32":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4635825662_28d3661bf00dc6013442_32.jpg","image_48":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4635825662_28d3661bf00dc6013442_48.jpg","image_72":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4635825662_28d3661bf00dc6013442_48.jpg","image_192":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4635825662_28d3661bf00dc6013442_48.jpg","image_original":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-04-28\/4635825662_28d3661bf00dc6013442_original.jpg","first_name":"Game","last_name":"Bot","title":"Game
|
66
|
+
ons.","real_name":"Game Bot","real_name_normalized":"Game Bot"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"has_files":false,"presence":"away"},{"id":"U06JGTU5V","name":"mathbot","deleted":false,"status":null,"color":"3c989f","real_name":"Math
|
67
|
+
Bot","tz":null,"tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"bot_id":"B06JH1N93","image_24":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_24.jpg","image_32":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_32.jpg","image_48":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_48.jpg","image_72":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_48.jpg","image_192":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_48.jpg","image_original":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-06-19\/6629501812_c507c80d735dfc75bbc8_original.jpg","first_name":"Math","last_name":"Bot","real_name":"Math
|
68
|
+
Bot","real_name_normalized":"Math Bot"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"has_files":false,"presence":"away"},{"id":"U07518DTL","name":"rubybot","deleted":false,"status":null,"color":"674b1b","real_name":"","tz":null,"tz_label":"Pacific
|
69
|
+
Daylight Time","tz_offset":-25200,"profile":{"bot_id":"B0751JU2H","image_24":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-02\/7171641589_359bf095c1fe0841e582_24.jpg","image_32":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-02\/7171641589_359bf095c1fe0841e582_32.jpg","image_48":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-02\/7171641589_359bf095c1fe0841e582_48.jpg","image_72":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-02\/7171641589_359bf095c1fe0841e582_48.jpg","image_192":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-02\/7171641589_359bf095c1fe0841e582_48.jpg","image_original":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2015-07-02\/7171641589_359bf095c1fe0841e582_original.jpg","real_name":"","real_name_normalized":""},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"has_files":false,"presence":"away"},{"id":"USLACKBOT","name":"slackbot","deleted":false,"status":null,"color":"757575","real_name":"slackbot","tz":null,"tz_label":"Pacific
|
70
|
+
Daylight Time","tz_offset":-25200,"profile":{"first_name":"slackbot","last_name":"","image_24":"https:\/\/slack-assets2.s3-us-west-2.amazonaws.com\/10068\/img\/slackbot_24.png","image_32":"https:\/\/slack-assets2.s3-us-west-2.amazonaws.com\/10068\/img\/slackbot_32.png","image_48":"https:\/\/slack-assets2.s3-us-west-2.amazonaws.com\/10068\/img\/slackbot_48.png","image_72":"https:\/\/slack-assets2.s3-us-west-2.amazonaws.com\/10068\/img\/slackbot_72.png","image_192":"https:\/\/slack-assets2.s3-us-west-2.amazonaws.com\/10068\/img\/slackbot_192.png","real_name":"slackbot","real_name_normalized":"slackbot","email":null},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"presence":"active"}],"cache_ts":1437840632,"cache_version":"v10-dog","bots":[{"id":"B04JPQ0JE","name":"bot","deleted":false,"icons":{"image_48":"https:\/\/slack.global.ssl.fastly.net\/93ed\/img\/services\/bots_48.png"}},{"id":"B04JZBDQC","name":"bot","deleted":false,"icons":{"image_48":"https:\/\/slack.global.ssl.fastly.net\/93ed\/img\/services\/bots_48.png"}},{"id":"B06JH1N93","name":"bot","deleted":false,"icons":{"image_48":"https:\/\/slack.global.ssl.fastly.net\/93ed\/img\/services\/bots_48.png"}},{"id":"B0751JU2H","name":"bot","deleted":false,"icons":{"image_48":"https:\/\/slack.global.ssl.fastly.net\/93ed\/img\/services\/bots_48.png"}},{"id":"B07KECJ6R","name":"bot","deleted":false,"icons":{"image_48":"https:\/\/slack.global.ssl.fastly.net\/93ed\/img\/services\/bots_48.png"}}],"url":"wss:\/\/ms173.slack-msgs.com\/websocket\/lqcUiAvrKTP-uuid="}'
|
71
|
+
http_version:
|
72
|
+
recorded_at: Sat, 25 Jul 2015 16:10:32 GMT
|
73
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' } do
|
4
|
+
include_context 'connected client'
|
5
|
+
|
6
|
+
describe '#message' do
|
7
|
+
before do
|
8
|
+
allow(client).to receive(:next_id).and_return(42)
|
9
|
+
end
|
10
|
+
it 'sends message' do
|
11
|
+
expect(socket).to receive(:send_data).with({ type: 'message', id: 42, text: 'hello world', channel: 'channel' }.to_json)
|
12
|
+
client.message(text: 'hello world', channel: 'channel')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' } do
|
4
|
+
include_context 'connected client'
|
5
|
+
|
6
|
+
describe '#ping' do
|
7
|
+
before do
|
8
|
+
allow(client).to receive(:next_id).and_return(42)
|
9
|
+
end
|
10
|
+
it 'sends message' do
|
11
|
+
expect(socket).to receive(:send_data).with({ type: 'ping', id: 42 }.to_json)
|
12
|
+
client.ping
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' } do
|
4
|
+
include_context 'connected client'
|
5
|
+
|
6
|
+
describe '#typing' do
|
7
|
+
before do
|
8
|
+
allow(client).to receive(:next_id).and_return(42)
|
9
|
+
end
|
10
|
+
it 'sends a typing indicator' do
|
11
|
+
expect(socket).to receive(:send_data).with({ type: 'typing', id: 42, channel: 'channel' }.to_json)
|
12
|
+
client.typing(channel: 'channel')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' } do
|
4
|
+
let(:client) { Slack::RealTime::Client.new }
|
5
|
+
let(:ws) { double(Faye::WebSocket::Client) }
|
6
|
+
let(:url) { 'wss://ms173.slack-msgs.com/websocket/lqcUiAvrKTP-uuid=' }
|
7
|
+
let(:socket) { double(Slack::RealTime::Socket, connected?: true) }
|
8
|
+
context 'started' do
|
9
|
+
describe '#start!' do
|
10
|
+
before do
|
11
|
+
allow(EM).to receive(:run).and_yield
|
12
|
+
allow(Slack::RealTime::Socket).to receive(:new).with(url).and_return(socket)
|
13
|
+
allow(socket).to receive(:connect!).and_yield(ws)
|
14
|
+
allow(ws).to receive(:on)
|
15
|
+
client.start!
|
16
|
+
end
|
17
|
+
it 'sets url' do
|
18
|
+
expect(client.url).to eq url
|
19
|
+
end
|
20
|
+
it 'uses web client to fetch url' do
|
21
|
+
expect(client.web_client).to be_a Slack::Web::Client
|
22
|
+
end
|
23
|
+
it 'remembers socket' do
|
24
|
+
expect(client.instance_variable_get('@socket')).to eq socket
|
25
|
+
end
|
26
|
+
it 'cannot be invoked twice' do
|
27
|
+
expect do
|
28
|
+
client.start!
|
29
|
+
end.to raise_error Slack::RealTime::Client::ClientAlreadyStartedError
|
30
|
+
end
|
31
|
+
describe '#stop!' do
|
32
|
+
before do
|
33
|
+
expect(socket).to receive(:disconnect!)
|
34
|
+
client.stop!
|
35
|
+
end
|
36
|
+
it 'cannot be invoked twice' do
|
37
|
+
client.instance_variable_set('@socket', nil) # caused by a :close callback
|
38
|
+
expect do
|
39
|
+
client.stop!
|
40
|
+
end.to raise_error Slack::RealTime::Client::ClientNotStartedError
|
41
|
+
end
|
42
|
+
end
|
43
|
+
describe '#next_id' do
|
44
|
+
it 'increments' do
|
45
|
+
previous_id = client.send(:next_id)
|
46
|
+
expect(client.send(:next_id)).to eq previous_id + 1
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Slack::RealTime::Socket do
|
4
|
+
context 'with url' do
|
5
|
+
let(:url) { 'wss://ms174.slack-msgs.com/websocket/xyz' }
|
6
|
+
let(:socket) { Slack::RealTime::Socket.new(url) }
|
7
|
+
let(:ws) { double(Faye::WebSocket::Client) }
|
8
|
+
describe '#initialize' do
|
9
|
+
it 'sets url' do
|
10
|
+
expect(socket.url).to eq url
|
11
|
+
end
|
12
|
+
end
|
13
|
+
describe '#connect!' do
|
14
|
+
before do
|
15
|
+
allow(Faye::WebSocket::Client).to receive(:new).and_return(ws)
|
16
|
+
end
|
17
|
+
it 'connects' do
|
18
|
+
expect(ws).to receive(:on).with(:close)
|
19
|
+
socket.connect!
|
20
|
+
expect(socket.instance_variable_get('@ws')).to eq ws
|
21
|
+
end
|
22
|
+
end
|
23
|
+
describe '#disconnect!' do
|
24
|
+
it 'closes and nils the websocket' do
|
25
|
+
socket.instance_variable_set('@ws', ws)
|
26
|
+
expect(ws).to receive(:close)
|
27
|
+
socket.disconnect!
|
28
|
+
end
|
29
|
+
end
|
30
|
+
describe 'send_data' do
|
31
|
+
before do
|
32
|
+
allow(Faye::WebSocket::Client).to receive(:new).and_return(ws)
|
33
|
+
allow(ws).to receive(:on)
|
34
|
+
socket.connect!
|
35
|
+
end
|
36
|
+
it 'sends data' do
|
37
|
+
expect(ws).to receive(:send).with('data')
|
38
|
+
socket.send_data('data')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|