graphql_channel.rb 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  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 = Gql::ZammadSchema.execute(query:, context:, variables:, operation_name:)
  18. payload = {
  19. result: result.to_h,
  20. more: result.subscription?,
  21. }
  22. # Track the subscription here so we can remove it
  23. # on unsubscribe.
  24. if result.context[:subscription_id]
  25. @subscription_ids << result.context[:subscription_id]
  26. end
  27. transmit(payload)
  28. end
  29. def unsubscribed
  30. @subscription_ids.each do |sid|
  31. Gql::ZammadSchema.subscriptions.delete_subscription(sid)
  32. end
  33. end
  34. private
  35. def ensure_hash(ambiguous_param)
  36. case ambiguous_param
  37. when String
  38. if ambiguous_param.present?
  39. ensure_hash(JSON.parse(ambiguous_param))
  40. else
  41. {}
  42. end
  43. when Hash, ActionController::Parameters
  44. ambiguous_param
  45. when nil
  46. {}
  47. else
  48. raise ArgumentError, "Unexpected parameter: #{ambiguous_param}"
  49. end
  50. end
  51. end