slack-ruby-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +6 -0
  6. data/.rubocop_todo.yml +34 -0
  7. data/.travis.yml +6 -0
  8. data/CHANGELOG.md +4 -0
  9. data/CONTRIBUTING.md +139 -0
  10. data/Gemfile +3 -0
  11. data/LICENSE.md +22 -0
  12. data/README.md +123 -0
  13. data/RELEASING.md +67 -0
  14. data/Rakefile +19 -0
  15. data/examples/hi_real_time/Gemfile +3 -0
  16. data/examples/hi_real_time/hi.gif +0 -0
  17. data/examples/hi_real_time/hi.rb +27 -0
  18. data/examples/hi_real_time_and_web/Gemfile +3 -0
  19. data/examples/hi_real_time_and_web/hi.gif +0 -0
  20. data/examples/hi_real_time_and_web/hi.rb +24 -0
  21. data/examples/hi_web/Gemfile +3 -0
  22. data/examples/hi_web/hi.gif +0 -0
  23. data/examples/hi_web/hi.rb +14 -0
  24. data/lib/slack-ruby-client.rb +23 -0
  25. data/lib/slack.rb +1 -0
  26. data/lib/slack/config.rb +17 -0
  27. data/lib/slack/real_time/api/message.rb +20 -0
  28. data/lib/slack/real_time/api/message_id.rb +14 -0
  29. data/lib/slack/real_time/api/ping.rb +16 -0
  30. data/lib/slack/real_time/api/typing.rb +17 -0
  31. data/lib/slack/real_time/client.rb +91 -0
  32. data/lib/slack/real_time/socket.rb +41 -0
  33. data/lib/slack/version.rb +3 -0
  34. data/lib/slack/web/api/endpoints.rb +39 -0
  35. data/lib/slack/web/api/endpoints/api.rb +25 -0
  36. data/lib/slack/web/api/endpoints/auth.rb +21 -0
  37. data/lib/slack/web/api/endpoints/channels.rb +216 -0
  38. data/lib/slack/web/api/endpoints/chat.rb +78 -0
  39. data/lib/slack/web/api/endpoints/emoji.rb +21 -0
  40. data/lib/slack/web/api/endpoints/files.rb +76 -0
  41. data/lib/slack/web/api/endpoints/groups.rb +229 -0
  42. data/lib/slack/web/api/endpoints/im.rb +82 -0
  43. data/lib/slack/web/api/endpoints/oauth.rb +32 -0
  44. data/lib/slack/web/api/endpoints/presence.rb +24 -0
  45. data/lib/slack/web/api/endpoints/rtm.rb +21 -0
  46. data/lib/slack/web/api/endpoints/search.rb +68 -0
  47. data/lib/slack/web/api/endpoints/stars.rb +23 -0
  48. data/lib/slack/web/api/endpoints/users.rb +70 -0
  49. data/lib/slack/web/api/error.rb +8 -0
  50. data/lib/slack/web/api/schema/method.json +45 -0
  51. data/lib/slack/web/api/tasks/generate.rake +37 -0
  52. data/lib/slack/web/api/templates/endpoints.erb +17 -0
  53. data/lib/slack/web/api/templates/method.erb +39 -0
  54. data/lib/slack/web/client.rb +17 -0
  55. data/lib/slack/web/config.rb +36 -0
  56. data/lib/slack/web/faraday/connection.rb +25 -0
  57. data/lib/slack/web/faraday/request.rb +39 -0
  58. data/lib/slack/web/faraday/response/raise_error.rb +14 -0
  59. data/lib/slack_ruby_client.rb +1 -0
  60. data/screenshots/register-bot.png +0 -0
  61. data/slack-ruby-client.gemspec +28 -0
  62. data/spec/fixtures/slack/web/auth_test_error.yml +48 -0
  63. data/spec/fixtures/slack/web/auth_test_success.yml +57 -0
  64. data/spec/fixtures/slack/web/rtm_start.yml +73 -0
  65. data/spec/slack/config_spec.rb +14 -0
  66. data/spec/slack/real_time/api/message_spec.rb +15 -0
  67. data/spec/slack/real_time/api/ping_spec.rb +15 -0
  68. data/spec/slack/real_time/api/typing_spec.rb +15 -0
  69. data/spec/slack/real_time/client_spec.rb +51 -0
  70. data/spec/slack/real_time/socket_spec.rb +42 -0
  71. data/spec/slack/version_spec.rb +7 -0
  72. data/spec/slack/web/api/endpoints/auth_spec.rb +15 -0
  73. data/spec/slack/web/client_spec.rb +31 -0
  74. data/spec/spec_helper.rb +14 -0
  75. data/spec/support/real_time/connected_client.rb +13 -0
  76. data/spec/support/vcr.rb +8 -0
  77. 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'
@@ -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,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Slack::Config do
4
+ describe '#configure' do
5
+ before do
6
+ Slack.configure do |config|
7
+ config.token = 'a token'
8
+ end
9
+ end
10
+ it 'sets token' do
11
+ expect(Slack.config.token).to eq 'a token'
12
+ end
13
+ end
14
+ 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 '#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