slack-ruby-client 0.13.1 → 2.0.0
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 +4 -4
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/integration_test.yml +26 -0
- data/.github/workflows/lint.yml +14 -0
- data/.github/workflows/pr_lint.yml +21 -0
- data/.github/workflows/test.yml +36 -0
- data/.gitignore +5 -3
- data/.rubocop.yml +34 -5
- data/.rubocop_todo.yml +180 -46
- data/.ruby-version +1 -0
- data/CHANGELOG.md +119 -2
- data/CONTRIBUTING.md +23 -11
- data/Dangerfile +2 -0
- data/Gemfile +22 -5
- data/Gemfile.danger +6 -0
- data/LICENSE.md +1 -1
- data/README.md +236 -101
- data/RELEASING.md +2 -2
- data/Rakefile +2 -1
- data/UPGRADING.md +100 -2
- data/bin/commands/admin_analytics.rb +16 -0
- data/bin/commands/admin_apps.rb +51 -0
- data/bin/commands/admin_apps_approved.rb +17 -0
- data/bin/commands/admin_apps_requests.rb +28 -0
- data/bin/commands/admin_apps_restricted.rb +17 -0
- data/bin/commands/admin_audit_anomaly_allow.rb +23 -0
- data/bin/commands/admin_auth_policy.rb +39 -0
- data/bin/commands/admin_barriers.rb +47 -0
- data/bin/commands/admin_conversations.rb +171 -0
- data/bin/commands/admin_conversations_ekm.rb +17 -0
- data/bin/commands/admin_conversations_restrictAccess.rb +37 -0
- data/bin/commands/admin_emoji.rb +54 -0
- data/bin/commands/admin_inviteRequests.rb +36 -0
- data/bin/commands/admin_inviteRequests_approved.rb +16 -0
- data/bin/commands/admin_inviteRequests_denied.rb +16 -0
- data/bin/commands/admin_teams.rb +27 -0
- data/bin/commands/admin_teams_admins.rb +16 -0
- data/bin/commands/admin_teams_owners.rb +16 -0
- data/bin/commands/admin_teams_settings.rb +64 -0
- data/bin/commands/admin_usergroups.rb +48 -0
- data/bin/commands/admin_users.rb +98 -0
- data/bin/commands/admin_users_session.rb +78 -0
- data/bin/commands/admin_users_unsupportedVersions.rb +15 -0
- data/bin/commands/api.rb +1 -1
- data/bin/commands/apps.rb +15 -0
- data/bin/commands/apps_connections.rb +13 -0
- data/bin/commands/apps_event_authorizations.rb +16 -0
- data/bin/commands/apps_manifest.rb +52 -0
- data/bin/commands/auth.rb +1 -0
- data/bin/commands/auth_teams.rb +16 -0
- data/bin/commands/bookmarks.rb +53 -0
- data/bin/commands/bots.rb +2 -0
- data/bin/commands/calls.rb +52 -0
- data/bin/commands/calls_participants.rb +25 -0
- data/bin/commands/chat.rb +61 -14
- data/bin/commands/chat_scheduledMessages.rb +19 -0
- data/bin/commands/conversations.rb +82 -10
- data/bin/commands/dialog.rb +1 -0
- data/bin/commands/dnd.rb +6 -3
- data/bin/commands/emoji.rb +1 -0
- data/bin/commands/files.rb +34 -18
- data/bin/commands/files_comments.rb +1 -21
- data/bin/commands/files_remote.rb +78 -0
- data/bin/commands/migration.rb +2 -0
- data/bin/commands/oauth.rb +2 -14
- data/bin/commands/oauth_v2.rb +29 -0
- data/bin/commands/openid_connect.rb +27 -0
- data/bin/commands/pins.rb +3 -6
- data/bin/commands/reactions.rb +3 -3
- data/bin/commands/reminders.rb +7 -0
- data/bin/commands/rtm.rb +1 -15
- data/bin/commands/search.rb +6 -1
- data/bin/commands/stars.rb +8 -6
- data/bin/commands/team.rb +6 -0
- data/bin/commands/team_billing.rb +13 -0
- data/bin/commands/team_preferences.rb +13 -0
- data/bin/commands/team_profile.rb +1 -0
- data/bin/commands/tooling_tokens.rb +14 -0
- data/bin/commands/usergroups.rb +7 -1
- data/bin/commands/usergroups_users.rb +3 -0
- data/bin/commands/users.rb +6 -4
- data/bin/commands/users_admin.rb +1 -0
- data/bin/commands/users_prefs.rb +1 -0
- data/bin/commands/users_profile.rb +6 -5
- data/bin/commands/views.rb +50 -0
- data/bin/commands/workflows.rb +38 -0
- data/bin/commands.rb +41 -8
- data/bin/slack +3 -4
- data/examples/hi_real_time_and_web/Gemfile +1 -0
- data/examples/hi_real_time_and_web/hi.rb +7 -3
- data/examples/hi_real_time_async_async/Gemfile +1 -0
- data/examples/hi_real_time_async_async/hi.rb +6 -2
- data/examples/hi_web/Gemfile +1 -0
- data/examples/hi_web/hi.rb +1 -0
- data/examples/new_ticket/Gemfile +1 -0
- data/examples/new_ticket/new_ticket.rb +1 -0
- data/lib/slack/config.rb +2 -2
- data/lib/slack/events/config.rb +32 -0
- data/lib/slack/events/request.rb +72 -0
- data/lib/slack/logger.rb +6 -5
- data/lib/slack/messages/formatting.rb +1 -0
- data/lib/slack/messages/message.rb +1 -4
- data/lib/slack/real_time/api/message.rb +6 -3
- data/lib/slack/real_time/api/message_id.rb +1 -0
- data/lib/slack/real_time/api/ping.rb +5 -2
- data/lib/slack/real_time/api/templates/event_handler.erb +5 -1
- data/lib/slack/real_time/api/typing.rb +5 -2
- data/lib/slack/real_time/client.rb +105 -54
- data/lib/slack/real_time/concurrency/async.rb +77 -6
- data/lib/slack/real_time/concurrency.rb +1 -2
- data/lib/slack/real_time/config.rb +9 -13
- data/lib/slack/real_time/models/base.rb +1 -4
- data/lib/slack/real_time/models/bot.rb +1 -0
- data/lib/slack/real_time/models/channel.rb +5 -0
- data/lib/slack/real_time/models/im.rb +1 -0
- data/lib/slack/real_time/models/{group.rb → mpim.rb} +2 -1
- data/lib/slack/real_time/models/team.rb +1 -0
- data/lib/slack/real_time/models/user.rb +1 -0
- data/lib/slack/real_time/models.rb +3 -1
- data/lib/slack/real_time/socket.rb +45 -17
- data/lib/slack/real_time/stores/base.rb +28 -14
- data/lib/slack/real_time/stores/starter.rb +325 -297
- data/lib/slack/real_time/stores/store.rb +271 -196
- data/lib/slack/real_time/stores.rb +2 -7
- data/lib/slack/version.rb +2 -1
- data/lib/slack/web/api/endpoints/admin_analytics.rb +28 -0
- data/lib/slack/web/api/endpoints/admin_apps.rb +78 -0
- data/lib/slack/web/api/endpoints/admin_apps_approved.rb +35 -0
- data/lib/slack/web/api/endpoints/admin_apps_requests.rb +51 -0
- data/lib/slack/web/api/endpoints/admin_apps_restricted.rb +35 -0
- data/lib/slack/web/api/endpoints/admin_audit_anomaly_allow.rb +34 -0
- data/lib/slack/web/api/endpoints/admin_auth_policy.rb +72 -0
- data/lib/slack/web/api/endpoints/admin_barriers.rb +82 -0
- data/lib/slack/web/api/endpoints/admin_conversations.rb +264 -0
- data/lib/slack/web/api/endpoints/admin_conversations_ekm.rb +35 -0
- data/lib/slack/web/api/endpoints/admin_conversations_restrictAccess.rb +61 -0
- data/lib/slack/web/api/endpoints/admin_emoji.rb +88 -0
- data/lib/slack/web/api/endpoints/admin_inviteRequests.rb +61 -0
- data/lib/slack/web/api/endpoints/admin_inviteRequests_approved.rb +33 -0
- data/lib/slack/web/api/endpoints/admin_inviteRequests_denied.rb +33 -0
- data/lib/slack/web/api/endpoints/admin_teams.rb +50 -0
- data/lib/slack/web/api/endpoints/admin_teams_admins.rb +34 -0
- data/lib/slack/web/api/endpoints/admin_teams_owners.rb +34 -0
- data/lib/slack/web/api/endpoints/admin_teams_settings.rb +99 -0
- data/lib/slack/web/api/endpoints/admin_usergroups.rb +77 -0
- data/lib/slack/web/api/endpoints/admin_users.rb +163 -0
- data/lib/slack/web/api/endpoints/admin_users_session.rb +122 -0
- data/lib/slack/web/api/endpoints/admin_users_unsupportedVersions.rb +25 -0
- data/lib/slack/web/api/endpoints/api.rb +2 -3
- data/lib/slack/web/api/endpoints/apps.rb +27 -0
- data/lib/slack/web/api/endpoints/apps_connections.rb +21 -0
- data/lib/slack/web/api/endpoints/apps_event_authorizations.rb +34 -0
- data/lib/slack/web/api/endpoints/apps_manifest.rb +77 -0
- data/lib/slack/web/api/endpoints/auth.rb +2 -1
- data/lib/slack/web/api/endpoints/auth_teams.rb +33 -0
- data/lib/slack/web/api/endpoints/bookmarks.rb +88 -0
- data/lib/slack/web/api/endpoints/bots.rb +4 -1
- data/lib/slack/web/api/endpoints/calls.rb +83 -0
- data/lib/slack/web/api/endpoints/calls_participants.rb +42 -0
- data/lib/slack/web/api/endpoints/chat.rb +168 -65
- data/lib/slack/web/api/endpoints/chat_scheduledMessages.rb +40 -0
- data/lib/slack/web/api/endpoints/conversations.rb +182 -67
- data/lib/slack/web/api/endpoints/dialog.rb +5 -4
- data/lib/slack/web/api/endpoints/dnd.rb +9 -4
- data/lib/slack/web/api/endpoints/emoji.rb +1 -0
- data/lib/slack/web/api/endpoints/files.rb +69 -37
- data/lib/slack/web/api/endpoints/files_comments.rb +4 -36
- data/lib/slack/web/api/endpoints/files_remote.rb +127 -0
- data/lib/slack/web/api/endpoints/migration.rb +6 -3
- data/lib/slack/web/api/endpoints/oauth.rb +7 -31
- data/lib/slack/web/api/endpoints/oauth_v2.rb +48 -0
- data/lib/slack/web/api/endpoints/openid_connect.rb +42 -0
- data/lib/slack/web/api/endpoints/pins.rb +11 -18
- data/lib/slack/web/api/endpoints/reactions.rb +22 -21
- data/lib/slack/web/api/endpoints/reminders.rb +23 -10
- data/lib/slack/web/api/endpoints/rtm.rb +3 -25
- data/lib/slack/web/api/endpoints/search.rb +31 -16
- data/lib/slack/web/api/endpoints/stars.rb +14 -11
- data/lib/slack/web/api/endpoints/team.rb +15 -4
- data/lib/slack/web/api/endpoints/team_billing.rb +21 -0
- data/lib/slack/web/api/endpoints/team_preferences.rb +21 -0
- data/lib/slack/web/api/endpoints/team_profile.rb +2 -1
- data/lib/slack/web/api/endpoints/tooling_tokens.rb +24 -0
- data/lib/slack/web/api/endpoints/usergroups.rb +31 -20
- data/lib/slack/web/api/endpoints/usergroups_users.rb +13 -8
- data/lib/slack/web/api/endpoints/users.rb +24 -23
- data/lib/slack/web/api/endpoints/users_admin.rb +3 -2
- data/lib/slack/web/api/endpoints/users_prefs.rb +1 -0
- data/lib/slack/web/api/endpoints/users_profile.rb +8 -7
- data/lib/slack/web/api/endpoints/views.rb +102 -0
- data/lib/slack/web/api/endpoints/workflows.rb +61 -0
- data/lib/slack/web/api/endpoints.rb +82 -18
- data/lib/slack/web/api/error.rb +1 -0
- data/lib/slack/web/api/errors/server_error.rb +37 -0
- data/lib/slack/web/api/errors/slack_error.rb +14 -1
- data/lib/slack/web/api/errors/too_many_requests_error.rb +2 -4
- data/lib/slack/web/api/errors.rb +1116 -0
- data/lib/slack/web/api/mixins/{channels.id.rb → conversations.id.rb} +5 -6
- data/lib/slack/web/api/mixins/ids.id.rb +3 -2
- data/lib/slack/web/api/mixins/users.id.rb +3 -4
- data/lib/slack/web/api/mixins/users.search.rb +3 -1
- data/lib/slack/web/api/mixins.rb +2 -2
- data/lib/slack/web/api/patches/chat.attachments-blocks.patch +69 -0
- data/lib/slack/web/api/patches/{dialog.1.open-json-support.patch → dialog.encoded-json.patch} +4 -4
- data/lib/slack/web/api/patches/views.view-json.patch +55 -0
- data/lib/slack/web/api/templates/command.erb +1 -0
- data/lib/slack/web/api/templates/commands.erb +1 -0
- data/lib/slack/web/api/templates/endpoints.erb +2 -2
- data/lib/slack/web/api/templates/errors.erb +20 -0
- data/lib/slack/web/api/templates/method.erb +6 -2
- data/lib/slack/web/api/templates/method_spec.erb +2 -1
- data/lib/slack/web/client.rb +2 -1
- data/lib/slack/web/config.rb +5 -2
- data/lib/slack/web/faraday/connection.rb +24 -20
- data/lib/slack/web/faraday/request.rb +5 -1
- data/lib/slack/web/faraday/response/raise_error.rb +14 -7
- data/lib/slack/web/faraday/response/wrap_error.rb +24 -0
- data/lib/slack/web/pagination/cursor.rb +7 -7
- data/lib/slack-ruby-client.rb +12 -5
- data/lib/slack.rb +1 -0
- data/lib/slack_ruby_client.rb +1 -0
- data/lib/tasks/git.rake +1 -0
- data/lib/tasks/real_time.rake +51 -21
- data/lib/tasks/update.rake +1 -0
- data/lib/tasks/web.rake +48 -12
- data/screenshots/create-app.png +0 -0
- data/slack-ruby-client.gemspec +7 -12
- data/spec/fixtures/slack/web/429_error.yml +50 -54
- data/spec/fixtures/slack/web/auth_test_error.yml +51 -18
- data/spec/fixtures/slack/web/auth_test_success.yml +50 -26
- data/spec/fixtures/slack/web/conversations_info.yml +167 -0
- data/spec/fixtures/slack/web/conversations_setTopic.yml +84 -0
- data/spec/fixtures/slack/web/conversations_setTopic_one_page.yml +172 -0
- data/spec/fixtures/slack/web/conversations_setTopic_paginated.yml +253 -0
- data/spec/fixtures/slack/web/paginated_users_list.yml +501 -69
- data/spec/fixtures/slack/web/rtm_connect.yml +347 -26
- data/spec/fixtures/slack/web/users_info.yml +153 -69
- data/spec/fixtures/slack/web/users_list.yml +102 -41
- data/spec/fixtures/slack/web/views_open_error.yml +83 -0
- data/spec/integration/integration_spec.rb +115 -47
- data/spec/slack/config_spec.rb +2 -0
- data/spec/slack/events/config_spec.rb +35 -0
- data/spec/slack/events/request_spec.rb +188 -0
- data/spec/slack/messages/formatting_spec.rb +35 -13
- data/spec/slack/real_time/api/message_spec.rb +7 -2
- data/spec/slack/real_time/api/ping_spec.rb +3 -1
- data/spec/slack/real_time/api/typing_spec.rb +6 -2
- data/spec/slack/real_time/client_spec.rb +300 -142
- data/spec/slack/real_time/concurrency/it_behaves_like_a_realtime_socket.rb +2 -0
- data/spec/slack/real_time/concurrency/with_concurrency_spec.rb +10 -0
- data/spec/slack/real_time/concurrency/without_concurrency_spec.rb +10 -0
- data/spec/slack/real_time/event_handlers/bot_spec.rb +20 -17
- data/spec/slack/real_time/event_handlers/event_handlers_spec.rb +3 -2
- data/spec/slack/real_time/event_handlers/im_spec.rb +31 -27
- data/spec/slack/real_time/event_handlers/{group_spec.rb → private_channel_spec.rb} +36 -27
- data/spec/slack/real_time/event_handlers/{channel_spec.rb → public_channel_spec.rb} +31 -24
- data/spec/slack/real_time/event_handlers/team_spec.rb +8 -7
- data/spec/slack/real_time/event_handlers/user_spec.rb +7 -5
- data/spec/slack/real_time/rtm_connect_spec.rb +2 -1
- data/spec/slack/real_time/stores/store_spec.rb +50 -0
- data/spec/slack/slack_spec.rb +41 -6
- data/spec/slack/version_spec.rb +2 -1
- data/spec/slack/web/api/endpoints/admin_analytics_spec.rb +13 -0
- data/spec/slack/web/api/endpoints/admin_apps_approved_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/admin_apps_requests_spec.rb +13 -0
- data/spec/slack/web/api/endpoints/admin_apps_restricted_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/admin_apps_spec.rb +18 -0
- data/spec/slack/web/api/endpoints/admin_audit_anomaly_allow_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/admin_auth_policy_spec.rb +35 -0
- data/spec/slack/web/api/endpoints/admin_barriers_spec.rb +38 -0
- data/spec/slack/web/api/endpoints/admin_conversations_ekm_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/admin_conversations_restrictAccess_spec.rb +32 -0
- data/spec/slack/web/api/endpoints/admin_conversations_spec.rb +98 -0
- data/spec/slack/web/api/endpoints/admin_emoji_spec.rb +37 -0
- data/spec/slack/web/api/endpoints/admin_inviteRequests_approved_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/admin_inviteRequests_denied_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/admin_inviteRequests_spec.rb +18 -0
- data/spec/slack/web/api/endpoints/admin_teams_admins_spec.rb +13 -0
- data/spec/slack/web/api/endpoints/admin_teams_owners_spec.rb +13 -0
- data/spec/slack/web/api/endpoints/admin_teams_settings_spec.rb +53 -0
- data/spec/slack/web/api/endpoints/admin_teams_spec.rb +16 -0
- data/spec/slack/web/api/endpoints/admin_usergroups_spec.rb +37 -0
- data/spec/slack/web/api/endpoints/admin_users_session_spec.rb +41 -0
- data/spec/slack/web/api/endpoints/admin_users_spec.rb +67 -0
- data/spec/slack/web/api/endpoints/admin_users_unsupportedVersions_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/api_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/apps_connections_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/apps_event_authorizations_spec.rb +13 -0
- data/spec/slack/web/api/endpoints/apps_manifest_spec.rb +36 -0
- data/spec/slack/web/api/endpoints/apps_spec.rb +16 -0
- data/spec/slack/web/api/endpoints/{apps_permissions_resources_spec.rb → auth_teams_spec.rb} +2 -1
- data/spec/slack/web/api/endpoints/bookmarks_spec.rb +40 -0
- data/spec/slack/web/api/endpoints/bots_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/calls_participants_spec.rb +24 -0
- data/spec/slack/web/api/endpoints/calls_spec.rb +31 -0
- data/spec/slack/web/api/endpoints/chat_scheduledMessages_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/custom_specs/auth_spec.rb +9 -7
- data/spec/slack/web/api/endpoints/custom_specs/chat_spec.rb +144 -40
- data/spec/slack/web/api/endpoints/custom_specs/conversations_spec.rb +13 -0
- data/spec/slack/web/api/endpoints/custom_specs/dialog_spec.rb +18 -6
- data/spec/slack/web/api/endpoints/custom_specs/users_spec.rb +8 -3
- data/spec/slack/web/api/endpoints/custom_specs/views_spec.rb +112 -0
- data/spec/slack/web/api/endpoints/dnd_spec.rb +4 -3
- data/spec/slack/web/api/endpoints/emoji_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/files_comments_spec.rb +3 -21
- data/spec/slack/web/api/endpoints/files_remote_spec.rb +24 -0
- data/spec/slack/web/api/endpoints/files_spec.rb +18 -4
- data/spec/slack/web/api/endpoints/migration_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/oauth_spec.rb +1 -22
- data/spec/slack/web/api/endpoints/oauth_v2_spec.rb +16 -0
- data/spec/slack/web/api/endpoints/openid_connect_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/pins_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/reactions_spec.rb +8 -1
- data/spec/slack/web/api/endpoints/reminders_spec.rb +3 -2
- data/spec/slack/web/api/endpoints/rtm_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/search_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/stars_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/{apps_permissions_scopes_spec.rb → team_billing_spec.rb} +2 -1
- data/spec/slack/web/api/endpoints/team_preferences_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/team_profile_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/team_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/tooling_tokens_spec.rb +13 -0
- data/spec/slack/web/api/endpoints/usergroups_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/usergroups_users_spec.rb +3 -2
- data/spec/slack/web/api/endpoints/users_admin_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/users_prefs_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/users_profile_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/workflows_spec.rb +26 -0
- data/spec/slack/web/api/error_spec.rb +7 -7
- data/spec/slack/web/api/errors/slack_error_spec.rb +26 -7
- data/spec/slack/web/api/mixins/conversations_list_spec.rb +21 -0
- data/spec/slack/web/api/mixins/conversations_spec.rb +45 -0
- data/spec/slack/web/api/mixins/users_spec.rb +19 -8
- data/spec/slack/web/api/pagination/cursor_spec.rb +47 -15
- data/spec/slack/web/client_spec.rb +199 -22
- data/spec/slack/web/faraday/request_spec.rb +80 -0
- data/spec/slack/web/faraday/response/raise_error_spec.rb +48 -12
- data/spec/spec_helper.rb +9 -2
- data/spec/support/queue_with_timeout.rb +5 -4
- data/spec/support/real_time/concurrency/mock.rb +1 -0
- data/spec/support/real_time/connected_client.rb +6 -6
- data/spec/support/real_time/event.rb +1 -0
- data/spec/support/real_time/loaded_client.rb +120 -0
- data/spec/support/token.rb +1 -0
- data/spec/support/vcr.rb +37 -1
- metadata +174 -262
- data/.travis.yml +0 -32
- data/bin/commands/apps_permissions.rb +0 -22
- data/bin/commands/apps_permissions_resources.rb +0 -14
- data/bin/commands/apps_permissions_scopes.rb +0 -12
- data/bin/commands/apps_permissions_users.rb +0 -25
- data/bin/commands/channels.rb +0 -175
- data/bin/commands/groups.rb +0 -174
- data/bin/commands/im.rb +0 -67
- data/bin/commands/mpim.rb +0 -65
- data/examples/hi_real_time/Gemfile +0 -5
- data/examples/hi_real_time/hi.gif +0 -0
- data/examples/hi_real_time/hi.rb +0 -37
- data/examples/hi_real_time_async_celluloid/Gemfile +0 -6
- data/examples/hi_real_time_async_celluloid/Procfile +0 -2
- data/examples/hi_real_time_async_celluloid/hi.rb +0 -35
- data/examples/hi_real_time_async_eventmachine/Gemfile +0 -6
- data/examples/hi_real_time_async_eventmachine/Procfile +0 -2
- data/examples/hi_real_time_async_eventmachine/hi.rb +0 -35
- data/lib/slack/real_time/concurrency/celluloid.rb +0 -118
- data/lib/slack/real_time/concurrency/eventmachine.rb +0 -66
- data/lib/slack/web/api/endpoints/apps_permissions.rb +0 -35
- data/lib/slack/web/api/endpoints/apps_permissions_resources.rb +0 -30
- data/lib/slack/web/api/endpoints/apps_permissions_scopes.rb +0 -20
- data/lib/slack/web/api/endpoints/apps_permissions_users.rb +0 -49
- data/lib/slack/web/api/endpoints/channels.rb +0 -266
- data/lib/slack/web/api/endpoints/groups.rb +0 -265
- data/lib/slack/web/api/endpoints/im.rb +0 -113
- data/lib/slack/web/api/endpoints/mpim.rb +0 -108
- data/lib/slack/web/api/endpoints/presence.rb +0 -23
- data/lib/slack/web/api/mixins/channels.id.json +0 -20
- data/lib/slack/web/api/mixins/groups.id.json +0 -20
- data/lib/slack/web/api/mixins/groups.id.rb +0 -26
- data/lib/slack/web/api/patches/chat.1.text-attachments-required.patch +0 -13
- data/lib/slack/web/api/patches/chat.2.attachments-json.patch +0 -17
- data/lib/slack/web/api/patches/chat.3.update-attachments-support.patch +0 -21
- data/lib/slack/web/api/patches/chat.4.postEphemeral-attachments-support.patch +0 -17
- data/lib/slack/web/api/patches/chat.5.postEphemeral-text-or-attachments.patch +0 -13
- data/screenshots/register-bot.png +0 -0
- data/spec/fixtures/slack/web/503_error.yml +0 -14
- data/spec/fixtures/slack/web/channels_info.yml +0 -46
- data/spec/fixtures/slack/web/groups_info.yml +0 -43
- data/spec/fixtures/slack/web/rtm_start.yml +0 -104
- data/spec/slack/real_time/concurrency/celluloid_spec.rb +0 -106
- data/spec/slack/real_time/concurrency/eventmachine_spec.rb +0 -47
- data/spec/slack/real_time/rtm_start_spec.rb +0 -13
- data/spec/slack/real_time/store_spec.rb +0 -11
- data/spec/slack/web/api/endpoints/apps_permissions_spec.rb +0 -15
- data/spec/slack/web/api/endpoints/apps_permissions_users_spec.rb +0 -18
- data/spec/slack/web/api/endpoints/conversations_spec.rb +0 -100
- data/spec/slack/web/api/endpoints/custom_specs/channels_spec.rb +0 -11
- data/spec/slack/web/api/endpoints/custom_specs/groups_spec.rb +0 -11
- data/spec/slack/web/api/endpoints/im_spec.rb +0 -38
- data/spec/slack/web/api/endpoints/mpim_spec.rb +0 -38
- data/spec/slack/web/api/errors/service_unavailable_spec.rb +0 -14
- data/spec/slack/web/api/mixins/channels_spec.rb +0 -33
- data/spec/slack/web/api/mixins/groups_spec.rb +0 -33
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Slack
|
|
2
3
|
module RealTime
|
|
3
4
|
class Client
|
|
4
5
|
class ClientNotStartedError < StandardError; end
|
|
6
|
+
|
|
5
7
|
class ClientAlreadyStartedError < StandardError; end
|
|
6
8
|
|
|
7
9
|
include Api::MessageId
|
|
@@ -9,19 +11,9 @@ module Slack
|
|
|
9
11
|
include Api::Message
|
|
10
12
|
include Api::Typing
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class << self
|
|
15
|
-
attr_accessor :events
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
attr_accessor :web_client
|
|
19
|
-
attr_accessor :store
|
|
20
|
-
attr_accessor :url
|
|
21
|
-
attr_accessor(*Config::ATTRIBUTES)
|
|
14
|
+
attr_accessor :web_client, :store, :url, *Config::ATTRIBUTES
|
|
22
15
|
|
|
23
|
-
protected :
|
|
24
|
-
protected :store_class, :store_class=
|
|
16
|
+
protected :store_class, :store_class=, :store_options, :store_options=
|
|
25
17
|
|
|
26
18
|
def initialize(options = {})
|
|
27
19
|
@callbacks = Hash.new { |h, k| h[k] = [] }
|
|
@@ -33,9 +25,9 @@ module Slack
|
|
|
33
25
|
@web_client = Slack::Web::Client.new(token: token, logger: logger)
|
|
34
26
|
end
|
|
35
27
|
|
|
36
|
-
|
|
28
|
+
[:self, :team, *Stores::Base::CACHES].each do |store_method|
|
|
37
29
|
define_method store_method do
|
|
38
|
-
store
|
|
30
|
+
store&.send(store_method)
|
|
39
31
|
end
|
|
40
32
|
end
|
|
41
33
|
|
|
@@ -46,26 +38,27 @@ module Slack
|
|
|
46
38
|
|
|
47
39
|
# Start RealTime client and block until it disconnects.
|
|
48
40
|
def start!(&block)
|
|
49
|
-
@callback = block if
|
|
50
|
-
|
|
41
|
+
@callback = block if block
|
|
42
|
+
build_socket
|
|
51
43
|
@socket.start_sync(self)
|
|
52
44
|
end
|
|
53
45
|
|
|
54
46
|
# Start RealTime client and return immediately.
|
|
55
47
|
# The RealTime::Client will run in the background.
|
|
56
48
|
def start_async(&block)
|
|
57
|
-
@callback = block if
|
|
58
|
-
|
|
49
|
+
@callback = block if block
|
|
50
|
+
build_socket
|
|
59
51
|
@socket.start_async(self)
|
|
60
52
|
end
|
|
61
53
|
|
|
62
54
|
def stop!
|
|
63
55
|
raise ClientNotStartedError unless started?
|
|
64
|
-
|
|
56
|
+
|
|
57
|
+
@socket&.disconnect!
|
|
65
58
|
end
|
|
66
59
|
|
|
67
60
|
def started?
|
|
68
|
-
@socket
|
|
61
|
+
@socket&.connected?
|
|
69
62
|
end
|
|
70
63
|
|
|
71
64
|
class << self
|
|
@@ -80,48 +73,105 @@ module Slack
|
|
|
80
73
|
|
|
81
74
|
def run_loop
|
|
82
75
|
@socket.connect! do |driver|
|
|
83
|
-
@callback.call(driver) if @callback
|
|
84
|
-
|
|
85
76
|
driver.on :open do |event|
|
|
86
|
-
logger.debug("#{self
|
|
87
|
-
|
|
77
|
+
logger.debug("#{self}##{__method__}") { event.class.name }
|
|
78
|
+
open_event(event)
|
|
88
79
|
callback(event, :open)
|
|
89
80
|
end
|
|
90
81
|
|
|
91
82
|
driver.on :message do |event|
|
|
92
|
-
logger.debug("#{self
|
|
83
|
+
logger.debug("#{self}##{__method__}") { "#{event.class}, #{event.data}" }
|
|
93
84
|
dispatch(event)
|
|
94
85
|
end
|
|
95
86
|
|
|
96
87
|
driver.on :close do |event|
|
|
97
|
-
logger.debug("#{self
|
|
88
|
+
logger.debug("#{self}##{__method__}") { event.class.name }
|
|
98
89
|
callback(event, :close)
|
|
99
90
|
close(event)
|
|
100
91
|
callback(event, :closed)
|
|
101
92
|
end
|
|
93
|
+
|
|
94
|
+
# This must be called last to ensure any events are registered before invoking user code.
|
|
95
|
+
@callback&.call(driver)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Ensure the server is running, and ping the remote server if no other messages were sent.
|
|
100
|
+
def keep_alive?
|
|
101
|
+
# We can't ping the remote server if we aren't connected.
|
|
102
|
+
return false if @socket.nil? || !@socket.connected?
|
|
103
|
+
|
|
104
|
+
time_since_last_message = @socket.time_since_last_message
|
|
105
|
+
|
|
106
|
+
# If the server responded within the specified time, we are okay:
|
|
107
|
+
return true if time_since_last_message < websocket_ping
|
|
108
|
+
|
|
109
|
+
# If the server has not responded for a while:
|
|
110
|
+
return false if time_since_last_message > (websocket_ping * 2)
|
|
111
|
+
|
|
112
|
+
# Kick off the next ping message:
|
|
113
|
+
ping
|
|
114
|
+
|
|
115
|
+
true
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Check if the remote server is responsive, and if not, restart the connection.
|
|
119
|
+
def run_ping!
|
|
120
|
+
return if keep_alive?
|
|
121
|
+
|
|
122
|
+
logger.warn(to_s) { 'is offline' }
|
|
123
|
+
|
|
124
|
+
restart_async
|
|
125
|
+
rescue Slack::Web::Api::Errors::SlackError => e
|
|
126
|
+
# stop pinging if bot was uninstalled
|
|
127
|
+
case e.message
|
|
128
|
+
when 'account_inactive', 'invalid_auth'
|
|
129
|
+
logger.warn(to_s) { e.message }
|
|
130
|
+
raise e
|
|
131
|
+
end
|
|
132
|
+
logger.debug("#{self}##{__method__}") { e }
|
|
133
|
+
rescue StandardError => e
|
|
134
|
+
# disregard all ping worker failures, keep pinging
|
|
135
|
+
logger.debug("#{self}##{__method__}") { e }
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def run_ping?
|
|
139
|
+
!websocket_ping.nil? && websocket_ping.positive?
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def websocket_ping_timer
|
|
143
|
+
websocket_ping / 2
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def to_s
|
|
147
|
+
if store&.team
|
|
148
|
+
"id=#{store.team.id}, name=#{store.team.name}, domain=#{store.team.domain}"
|
|
149
|
+
else
|
|
150
|
+
super
|
|
102
151
|
end
|
|
103
152
|
end
|
|
104
153
|
|
|
105
154
|
protected
|
|
106
155
|
|
|
156
|
+
def restart_async
|
|
157
|
+
logger.debug("#{self}##{__method__}")
|
|
158
|
+
@socket.close
|
|
159
|
+
start = web_client.rtm_connect(start_options)
|
|
160
|
+
data = Slack::Messages::Message.new(start)
|
|
161
|
+
@url = data.url
|
|
162
|
+
@store = store_class.new(data, store_options.to_h) if store_class
|
|
163
|
+
@socket.restart_async(self, @url)
|
|
164
|
+
end
|
|
165
|
+
|
|
107
166
|
# @return [Slack::RealTime::Socket]
|
|
108
167
|
def build_socket
|
|
109
168
|
raise ClientAlreadyStartedError if started?
|
|
110
|
-
|
|
169
|
+
|
|
170
|
+
start = web_client.rtm_connect(start_options)
|
|
111
171
|
data = Slack::Messages::Message.new(start)
|
|
112
172
|
@url = data.url
|
|
113
|
-
@store =
|
|
114
|
-
socket_class.new(@url, socket_options)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def rtm_start_method
|
|
118
|
-
if start_method
|
|
119
|
-
start_method
|
|
120
|
-
elsif @store_class && @store_class <= Slack::RealTime::Stores::Store
|
|
121
|
-
:rtm_start
|
|
122
|
-
else
|
|
123
|
-
:rtm_connect
|
|
124
|
-
end
|
|
173
|
+
@store = store_class.new(data, store_options.to_h) if store_class
|
|
174
|
+
@socket = socket_class.new(@url, socket_options)
|
|
125
175
|
end
|
|
126
176
|
|
|
127
177
|
def socket_options
|
|
@@ -133,23 +183,22 @@ module Slack
|
|
|
133
183
|
end
|
|
134
184
|
|
|
135
185
|
attr_reader :callbacks
|
|
186
|
+
|
|
136
187
|
def socket_class
|
|
137
188
|
concurrency::Socket
|
|
138
189
|
end
|
|
139
190
|
|
|
140
191
|
def send_json(data)
|
|
141
192
|
raise ClientNotStartedError unless started?
|
|
142
|
-
|
|
193
|
+
|
|
194
|
+
logger.debug("#{self}##{__method__}") { data }
|
|
143
195
|
@socket.send_data(data.to_json)
|
|
144
196
|
end
|
|
145
197
|
|
|
146
|
-
def
|
|
198
|
+
def open_event(_event); end
|
|
147
199
|
|
|
148
200
|
def close(_event)
|
|
149
|
-
socket
|
|
150
|
-
@socket = nil
|
|
151
|
-
|
|
152
|
-
[socket, socket_class].each do |s|
|
|
201
|
+
[@socket, socket_class].each do |s|
|
|
153
202
|
s.close if s.respond_to?(:close)
|
|
154
203
|
end
|
|
155
204
|
end
|
|
@@ -157,50 +206,52 @@ module Slack
|
|
|
157
206
|
def callback(event, type)
|
|
158
207
|
callbacks = self.callbacks[type.to_s]
|
|
159
208
|
return false unless callbacks
|
|
209
|
+
|
|
160
210
|
callbacks.each do |c|
|
|
161
211
|
c.call(event)
|
|
162
212
|
end
|
|
163
213
|
true
|
|
164
214
|
rescue StandardError => e
|
|
165
|
-
logger.error e
|
|
215
|
+
logger.error("#{self}##{__method__}") { e }
|
|
166
216
|
false
|
|
167
217
|
end
|
|
168
218
|
|
|
169
219
|
def dispatch(event)
|
|
170
220
|
return false unless event.data
|
|
221
|
+
|
|
171
222
|
data = Slack::Messages::Message.new(JSON.parse(event.data))
|
|
172
223
|
type = data.type
|
|
173
224
|
return false unless type
|
|
225
|
+
|
|
174
226
|
type = type.to_s
|
|
175
|
-
logger.debug("#{self
|
|
227
|
+
logger.debug("#{self}##{__method__}") { data.to_s }
|
|
176
228
|
run_handlers(type, data) if @store
|
|
177
229
|
run_callbacks(type, data)
|
|
178
230
|
rescue StandardError => e
|
|
179
|
-
logger.error e
|
|
231
|
+
logger.error("#{self}##{__method__}") { e }
|
|
180
232
|
false
|
|
181
233
|
end
|
|
182
234
|
|
|
183
235
|
def run_handlers(type, data)
|
|
184
236
|
handlers = store.class.events[type.to_s]
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
store.instance_exec(data, &handler)
|
|
188
|
-
end
|
|
237
|
+
handlers.each do |handler|
|
|
238
|
+
store.instance_exec(data, self, &handler)
|
|
189
239
|
end
|
|
190
240
|
rescue StandardError => e
|
|
191
|
-
logger.error e
|
|
241
|
+
logger.error("#{self}##{__method__}") { e }
|
|
192
242
|
false
|
|
193
243
|
end
|
|
194
244
|
|
|
195
245
|
def run_callbacks(type, data)
|
|
196
246
|
callbacks = self.callbacks[type]
|
|
197
247
|
return false unless callbacks
|
|
248
|
+
|
|
198
249
|
callbacks.each do |c|
|
|
199
250
|
c.call(data)
|
|
200
251
|
end
|
|
201
252
|
true
|
|
202
253
|
rescue StandardError => e
|
|
203
|
-
logger.error e
|
|
254
|
+
logger.error("#{self}##{__method__}") { e }
|
|
204
255
|
false
|
|
205
256
|
end
|
|
206
257
|
end
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'async/websocket'
|
|
3
|
+
require 'async/notification'
|
|
4
|
+
require 'async/clock'
|
|
2
5
|
|
|
3
6
|
module Slack
|
|
4
7
|
module RealTime
|
|
@@ -12,28 +15,89 @@ module Slack
|
|
|
12
15
|
class Socket < Slack::RealTime::Socket
|
|
13
16
|
attr_reader :client
|
|
14
17
|
|
|
18
|
+
def start_sync(client)
|
|
19
|
+
start_reactor(client).wait
|
|
20
|
+
end
|
|
21
|
+
|
|
15
22
|
def start_async(client)
|
|
16
23
|
Thread.new do
|
|
17
|
-
|
|
18
|
-
|
|
24
|
+
start_reactor(client)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def start_reactor(client)
|
|
29
|
+
Async do |task|
|
|
30
|
+
@restart = ::Async::Notification.new
|
|
31
|
+
|
|
32
|
+
if client.run_ping?
|
|
33
|
+
@ping_task = task.async do |subtask|
|
|
34
|
+
subtask.annotate "#{client} keep-alive"
|
|
35
|
+
|
|
36
|
+
# The timer task will naturally exit after the driver is set to nil.
|
|
37
|
+
while @restart
|
|
38
|
+
subtask.sleep client.websocket_ping_timer
|
|
39
|
+
client.run_ping! if @restart
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
while @restart
|
|
45
|
+
@client_task&.stop
|
|
46
|
+
|
|
47
|
+
@client_task = task.async do |subtask|
|
|
48
|
+
subtask.annotate "#{client} run-loop"
|
|
49
|
+
client.run_loop
|
|
50
|
+
rescue ::Async::Wrapper::Cancelled => e
|
|
51
|
+
# Will get restarted by ping worker.
|
|
52
|
+
rescue StandardError => e
|
|
53
|
+
client.logger.error(subtask.to_s) { e.message }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
@restart.wait
|
|
19
57
|
end
|
|
58
|
+
|
|
59
|
+
@ping_task&.stop
|
|
20
60
|
end
|
|
21
61
|
end
|
|
22
62
|
|
|
63
|
+
def restart_async(_client, new_url)
|
|
64
|
+
@url = new_url
|
|
65
|
+
@last_message_at = current_time
|
|
66
|
+
|
|
67
|
+
@restart&.signal
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def current_time
|
|
71
|
+
::Async::Clock.now
|
|
72
|
+
end
|
|
73
|
+
|
|
23
74
|
def connect!
|
|
24
75
|
super
|
|
25
76
|
run_loop
|
|
26
77
|
end
|
|
27
78
|
|
|
79
|
+
# Kill the restart/ping loop.
|
|
80
|
+
def disconnect!
|
|
81
|
+
super
|
|
82
|
+
ensure
|
|
83
|
+
if (restart = @restart)
|
|
84
|
+
@restart = nil
|
|
85
|
+
restart.signal
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Close the socket.
|
|
28
90
|
def close
|
|
29
|
-
@closing = true
|
|
30
|
-
@driver.close if @driver
|
|
31
91
|
super
|
|
92
|
+
ensure
|
|
93
|
+
if @socket
|
|
94
|
+
@socket.close
|
|
95
|
+
@socket = nil
|
|
96
|
+
end
|
|
32
97
|
end
|
|
33
98
|
|
|
34
99
|
def run_loop
|
|
35
|
-
@
|
|
36
|
-
while @driver && @driver.next_event
|
|
100
|
+
while @driver&.next_event
|
|
37
101
|
# $stderr.puts event.inspect
|
|
38
102
|
end
|
|
39
103
|
end
|
|
@@ -65,3 +129,10 @@ module Slack
|
|
|
65
129
|
end
|
|
66
130
|
end
|
|
67
131
|
end
|
|
132
|
+
|
|
133
|
+
if Gem::Version.new(Async::WebSocket::VERSION) >= Gem::Version.new('0.9.0')
|
|
134
|
+
raise(
|
|
135
|
+
"Incompatible version of async-websocket, #{Async::WebSocket::VERSION}, " \
|
|
136
|
+
"use \"gem 'async-websocket', '~> 0.8.0'\"."
|
|
137
|
+
)
|
|
138
|
+
end
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Slack
|
|
2
3
|
module RealTime
|
|
3
4
|
module Concurrency
|
|
4
5
|
autoload :Async, 'slack/real_time/concurrency/async'
|
|
5
|
-
autoload :Eventmachine, 'slack/real_time/concurrency/eventmachine'
|
|
6
|
-
autoload :Celluloid, 'slack/real_time/concurrency/celluloid'
|
|
7
6
|
end
|
|
8
7
|
end
|
|
9
8
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Slack
|
|
2
3
|
module RealTime
|
|
3
4
|
module Config
|
|
@@ -10,22 +11,23 @@ module Slack
|
|
|
10
11
|
websocket_ping
|
|
11
12
|
websocket_proxy
|
|
12
13
|
concurrency
|
|
13
|
-
start_method
|
|
14
14
|
start_options
|
|
15
15
|
store_class
|
|
16
|
+
store_options
|
|
16
17
|
logger
|
|
17
18
|
].freeze
|
|
18
19
|
|
|
19
|
-
attr_accessor(*Config::ATTRIBUTES)
|
|
20
|
+
attr_accessor(*Config::ATTRIBUTES - [:concurrency])
|
|
21
|
+
attr_writer :concurrency
|
|
20
22
|
|
|
21
23
|
def reset
|
|
22
24
|
self.websocket_ping = 30
|
|
23
25
|
self.websocket_proxy = nil
|
|
24
26
|
self.token = nil
|
|
25
27
|
self.concurrency = method(:detect_concurrency)
|
|
26
|
-
self.start_method = nil
|
|
27
28
|
self.start_options = { request: { timeout: 180 } }
|
|
28
|
-
self.store_class = Slack::RealTime::
|
|
29
|
+
self.store_class = Slack::RealTime::Stores::Starter
|
|
30
|
+
self.store_options = {}
|
|
29
31
|
self.logger = nil
|
|
30
32
|
end
|
|
31
33
|
|
|
@@ -36,15 +38,9 @@ module Slack
|
|
|
36
38
|
private
|
|
37
39
|
|
|
38
40
|
def detect_concurrency
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
rescue LoadError, NameError
|
|
43
|
-
false # could not be loaded, missing dependencies
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
raise NoConcurrencyError, 'Missing concurrency. Add async-websocket, faye-websocket or celluloid-io to your Gemfile.'
|
|
41
|
+
Slack::RealTime::Concurrency.const_get(:Async)
|
|
42
|
+
rescue LoadError, NameError
|
|
43
|
+
raise NoConcurrencyError, 'Missing concurrency. Add async-websocket to your Gemfile.'
|
|
48
44
|
end
|
|
49
45
|
end
|
|
50
46
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'models/base'
|
|
2
4
|
require_relative 'models/user'
|
|
3
5
|
require_relative 'models/bot'
|
|
4
6
|
require_relative 'models/channel'
|
|
5
|
-
require_relative 'models/group'
|
|
6
7
|
require_relative 'models/team'
|
|
7
8
|
require_relative 'models/im'
|
|
9
|
+
require_relative 'models/mpim'
|
|
@@ -1,25 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Slack
|
|
2
3
|
module RealTime
|
|
3
4
|
class Socket
|
|
4
|
-
attr_accessor :url
|
|
5
|
-
attr_accessor :options
|
|
5
|
+
attr_accessor :url, :options
|
|
6
6
|
attr_reader :driver
|
|
7
|
-
attr_reader :logger
|
|
8
|
-
protected :logger
|
|
9
7
|
|
|
10
8
|
def initialize(url, options = {})
|
|
11
9
|
@url = url
|
|
12
|
-
@options = options
|
|
10
|
+
@options = options.dup
|
|
13
11
|
@driver = nil
|
|
14
|
-
@logger = options.delete(:logger) || Slack::RealTime::Config.logger || Slack::Config.logger
|
|
12
|
+
@logger = @options.delete(:logger) || Slack::RealTime::Config.logger || Slack::Config.logger
|
|
13
|
+
@last_message_at = nil
|
|
15
14
|
end
|
|
16
15
|
|
|
17
16
|
def send_data(message)
|
|
18
17
|
logger.debug("#{self.class}##{__method__}") { message }
|
|
19
18
|
case message
|
|
20
|
-
when Numeric then driver.text(message.to_s)
|
|
21
|
-
when String then driver.text(message)
|
|
22
|
-
when Array then driver.binary(message)
|
|
19
|
+
when Numeric then @driver.text(message.to_s)
|
|
20
|
+
when String then @driver.text(message)
|
|
21
|
+
when Array then @driver.binary(message)
|
|
23
22
|
else false
|
|
24
23
|
end
|
|
25
24
|
end
|
|
@@ -28,24 +27,31 @@ module Slack
|
|
|
28
27
|
return if connected?
|
|
29
28
|
|
|
30
29
|
connect
|
|
31
|
-
logger.debug("#{self.class}##{__method__}") { driver.class }
|
|
30
|
+
logger.debug("#{self.class}##{__method__}") { @driver.class }
|
|
31
|
+
|
|
32
|
+
@driver.on :message do
|
|
33
|
+
@last_message_at = current_time
|
|
34
|
+
end
|
|
32
35
|
|
|
33
|
-
yield driver if block_given?
|
|
36
|
+
yield @driver if block_given?
|
|
34
37
|
end
|
|
35
38
|
|
|
39
|
+
# Gracefully shut down the connection.
|
|
36
40
|
def disconnect!
|
|
37
|
-
driver.close
|
|
41
|
+
@driver.close
|
|
42
|
+
ensure
|
|
43
|
+
close
|
|
38
44
|
end
|
|
39
45
|
|
|
40
46
|
def connected?
|
|
41
|
-
|
|
47
|
+
!@driver.nil?
|
|
42
48
|
end
|
|
43
49
|
|
|
44
50
|
def start_sync(client)
|
|
45
51
|
thread = start_async(client)
|
|
46
|
-
thread
|
|
52
|
+
thread&.join
|
|
47
53
|
rescue Interrupt
|
|
48
|
-
thread
|
|
54
|
+
thread&.exit
|
|
49
55
|
end
|
|
50
56
|
|
|
51
57
|
# @return [#join]
|
|
@@ -53,12 +59,34 @@ module Slack
|
|
|
53
59
|
raise NotImplementedError, "Expected #{self.class} to implement #{__method__}."
|
|
54
60
|
end
|
|
55
61
|
|
|
62
|
+
def restart_async(_client, _url)
|
|
63
|
+
raise NotImplementedError, "Expected #{self.class} to implement #{__method__}."
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def time_since_last_message
|
|
67
|
+
return 0 unless @last_message_at
|
|
68
|
+
|
|
69
|
+
current_time - @last_message_at
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def current_time
|
|
73
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
74
|
+
end
|
|
75
|
+
|
|
56
76
|
def close
|
|
77
|
+
# When you call `driver.emit(:close)`, it will typically end up calling `client.close`
|
|
78
|
+
# which will call `@socket.close` and end up back here. In order to break this infinite
|
|
79
|
+
# recursion, we check and set `@driver = nil` before invoking `client.close`.
|
|
80
|
+
return unless (driver = @driver)
|
|
81
|
+
|
|
57
82
|
@driver = nil
|
|
83
|
+
driver.emit(:close)
|
|
58
84
|
end
|
|
59
85
|
|
|
60
86
|
protected
|
|
61
87
|
|
|
88
|
+
attr_reader :logger
|
|
89
|
+
|
|
62
90
|
def addr
|
|
63
91
|
URI(url).host
|
|
64
92
|
end
|
|
@@ -69,9 +97,9 @@ module Slack
|
|
|
69
97
|
|
|
70
98
|
def port
|
|
71
99
|
case (uri = URI(url)).scheme
|
|
72
|
-
when 'wss'
|
|
100
|
+
when 'wss', 'https'
|
|
73
101
|
URI::HTTPS::DEFAULT_PORT
|
|
74
|
-
when 'ws', 'http'
|
|
102
|
+
when 'ws', 'http'
|
|
75
103
|
URI::HTTP::DEFAULT_PORT
|
|
76
104
|
else
|
|
77
105
|
uri.port
|