slack-ruby-client 0.13.0 → 0.17.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/.gitignore +1 -0
- data/.rubocop.yml +24 -5
- data/.rubocop_todo.yml +100 -54
- data/.travis.yml +4 -8
- data/CHANGELOG.md +118 -35
- data/CONTRIBUTING.md +17 -6
- data/Dangerfile +2 -0
- data/Gemfile +10 -5
- data/LICENSE.md +1 -1
- data/README.md +185 -48
- data/Rakefile +2 -1
- data/UPGRADING.md +30 -2
- data/bin/commands.rb +32 -0
- data/bin/commands/admin_analytics.rb +16 -0
- data/bin/commands/admin_apps.rb +40 -0
- data/bin/commands/admin_apps_approved.rb +17 -0
- data/bin/commands/admin_apps_requests.rb +16 -0
- data/bin/commands/admin_apps_restricted.rb +17 -0
- data/bin/commands/admin_barriers.rb +47 -0
- data/bin/commands/admin_conversations.rb +159 -0
- data/bin/commands/admin_conversations_ekm.rb +17 -0
- data/bin/commands/admin_conversations_restrictAccess.rb +37 -0
- data/bin/commands/admin_conversations_whitelist.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 +97 -0
- data/bin/commands/admin_users_session.rb +38 -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_permissions.rb +1 -0
- data/bin/commands/apps_permissions_resources.rb +1 -0
- data/bin/commands/apps_permissions_scopes.rb +1 -0
- data/bin/commands/apps_permissions_users.rb +1 -0
- data/bin/commands/auth.rb +1 -0
- data/bin/commands/auth_teams.rb +16 -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/channels.rb +1 -153
- data/bin/commands/chat.rb +51 -10
- data/bin/commands/chat_scheduledMessages.rb +19 -0
- data/bin/commands/conversations.rb +16 -3
- data/bin/commands/dialog.rb +1 -0
- data/bin/commands/dnd.rb +5 -2
- data/bin/commands/emoji.rb +1 -0
- data/bin/commands/files.rb +8 -17
- data/bin/commands/files_comments.rb +1 -21
- data/bin/commands/files_remote.rb +78 -0
- data/bin/commands/groups.rb +1 -161
- data/bin/commands/im.rb +1 -62
- data/bin/commands/migration.rb +2 -0
- data/bin/commands/mpim.rb +1 -60
- data/bin/commands/oauth.rb +2 -1
- data/bin/commands/oauth_v2.rb +17 -0
- data/bin/commands/pins.rb +1 -4
- data/bin/commands/reactions.rb +3 -3
- data/bin/commands/reminders.rb +1 -0
- data/bin/commands/rtm.rb +1 -0
- data/bin/commands/search.rb +4 -0
- data/bin/commands/stars.rb +1 -0
- data/bin/commands/team.rb +5 -0
- data/bin/commands/team_profile.rb +1 -0
- data/bin/commands/usergroups.rb +6 -0
- data/bin/commands/usergroups_users.rb +3 -0
- data/bin/commands/users.rb +5 -3
- 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 +48 -0
- data/bin/commands/workflows.rb +38 -0
- data/bin/slack +2 -3
- 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-ruby-client.rb +10 -4
- data/lib/slack.rb +1 -0
- data/lib/slack/config.rb +1 -0
- data/lib/slack/events/config.rb +32 -0
- data/lib/slack/events/request.rb +70 -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 +3 -1
- 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/typing.rb +3 -1
- data/lib/slack/real_time/client.rb +98 -28
- data/lib/slack/real_time/concurrency.rb +1 -2
- data/lib/slack/real_time/concurrency/async.rb +79 -6
- data/lib/slack/real_time/config.rb +6 -10
- data/lib/slack/real_time/models.rb +1 -0
- 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 +1 -0
- data/lib/slack/real_time/models/group.rb +1 -0
- data/lib/slack/real_time/models/im.rb +1 -0
- 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/socket.rb +44 -15
- data/lib/slack/real_time/stores.rb +1 -0
- data/lib/slack/real_time/stores/base.rb +4 -1
- data/lib/slack/real_time/stores/starter.rb +11 -0
- data/lib/slack/real_time/stores/store.rb +28 -25
- data/lib/slack/version.rb +2 -1
- data/lib/slack/web/api/endpoints.rb +64 -0
- data/lib/slack/web/api/endpoints/admin_analytics.rb +28 -0
- data/lib/slack/web/api/endpoints/admin_apps.rb +62 -0
- data/lib/slack/web/api/endpoints/admin_apps_approved.rb +35 -0
- data/lib/slack/web/api/endpoints/admin_apps_requests.rb +33 -0
- data/lib/slack/web/api/endpoints/admin_apps_restricted.rb +35 -0
- data/lib/slack/web/api/endpoints/admin_barriers.rb +82 -0
- data/lib/slack/web/api/endpoints/admin_conversations.rb +246 -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_conversations_whitelist.rb +64 -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 +161 -0
- data/lib/slack/web/api/endpoints/admin_users_session.rb +66 -0
- data/lib/slack/web/api/endpoints/api.rb +1 -2
- 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_permissions.rb +1 -0
- data/lib/slack/web/api/endpoints/apps_permissions_resources.rb +1 -0
- data/lib/slack/web/api/endpoints/apps_permissions_scopes.rb +1 -0
- data/lib/slack/web/api/endpoints/apps_permissions_users.rb +1 -0
- data/lib/slack/web/api/endpoints/auth.rb +1 -0
- data/lib/slack/web/api/endpoints/auth_teams.rb +33 -0
- data/lib/slack/web/api/endpoints/bots.rb +3 -0
- 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/channels.rb +2 -243
- data/lib/slack/web/api/endpoints/chat.rb +112 -21
- data/lib/slack/web/api/endpoints/chat_scheduledMessages.rb +40 -0
- data/lib/slack/web/api/endpoints/conversations.rb +40 -19
- data/lib/slack/web/api/endpoints/dialog.rb +1 -0
- data/lib/slack/web/api/endpoints/dnd.rb +7 -1
- data/lib/slack/web/api/endpoints/emoji.rb +1 -0
- data/lib/slack/web/api/endpoints/files.rb +10 -17
- data/lib/slack/web/api/endpoints/files_comments.rb +1 -33
- data/lib/slack/web/api/endpoints/files_remote.rb +127 -0
- data/lib/slack/web/api/endpoints/groups.rb +1 -253
- data/lib/slack/web/api/endpoints/im.rb +1 -101
- data/lib/slack/web/api/endpoints/migration.rb +3 -0
- data/lib/slack/web/api/endpoints/mpim.rb +1 -96
- data/lib/slack/web/api/endpoints/oauth.rb +2 -4
- data/lib/slack/web/api/endpoints/oauth_v2.rb +30 -0
- data/lib/slack/web/api/endpoints/pins.rb +4 -11
- data/lib/slack/web/api/endpoints/reactions.rb +10 -9
- data/lib/slack/web/api/endpoints/reminders.rb +1 -0
- data/lib/slack/web/api/endpoints/rtm.rb +1 -0
- data/lib/slack/web/api/endpoints/search.rb +7 -0
- data/lib/slack/web/api/endpoints/stars.rb +3 -2
- data/lib/slack/web/api/endpoints/team.rb +9 -0
- data/lib/slack/web/api/endpoints/team_profile.rb +1 -0
- data/lib/slack/web/api/endpoints/usergroups.rb +11 -0
- data/lib/slack/web/api/endpoints/usergroups_users.rb +5 -0
- data/lib/slack/web/api/endpoints/users.rb +8 -7
- data/lib/slack/web/api/endpoints/users_admin.rb +1 -0
- data/lib/slack/web/api/endpoints/users_prefs.rb +1 -0
- data/lib/slack/web/api/endpoints/users_profile.rb +4 -3
- data/lib/slack/web/api/endpoints/views.rb +97 -0
- data/lib/slack/web/api/endpoints/workflows.rb +61 -0
- data/lib/slack/web/api/error.rb +1 -0
- data/lib/slack/web/api/errors.rb +848 -0
- data/lib/slack/web/api/errors/internal_error.rb +14 -0
- data/lib/slack/web/api/errors/slack_error.rb +14 -1
- data/lib/slack/web/api/errors/too_many_requests_error.rb +1 -0
- data/lib/slack/web/api/mixins.rb +2 -0
- data/lib/slack/web/api/mixins/channels.id.rb +2 -3
- data/lib/slack/web/api/mixins/conversations.id.rb +25 -0
- data/lib/slack/web/api/mixins/groups.id.rb +2 -3
- data/lib/slack/web/api/mixins/ids.id.rb +3 -2
- data/lib/slack/web/api/mixins/users.id.rb +2 -3
- data/lib/slack/web/api/mixins/users.search.rb +1 -0
- data/lib/slack/web/api/patches/chat.1.patch +71 -0
- data/lib/slack/web/api/patches/views.1.view-json.patch +40 -0
- data/lib/slack/web/api/patches/views.1.views-published.patch +16 -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 -0
- data/lib/slack/web/api/templates/errors.erb +20 -0
- data/lib/slack/web/api/templates/method.erb +5 -1
- 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 +3 -0
- data/lib/slack/web/faraday/connection.rb +24 -20
- data/lib/slack/web/faraday/request.rb +1 -0
- data/lib/slack/web/faraday/response/raise_error.rb +21 -6
- data/lib/slack/web/faraday/response/wrap_error.rb +24 -0
- data/lib/slack/web/pagination/cursor.rb +6 -2
- data/lib/slack_ruby_client.rb +1 -0
- data/lib/tasks/git.rake +1 -0
- data/lib/tasks/real_time.rake +15 -5
- data/lib/tasks/update.rake +1 -0
- data/lib/tasks/web.rake +39 -10
- data/screenshots/create-app.png +0 -0
- data/slack-ruby-client.gemspec +8 -4
- data/spec/fixtures/slack/web/channels_info.yml +108 -15
- data/spec/fixtures/slack/web/{groups_info.yml → conversations_info.yml} +4 -4
- data/spec/fixtures/slack/web/conversations_setTopic.yml +69 -0
- data/spec/fixtures/slack/web/conversations_setTopic_one_page.yml +142 -0
- data/spec/fixtures/slack/web/conversations_setTopic_paginated.yml +208 -0
- data/spec/fixtures/slack/web/views_open_error.yml +76 -0
- data/spec/integration/integration_spec.rb +116 -49
- data/spec/slack/config_spec.rb +2 -0
- data/spec/slack/events/config_spec.rb +33 -0
- data/spec/slack/events/request_spec.rb +184 -0
- data/spec/slack/messages/formatting_spec.rb +25 -13
- data/spec/slack/real_time/api/message_spec.rb +6 -1
- data/spec/slack/real_time/api/ping_spec.rb +2 -0
- data/spec/slack/real_time/api/typing_spec.rb +5 -1
- data/spec/slack/real_time/client_spec.rb +228 -30
- 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 +2 -1
- data/spec/slack/real_time/event_handlers/channel_spec.rb +9 -6
- data/spec/slack/real_time/event_handlers/event_handlers_spec.rb +2 -1
- data/spec/slack/real_time/event_handlers/group_spec.rb +5 -4
- data/spec/slack/real_time/event_handlers/im_spec.rb +4 -3
- data/spec/slack/real_time/event_handlers/team_spec.rb +3 -1
- data/spec/slack/real_time/event_handlers/user_spec.rb +1 -0
- data/spec/slack/real_time/rtm_connect_spec.rb +2 -1
- data/spec/slack/real_time/rtm_start_spec.rb +2 -1
- data/spec/slack/real_time/store_spec.rb +2 -1
- data/spec/slack/slack_spec.rb +37 -5
- 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 +8 -0
- data/spec/slack/web/api/endpoints/admin_apps_restricted_spec.rb +8 -0
- data/spec/slack/web/api/endpoints/admin_apps_spec.rb +13 -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 +93 -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 +21 -0
- data/spec/slack/web/api/endpoints/admin_users_spec.rb +67 -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_permissions_resources_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/apps_permissions_scopes_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/apps_permissions_spec.rb +3 -2
- data/spec/slack/web/api/endpoints/apps_permissions_users_spec.rb +4 -3
- data/spec/slack/web/api/endpoints/apps_spec.rb +16 -0
- data/spec/slack/web/api/endpoints/auth_teams_spec.rb +8 -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/conversations_spec.rb +21 -12
- data/spec/slack/web/api/endpoints/custom_specs/auth_spec.rb +5 -1
- data/spec/slack/web/api/endpoints/custom_specs/chat_spec.rb +112 -36
- data/spec/slack/web/api/endpoints/custom_specs/conversations_spec.rb +13 -0
- data/spec/slack/web/api/endpoints/custom_specs/dialog_spec.rb +12 -4
- data/spec/slack/web/api/endpoints/custom_specs/users_spec.rb +6 -1
- data/spec/slack/web/api/endpoints/custom_specs/views_spec.rb +95 -0
- data/spec/slack/web/api/endpoints/dnd_spec.rb +6 -0
- 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 +5 -4
- data/spec/slack/web/api/endpoints/im_spec.rb +1 -31
- data/spec/slack/web/api/endpoints/migration_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/mpim_spec.rb +1 -31
- data/spec/slack/web/api/endpoints/oauth_spec.rb +4 -14
- data/spec/slack/web/api/endpoints/oauth_v2_spec.rb +13 -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/team_profile_spec.rb +1 -0
- data/spec/slack/web/api/endpoints/team_spec.rb +1 -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 +4 -2
- data/spec/slack/web/api/errors/slack_error_spec.rb +26 -2
- data/spec/slack/web/api/mixins/channels_spec.rb +17 -7
- data/spec/slack/web/api/mixins/conversations_list_spec.rb +21 -0
- data/spec/slack/web/api/mixins/conversations_spec.rb +43 -0
- data/spec/slack/web/api/mixins/groups_spec.rb +17 -7
- data/spec/slack/web/api/mixins/users_spec.rb +17 -8
- data/spec/slack/web/api/pagination/cursor_spec.rb +40 -10
- data/spec/slack/web/client_spec.rb +166 -18
- data/spec/slack/web/faraday/response/raise_error_spec.rb +47 -12
- data/spec/spec_helper.rb +8 -1
- 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 +9 -3
- data/spec/support/real_time/event.rb +1 -0
- data/spec/support/token.rb +1 -0
- data/spec/support/vcr.rb +5 -0
- metadata +226 -52
- 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 -103
- data/lib/slack/real_time/concurrency/eventmachine.rb +0 -66
- 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/slack/real_time/concurrency/celluloid_spec.rb +0 -106
- data/spec/slack/real_time/concurrency/eventmachine_spec.rb +0 -47
- 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/errors/service_unavailable_spec.rb +0 -14
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Slack
|
|
2
3
|
module RealTime
|
|
3
4
|
class Client
|
|
@@ -20,7 +21,6 @@ module Slack
|
|
|
20
21
|
attr_accessor :url
|
|
21
22
|
attr_accessor(*Config::ATTRIBUTES)
|
|
22
23
|
|
|
23
|
-
protected :logger, :logger=
|
|
24
24
|
protected :store_class, :store_class=
|
|
25
25
|
|
|
26
26
|
def initialize(options = {})
|
|
@@ -35,7 +35,7 @@ module Slack
|
|
|
35
35
|
|
|
36
36
|
%i[users self channels team teams groups ims bots].each do |store_method|
|
|
37
37
|
define_method store_method do
|
|
38
|
-
store
|
|
38
|
+
store&.send(store_method)
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
@@ -47,7 +47,7 @@ module Slack
|
|
|
47
47
|
# Start RealTime client and block until it disconnects.
|
|
48
48
|
def start!(&block)
|
|
49
49
|
@callback = block if block_given?
|
|
50
|
-
|
|
50
|
+
build_socket
|
|
51
51
|
@socket.start_sync(self)
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -55,17 +55,18 @@ module Slack
|
|
|
55
55
|
# The RealTime::Client will run in the background.
|
|
56
56
|
def start_async(&block)
|
|
57
57
|
@callback = block if block_given?
|
|
58
|
-
|
|
58
|
+
build_socket
|
|
59
59
|
@socket.start_async(self)
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def stop!
|
|
63
63
|
raise ClientNotStartedError unless started?
|
|
64
|
-
|
|
64
|
+
|
|
65
|
+
@socket&.disconnect!
|
|
65
66
|
end
|
|
66
67
|
|
|
67
68
|
def started?
|
|
68
|
-
@socket
|
|
69
|
+
@socket&.connected?
|
|
69
70
|
end
|
|
70
71
|
|
|
71
72
|
class << self
|
|
@@ -80,38 +81,105 @@ module Slack
|
|
|
80
81
|
|
|
81
82
|
def run_loop
|
|
82
83
|
@socket.connect! do |driver|
|
|
83
|
-
@callback.call(driver) if @callback
|
|
84
|
-
|
|
85
84
|
driver.on :open do |event|
|
|
86
|
-
logger.debug("#{self
|
|
87
|
-
|
|
85
|
+
logger.debug("#{self}##{__method__}") { event.class.name }
|
|
86
|
+
open_event(event)
|
|
88
87
|
callback(event, :open)
|
|
89
88
|
end
|
|
90
89
|
|
|
91
90
|
driver.on :message do |event|
|
|
92
|
-
logger.debug("#{self
|
|
91
|
+
logger.debug("#{self}##{__method__}") { "#{event.class}, #{event.data}" }
|
|
93
92
|
dispatch(event)
|
|
94
93
|
end
|
|
95
94
|
|
|
96
95
|
driver.on :close do |event|
|
|
97
|
-
logger.debug("#{self
|
|
96
|
+
logger.debug("#{self}##{__method__}") { event.class.name }
|
|
98
97
|
callback(event, :close)
|
|
99
98
|
close(event)
|
|
100
99
|
callback(event, :closed)
|
|
101
100
|
end
|
|
101
|
+
|
|
102
|
+
# This must be called last to ensure any events are registered before invoking user code.
|
|
103
|
+
@callback&.call(driver)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Ensure the server is running, and ping the remote server if no other messages were sent.
|
|
108
|
+
def keep_alive?
|
|
109
|
+
# We can't ping the remote server if we aren't connected.
|
|
110
|
+
return false if @socket.nil? || !@socket.connected?
|
|
111
|
+
|
|
112
|
+
time_since_last_message = @socket.time_since_last_message
|
|
113
|
+
|
|
114
|
+
# If the server responded within the specified time, we are okay:
|
|
115
|
+
return true if time_since_last_message < websocket_ping
|
|
116
|
+
|
|
117
|
+
# If the server has not responded for a while:
|
|
118
|
+
return false if time_since_last_message > (websocket_ping * 2)
|
|
119
|
+
|
|
120
|
+
# Kick off the next ping message:
|
|
121
|
+
ping
|
|
122
|
+
|
|
123
|
+
true
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Check if the remote server is responsive, and if not, restart the connection.
|
|
127
|
+
def run_ping!
|
|
128
|
+
return if keep_alive?
|
|
129
|
+
|
|
130
|
+
logger.warn(to_s) { 'is offline' }
|
|
131
|
+
|
|
132
|
+
restart_async
|
|
133
|
+
rescue Slack::Web::Api::Errors::SlackError => e
|
|
134
|
+
# stop pinging if bot was uninstalled
|
|
135
|
+
case e.message
|
|
136
|
+
when 'account_inactive', 'invalid_auth' then
|
|
137
|
+
logger.warn(to_s) { e.message }
|
|
138
|
+
raise e
|
|
139
|
+
end
|
|
140
|
+
logger.debug("#{self}##{__method__}") { e }
|
|
141
|
+
rescue StandardError => e
|
|
142
|
+
# disregard all ping worker failures, keep pinging
|
|
143
|
+
logger.debug("#{self}##{__method__}") { e }
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def run_ping?
|
|
147
|
+
!websocket_ping.nil? && websocket_ping.positive?
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def websocket_ping_timer
|
|
151
|
+
websocket_ping / 2
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def to_s
|
|
155
|
+
if store&.team
|
|
156
|
+
"id=#{store.team.id}, name=#{store.team.name}, domain=#{store.team.domain}"
|
|
157
|
+
else
|
|
158
|
+
super
|
|
102
159
|
end
|
|
103
160
|
end
|
|
104
161
|
|
|
105
162
|
protected
|
|
106
163
|
|
|
164
|
+
def restart_async
|
|
165
|
+
logger.debug("#{self}##{__method__}")
|
|
166
|
+
@socket.close
|
|
167
|
+
start = web_client.send(rtm_start_method, start_options)
|
|
168
|
+
data = Slack::Messages::Message.new(start)
|
|
169
|
+
@url = data.url
|
|
170
|
+
@store = @store_class.new(data) if @store_class
|
|
171
|
+
@socket.restart_async(self, @url)
|
|
172
|
+
end
|
|
173
|
+
|
|
107
174
|
# @return [Slack::RealTime::Socket]
|
|
108
175
|
def build_socket
|
|
109
176
|
raise ClientAlreadyStartedError if started?
|
|
177
|
+
|
|
110
178
|
start = web_client.send(rtm_start_method, start_options)
|
|
111
179
|
data = Slack::Messages::Message.new(start)
|
|
112
180
|
@url = data.url
|
|
113
181
|
@store = @store_class.new(data) if @store_class
|
|
114
|
-
socket_class.new(@url, socket_options)
|
|
182
|
+
@socket = socket_class.new(@url, socket_options)
|
|
115
183
|
end
|
|
116
184
|
|
|
117
185
|
def rtm_start_method
|
|
@@ -139,17 +207,15 @@ module Slack
|
|
|
139
207
|
|
|
140
208
|
def send_json(data)
|
|
141
209
|
raise ClientNotStartedError unless started?
|
|
142
|
-
|
|
210
|
+
|
|
211
|
+
logger.debug("#{self}##{__method__}") { data }
|
|
143
212
|
@socket.send_data(data.to_json)
|
|
144
213
|
end
|
|
145
214
|
|
|
146
|
-
def
|
|
215
|
+
def open_event(_event); end
|
|
147
216
|
|
|
148
217
|
def close(_event)
|
|
149
|
-
socket
|
|
150
|
-
@socket = nil
|
|
151
|
-
|
|
152
|
-
[socket, socket_class].each do |s|
|
|
218
|
+
[@socket, socket_class].each do |s|
|
|
153
219
|
s.close if s.respond_to?(:close)
|
|
154
220
|
end
|
|
155
221
|
end
|
|
@@ -157,50 +223,54 @@ module Slack
|
|
|
157
223
|
def callback(event, type)
|
|
158
224
|
callbacks = self.callbacks[type.to_s]
|
|
159
225
|
return false unless callbacks
|
|
226
|
+
|
|
160
227
|
callbacks.each do |c|
|
|
161
228
|
c.call(event)
|
|
162
229
|
end
|
|
163
230
|
true
|
|
164
231
|
rescue StandardError => e
|
|
165
|
-
logger.error e
|
|
232
|
+
logger.error("#{self}##{__method__}") { e }
|
|
166
233
|
false
|
|
167
234
|
end
|
|
168
235
|
|
|
169
236
|
def dispatch(event)
|
|
170
237
|
return false unless event.data
|
|
238
|
+
|
|
171
239
|
data = Slack::Messages::Message.new(JSON.parse(event.data))
|
|
172
240
|
type = data.type
|
|
173
241
|
return false unless type
|
|
242
|
+
|
|
174
243
|
type = type.to_s
|
|
175
|
-
logger.debug("#{self
|
|
244
|
+
logger.debug("#{self}##{__method__}") { data.to_s }
|
|
176
245
|
run_handlers(type, data) if @store
|
|
177
246
|
run_callbacks(type, data)
|
|
178
247
|
rescue StandardError => e
|
|
179
|
-
logger.error e
|
|
248
|
+
logger.error("#{self}##{__method__}") { e }
|
|
180
249
|
false
|
|
181
250
|
end
|
|
182
251
|
|
|
183
252
|
def run_handlers(type, data)
|
|
253
|
+
return unless store.class.events
|
|
254
|
+
|
|
184
255
|
handlers = store.class.events[type.to_s]
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
store.instance_exec(data, &handler)
|
|
188
|
-
end
|
|
256
|
+
handlers&.each do |handler|
|
|
257
|
+
store.instance_exec(data, &handler)
|
|
189
258
|
end
|
|
190
259
|
rescue StandardError => e
|
|
191
|
-
logger.error e
|
|
260
|
+
logger.error("#{self}##{__method__}") { e }
|
|
192
261
|
false
|
|
193
262
|
end
|
|
194
263
|
|
|
195
264
|
def run_callbacks(type, data)
|
|
196
265
|
callbacks = self.callbacks[type]
|
|
197
266
|
return false unless callbacks
|
|
267
|
+
|
|
198
268
|
callbacks.each do |c|
|
|
199
269
|
c.call(data)
|
|
200
270
|
end
|
|
201
271
|
true
|
|
202
272
|
rescue StandardError => e
|
|
203
|
-
logger.error e
|
|
273
|
+
logger.error("#{self}##{__method__}") { e }
|
|
204
274
|
false
|
|
205
275
|
end
|
|
206
276
|
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,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,91 @@ 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
|
+
begin
|
|
49
|
+
subtask.annotate "#{client} run-loop"
|
|
50
|
+
client.run_loop
|
|
51
|
+
rescue ::Async::Wrapper::Cancelled => e
|
|
52
|
+
# Will get restarted by ping worker.
|
|
53
|
+
rescue StandardError => e
|
|
54
|
+
client.logger.error(subtask.to_s) { e.message }
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
@restart.wait
|
|
19
59
|
end
|
|
60
|
+
|
|
61
|
+
@ping_task&.stop
|
|
20
62
|
end
|
|
21
63
|
end
|
|
22
64
|
|
|
65
|
+
def restart_async(_client, new_url)
|
|
66
|
+
@url = new_url
|
|
67
|
+
@last_message_at = current_time
|
|
68
|
+
|
|
69
|
+
@restart&.signal
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def current_time
|
|
73
|
+
::Async::Clock.now
|
|
74
|
+
end
|
|
75
|
+
|
|
23
76
|
def connect!
|
|
24
77
|
super
|
|
25
78
|
run_loop
|
|
26
79
|
end
|
|
27
80
|
|
|
81
|
+
# Kill the restart/ping loop.
|
|
82
|
+
def disconnect!
|
|
83
|
+
super
|
|
84
|
+
ensure
|
|
85
|
+
if (restart = @restart)
|
|
86
|
+
@restart = nil
|
|
87
|
+
restart.signal
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Close the socket.
|
|
28
92
|
def close
|
|
29
|
-
@closing = true
|
|
30
|
-
@driver.close if @driver
|
|
31
93
|
super
|
|
94
|
+
ensure
|
|
95
|
+
if @socket
|
|
96
|
+
@socket.close
|
|
97
|
+
@socket = nil
|
|
98
|
+
end
|
|
32
99
|
end
|
|
33
100
|
|
|
34
101
|
def run_loop
|
|
35
|
-
@
|
|
36
|
-
while @driver && @driver.next_event
|
|
102
|
+
while @driver&.next_event
|
|
37
103
|
# $stderr.puts event.inspect
|
|
38
104
|
end
|
|
39
105
|
end
|
|
@@ -65,3 +131,10 @@ module Slack
|
|
|
65
131
|
end
|
|
66
132
|
end
|
|
67
133
|
end
|
|
134
|
+
|
|
135
|
+
if Gem::Version.new(Async::WebSocket::VERSION) >= Gem::Version.new('0.9.0')
|
|
136
|
+
raise(
|
|
137
|
+
"Incompatible version of async-websocket, #{Async::WebSocket::VERSION}, " \
|
|
138
|
+
"use \"gem 'async-websocket', '~> 0.8.0'\"."
|
|
139
|
+
)
|
|
140
|
+
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Slack
|
|
2
3
|
module RealTime
|
|
3
4
|
module Config
|
|
@@ -16,7 +17,8 @@ module Slack
|
|
|
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
|
|
@@ -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
|
|