graphql_channel.rb 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class GraphqlChannel < ApplicationCable::Channel
  3. def subscribed
  4. @subscription_ids = []
  5. end
  6. def execute(data)
  7. query = data['query']
  8. variables = ensure_hash(data['variables'])
  9. operation_name = data['operationName']
  10. # context must be kept in sync with GraphqlController!
  11. context = {
  12. sid: sid,
  13. current_user: current_user,
  14. # :channel is required for ActionCableSubscriptions and MUST NOT be used otherwise.
  15. channel: self,
  16. }
  17. result = UserInfo.with_user_id(current_user&.id) do
  18. Gql::ZammadSchema.execute(query:, context:, variables:, operation_name:)
  19. end
  20. payload = {
  21. result: result.to_h,
  22. more: result.subscription?,
  23. }
  24. # Track the subscription here so we can remove it
  25. # on unsubscribe.
  26. if result.context[:subscription_id]
  27. @subscription_ids << result.context[:subscription_id]
  28. end
  29. transmit(payload)
  30. end
  31. def unsubscribed
  32. @subscription_ids.each do |sid|
  33. Gql::ZammadSchema.subscriptions.delete_subscription(sid)
  34. end
  35. end
  36. private
  37. def ensure_hash(ambiguous_param)
  38. case ambiguous_param
  39. when String
  40. if ambiguous_param.present?
  41. ensure_hash(JSON.parse(ambiguous_param))
  42. else
  43. {}
  44. end
  45. when Hash, ActionController::Parameters
  46. ambiguous_param
  47. when nil
  48. {}
  49. else
  50. raise ArgumentError, "Unexpected parameter: #{ambiguous_param}"
  51. end
  52. end
  53. end