Module: StreamChat::Webhook

Defined in:
lib/getstream_ruby/generated/webhook.rb

Constant Summary collapse

EVENT_TYPE_WILDCARD =

Webhook event type constants

'*'
EVENT_TYPE_APPEAL_ACCEPTED =
'appeal.accepted'
EVENT_TYPE_APPEAL_CREATED =
'appeal.created'
EVENT_TYPE_APPEAL_REJECTED =
'appeal.rejected'
EVENT_TYPE_CALL_ACCEPTED =
'call.accepted'
EVENT_TYPE_CALL_BLOCKED_USER =
'call.blocked_user'
EVENT_TYPE_CALL_CLOSED_CAPTION =
'call.closed_caption'
EVENT_TYPE_CALL_CLOSED_CAPTIONS_FAILED =
'call.closed_captions_failed'
EVENT_TYPE_CALL_CLOSED_CAPTIONS_STARTED =
'call.closed_captions_started'
EVENT_TYPE_CALL_CLOSED_CAPTIONS_STOPPED =
'call.closed_captions_stopped'
EVENT_TYPE_CALL_CREATED =
'call.created'
EVENT_TYPE_CALL_DELETED =
'call.deleted'
EVENT_TYPE_CALL_DTMF =
'call.dtmf'
EVENT_TYPE_CALL_ENDED =
'call.ended'
EVENT_TYPE_CALL_FRAME_RECORDING_FAILED =
'call.frame_recording_failed'
EVENT_TYPE_CALL_FRAME_RECORDING_READY =
'call.frame_recording_ready'
EVENT_TYPE_CALL_FRAME_RECORDING_STARTED =
'call.frame_recording_started'
EVENT_TYPE_CALL_FRAME_RECORDING_STOPPED =
'call.frame_recording_stopped'
EVENT_TYPE_CALL_HLS_BROADCASTING_FAILED =
'call.hls_broadcasting_failed'
EVENT_TYPE_CALL_HLS_BROADCASTING_STARTED =
'call.hls_broadcasting_started'
EVENT_TYPE_CALL_HLS_BROADCASTING_STOPPED =
'call.hls_broadcasting_stopped'
EVENT_TYPE_CALL_KICKED_USER =
'call.kicked_user'
EVENT_TYPE_CALL_LIVE_STARTED =
'call.live_started'
EVENT_TYPE_CALL_MEMBER_ADDED =
'call.member_added'
EVENT_TYPE_CALL_MEMBER_REMOVED =
'call.member_removed'
EVENT_TYPE_CALL_MEMBER_UPDATED =
'call.member_updated'
EVENT_TYPE_CALL_MEMBER_UPDATED_PERMISSION =
'call.member_updated_permission'
EVENT_TYPE_CALL_MISSED =
'call.missed'
EVENT_TYPE_CALL_MODERATION_BLUR =
'call.moderation_blur'
EVENT_TYPE_CALL_MODERATION_WARNING =
'call.moderation_warning'
EVENT_TYPE_CALL_NOTIFICATION =
'call.notification'
EVENT_TYPE_CALL_PERMISSION_REQUEST =
'call.permission_request'
EVENT_TYPE_CALL_PERMISSIONS_UPDATED =
'call.permissions_updated'
EVENT_TYPE_CALL_REACTION_NEW =
'call.reaction_new'
EVENT_TYPE_CALL_RECORDING_FAILED =
'call.recording_failed'
EVENT_TYPE_CALL_RECORDING_READY =
'call.recording_ready'
EVENT_TYPE_CALL_RECORDING_STARTED =
'call.recording_started'
EVENT_TYPE_CALL_RECORDING_STOPPED =
'call.recording_stopped'
EVENT_TYPE_CALL_REJECTED =
'call.rejected'
EVENT_TYPE_CALL_RING =
'call.ring'
EVENT_TYPE_CALL_RTMP_BROADCAST_FAILED =
'call.rtmp_broadcast_failed'
EVENT_TYPE_CALL_RTMP_BROADCAST_STARTED =
'call.rtmp_broadcast_started'
EVENT_TYPE_CALL_RTMP_BROADCAST_STOPPED =
'call.rtmp_broadcast_stopped'
EVENT_TYPE_CALL_SESSION_ENDED =
'call.session_ended'
EVENT_TYPE_CALL_SESSION_PARTICIPANT_COUNT_UPDATED =
'call.session_participant_count_updated'
EVENT_TYPE_CALL_SESSION_PARTICIPANT_JOINED =
'call.session_participant_joined'
EVENT_TYPE_CALL_SESSION_PARTICIPANT_LEFT =
'call.session_participant_left'
EVENT_TYPE_CALL_SESSION_STARTED =
'call.session_started'
EVENT_TYPE_CALL_STATS_REPORT_READY =
'call.stats_report_ready'
EVENT_TYPE_CALL_TRANSCRIPTION_FAILED =
'call.transcription_failed'
EVENT_TYPE_CALL_TRANSCRIPTION_READY =
'call.transcription_ready'
EVENT_TYPE_CALL_TRANSCRIPTION_STARTED =
'call.transcription_started'
EVENT_TYPE_CALL_TRANSCRIPTION_STOPPED =
'call.transcription_stopped'
EVENT_TYPE_CALL_UNBLOCKED_USER =
'call.unblocked_user'
EVENT_TYPE_CALL_UPDATED =
'call.updated'
EVENT_TYPE_CALL_USER_FEEDBACK_SUBMITTED =
'call.user_feedback_submitted'
EVENT_TYPE_CALL_USER_MUTED =
'call.user_muted'
EVENT_TYPE_CAMPAIGN_COMPLETED =
'campaign.completed'
EVENT_TYPE_CAMPAIGN_STARTED =
'campaign.started'
EVENT_TYPE_CHANNEL_CREATED =
'channel.created'
EVENT_TYPE_CHANNEL_DELETED =
'channel.deleted'
EVENT_TYPE_CHANNEL_FROZEN =
'channel.frozen'
EVENT_TYPE_CHANNEL_HIDDEN =
'channel.hidden'
EVENT_TYPE_CHANNEL_MAX_STREAK_CHANGED =
'channel.max_streak_changed'
EVENT_TYPE_CHANNEL_MUTED =
'channel.muted'
EVENT_TYPE_CHANNEL_TRUNCATED =
'channel.truncated'
EVENT_TYPE_CHANNEL_UNFROZEN =
'channel.unfrozen'
EVENT_TYPE_CHANNEL_UNMUTED =
'channel.unmuted'
EVENT_TYPE_CHANNEL_UPDATED =
'channel.updated'
EVENT_TYPE_CHANNEL_VISIBLE =
'channel.visible'
EVENT_TYPE_CHANNEL_BATCH_UPDATE_COMPLETED =
'channel_batch_update.completed'
EVENT_TYPE_CHANNEL_BATCH_UPDATE_STARTED =
'channel_batch_update.started'
EVENT_TYPE_CUSTOM =
'custom'
EVENT_TYPE_EXPORT_BULK_IMAGE_MODERATION_ERROR =
'export.bulk_image_moderation.error'
EVENT_TYPE_EXPORT_BULK_IMAGE_MODERATION_SUCCESS =
'export.bulk_image_moderation.success'
EVENT_TYPE_EXPORT_CHANNELS_ERROR =
'export.channels.error'
EVENT_TYPE_EXPORT_CHANNELS_SUCCESS =
'export.channels.success'
EVENT_TYPE_EXPORT_MODERATION_LOGS_ERROR =
'export.moderation_logs.error'
EVENT_TYPE_EXPORT_MODERATION_LOGS_SUCCESS =
'export.moderation_logs.success'
EVENT_TYPE_EXPORT_USERS_ERROR =
'export.users.error'
EVENT_TYPE_EXPORT_USERS_SUCCESS =
'export.users.success'
EVENT_TYPE_FEEDS_ACTIVITY_ADDED =
'feeds.activity.added'
EVENT_TYPE_FEEDS_ACTIVITY_DELETED =
'feeds.activity.deleted'
EVENT_TYPE_FEEDS_ACTIVITY_FEEDBACK =
'feeds.activity.feedback'
EVENT_TYPE_FEEDS_ACTIVITY_MARKED =
'feeds.activity.marked'
EVENT_TYPE_FEEDS_ACTIVITY_PINNED =
'feeds.activity.pinned'
EVENT_TYPE_FEEDS_ACTIVITY_REACTION_ADDED =
'feeds.activity.reaction.added'
EVENT_TYPE_FEEDS_ACTIVITY_REACTION_DELETED =
'feeds.activity.reaction.deleted'
EVENT_TYPE_FEEDS_ACTIVITY_REACTION_UPDATED =
'feeds.activity.reaction.updated'
EVENT_TYPE_FEEDS_ACTIVITY_REMOVED_FROM_FEED =
'feeds.activity.removed_from_feed'
EVENT_TYPE_FEEDS_ACTIVITY_RESTORED =
'feeds.activity.restored'
EVENT_TYPE_FEEDS_ACTIVITY_UNPINNED =
'feeds.activity.unpinned'
EVENT_TYPE_FEEDS_ACTIVITY_UPDATED =
'feeds.activity.updated'
EVENT_TYPE_FEEDS_BOOKMARK_ADDED =
'feeds.bookmark.added'
EVENT_TYPE_FEEDS_BOOKMARK_DELETED =
'feeds.bookmark.deleted'
EVENT_TYPE_FEEDS_BOOKMARK_UPDATED =
'feeds.bookmark.updated'
EVENT_TYPE_FEEDS_BOOKMARK_FOLDER_DELETED =
'feeds.bookmark_folder.deleted'
EVENT_TYPE_FEEDS_BOOKMARK_FOLDER_UPDATED =
'feeds.bookmark_folder.updated'
EVENT_TYPE_FEEDS_COMMENT_ADDED =
'feeds.comment.added'
EVENT_TYPE_FEEDS_COMMENT_DELETED =
'feeds.comment.deleted'
EVENT_TYPE_FEEDS_COMMENT_REACTION_ADDED =
'feeds.comment.reaction.added'
EVENT_TYPE_FEEDS_COMMENT_REACTION_DELETED =
'feeds.comment.reaction.deleted'
EVENT_TYPE_FEEDS_COMMENT_REACTION_UPDATED =
'feeds.comment.reaction.updated'
EVENT_TYPE_FEEDS_COMMENT_UPDATED =
'feeds.comment.updated'
EVENT_TYPE_FEEDS_FEED_CREATED =
'feeds.feed.created'
EVENT_TYPE_FEEDS_FEED_DELETED =
'feeds.feed.deleted'
EVENT_TYPE_FEEDS_FEED_UPDATED =
'feeds.feed.updated'
EVENT_TYPE_FEEDS_FEED_GROUP_CHANGED =
'feeds.feed_group.changed'
EVENT_TYPE_FEEDS_FEED_GROUP_DELETED =
'feeds.feed_group.deleted'
EVENT_TYPE_FEEDS_FEED_GROUP_RESTORED =
'feeds.feed_group.restored'
EVENT_TYPE_FEEDS_FEED_MEMBER_ADDED =
'feeds.feed_member.added'
EVENT_TYPE_FEEDS_FEED_MEMBER_REMOVED =
'feeds.feed_member.removed'
EVENT_TYPE_FEEDS_FEED_MEMBER_UPDATED =
'feeds.feed_member.updated'
EVENT_TYPE_FEEDS_FOLLOW_CREATED =
'feeds.follow.created'
EVENT_TYPE_FEEDS_FOLLOW_DELETED =
'feeds.follow.deleted'
EVENT_TYPE_FEEDS_FOLLOW_UPDATED =
'feeds.follow.updated'
EVENT_TYPE_FEEDS_NOTIFICATION_FEED_UPDATED =
'feeds.notification_feed.updated'
EVENT_TYPE_FEEDS_STORIES_FEED_UPDATED =
'feeds.stories_feed.updated'
EVENT_TYPE_FLAG_UPDATED =
'flag.updated'
EVENT_TYPE_INGRESS_ERROR =
'ingress.error'
EVENT_TYPE_INGRESS_STARTED =
'ingress.started'
EVENT_TYPE_INGRESS_STOPPED =
'ingress.stopped'
EVENT_TYPE_MEMBER_ADDED =
'member.added'
EVENT_TYPE_MEMBER_REMOVED =
'member.removed'
EVENT_TYPE_MEMBER_UPDATED =
'member.updated'
EVENT_TYPE_MESSAGE_DELETED =
'message.deleted'
EVENT_TYPE_MESSAGE_FLAGGED =
'message.flagged'
EVENT_TYPE_MESSAGE_NEW =
'message.new'
EVENT_TYPE_MESSAGE_PENDING =
'message.pending'
EVENT_TYPE_MESSAGE_READ =
'message.read'
EVENT_TYPE_MESSAGE_UNBLOCKED =
'message.unblocked'
EVENT_TYPE_MESSAGE_UNDELETED =
'message.undeleted'
EVENT_TYPE_MESSAGE_UPDATED =
'message.updated'
EVENT_TYPE_MODERATION_CUSTOM_ACTION =
'moderation.custom_action'
EVENT_TYPE_MODERATION_FLAGGED =
'moderation.flagged'
EVENT_TYPE_MODERATION_MARK_REVIEWED =
'moderation.mark_reviewed'
EVENT_TYPE_MODERATION_CHECK_COMPLETED =
'moderation_check.completed'
EVENT_TYPE_MODERATION_RULE_TRIGGERED =
'moderation_rule.triggered'
EVENT_TYPE_NOTIFICATION_MARK_UNREAD =
'notification.mark_unread'
EVENT_TYPE_NOTIFICATION_REMINDER_DUE =
'notification.reminder_due'
EVENT_TYPE_NOTIFICATION_THREAD_MESSAGE_NEW =
'notification.thread_message_new'
EVENT_TYPE_REACTION_DELETED =
'reaction.deleted'
EVENT_TYPE_REACTION_NEW =
'reaction.new'
EVENT_TYPE_REACTION_UPDATED =
'reaction.updated'
EVENT_TYPE_REMINDER_CREATED =
'reminder.created'
EVENT_TYPE_REMINDER_DELETED =
'reminder.deleted'
EVENT_TYPE_REMINDER_UPDATED =
'reminder.updated'
EVENT_TYPE_REVIEW_QUEUE_ITEM_NEW =
'review_queue_item.new'
EVENT_TYPE_REVIEW_QUEUE_ITEM_UPDATED =
'review_queue_item.updated'
EVENT_TYPE_THREAD_UPDATED =
'thread.updated'
EVENT_TYPE_USER_BANNED =
'user.banned'
EVENT_TYPE_USER_DEACTIVATED =
'user.deactivated'
EVENT_TYPE_USER_DELETED =
'user.deleted'
EVENT_TYPE_USER_FLAGGED =
'user.flagged'
EVENT_TYPE_USER_MESSAGES_DELETED =
'user.messages.deleted'
EVENT_TYPE_USER_MUTED =
'user.muted'
EVENT_TYPE_USER_REACTIVATED =
'user.reactivated'
EVENT_TYPE_USER_UNBANNED =
'user.unbanned'
EVENT_TYPE_USER_UNMUTED =
'user.unmuted'
EVENT_TYPE_USER_UNREAD_MESSAGE_REMINDER =
'user.unread_message_reminder'
EVENT_TYPE_USER_UPDATED =
'user.updated'
EVENT_TYPE_USER_GROUP_CREATED =
'user_group.created'
EVENT_TYPE_USER_GROUP_DELETED =
'user_group.deleted'
EVENT_TYPE_USER_GROUP_MEMBER_ADDED =
'user_group.member_added'
EVENT_TYPE_USER_GROUP_MEMBER_REMOVED =
'user_group.member_removed'
EVENT_TYPE_USER_GROUP_UPDATED =
'user_group.updated'

Class Method Summary collapse

Class Method Details

.get_event_type(raw_event) ⇒ String?

Extract the event type from a raw webhook payload.

Parameters:

  • raw_event (String, Hash)

    The raw webhook payload

Returns:

  • (String, nil)

    The event type string (e.g., “message.new”)



343
344
345
346
# File 'lib/getstream_ruby/generated/webhook.rb', line 343

def self.get_event_type(raw_event)
  data = parse_to_hash(raw_event)
  data&.fetch('type', nil)
end

.parse_webhook_event(raw_event) ⇒ Object

Deserialize a raw webhook payload into a typed event object.

Parameters:

  • raw_event (String, Hash)

    The raw webhook payload

Returns:

  • (Object)

    A typed event object corresponding to the event type

Raises:

  • (ArgumentError)

    if the event type is unknown or deserialization fails



353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/getstream_ruby/generated/webhook.rb', line 353

def self.parse_webhook_event(raw_event)
  data = parse_to_hash(raw_event)
  raise ArgumentError, 'Invalid webhook payload' unless data

  event_type = data['type']
  raise ArgumentError, "Webhook payload missing 'type' field" unless event_type

  event_class = event_class_for_type(event_type)
  raise ArgumentError, "Unknown webhook event type: #{event_type}" unless event_class

  event_class.new(data)
rescue JSON::ParserError => e
  raise ArgumentError, "Invalid JSON in webhook payload: #{e.message}"
rescue StandardError => e
  raise ArgumentError, "Failed to deserialize webhook event: #{e.message}"
end

.verify_signature(body, signature, secret) ⇒ Boolean

Verify the HMAC-SHA256 signature of a webhook payload.

Parameters:

  • body (String)

    The raw request body

  • signature (String)

    The signature from the X-Signature header

  • secret (String)

    Your webhook secret (found in the Stream Dashboard)

Returns:

  • (Boolean)

    true if the signature is valid, false otherwise



728
729
730
731
732
733
734
735
# File 'lib/getstream_ruby/generated/webhook.rb', line 728

def self.verify_signature(body, signature, secret)
  return false if signature.nil? || signature.bytesize != 64
  
  expected = OpenSSL::HMAC.hexdigest('SHA256', secret, body)
  OpenSSL.fixed_length_secure_compare(signature, expected)
rescue ArgumentError
  false
end