graphql_channel.rb 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. # Copyright (C) 2012-2025 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. current_user_id: current_user&.id,
  15. # :channel is required for ActionCableSubscriptions and MUST NOT be used otherwise.
  16. channel: self,
  17. }
  18. result = UserInfo.with_user_id(current_user&.id) do
  19. Gql::ZammadSchema.execute(query:, context:, variables:, operation_name:)
  20. end
  21. payload = {
  22. result: result.to_h,
  23. more: result.subscription?,
  24. }
  25. # Track the subscription here so we can remove it
  26. # on unsubscribe.
  27. if result.context[:subscription_id]
  28. @subscription_ids << result.context[:subscription_id]
  29. end
  30. transmit(payload)
  31. end
  32. def unsubscribed
  33. @subscription_ids.each do |sid|
  34. Gql::ZammadSchema.subscriptions.delete_subscription(sid)
  35. end
  36. end
  37. private
  38. def ensure_hash(ambiguous_param)
  39. case ambiguous_param
  40. when String
  41. if ambiguous_param.present?
  42. ensure_hash(JSON.parse(ambiguous_param))
  43. else
  44. {}
  45. end
  46. when Hash, ActionController::Parameters
  47. ambiguous_param
  48. when nil
  49. {}
  50. else
  51. raise ArgumentError, "Unexpected parameter: #{ambiguous_param}"
  52. end
  53. end
  54. end