Module: HeyQuarry::ShopifyProfileSync::Sync

Defined in:
lib/heyquarry/shopify_profile_sync/sync.rb

Class Method Summary collapse

Class Method Details

.fetch_shop_from_session(shop_domain, access_token, admin_api_version) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/heyquarry/shopify_profile_sync/sync.rb', line 51

def fetch_shop_from_session(shop_domain, access_token, admin_api_version)
  host = shop_domain.sub(%r{\Ahttps?://}, "").sub(%r{/\z}, "")
  uri = URI("https://#{host}/admin/api/#{admin_api_version}/graphql.json")
  request = Net::HTTP::Post.new(uri)
  request["Content-Type"] = "application/json"
  request["X-Shopify-Access-Token"] = access_token
  request.body = JSON.generate(query: SHOP_PROFILE_QUERY)

  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(request) }
  JSON.parse(response.body).dig("data", "shop")
end

.post_profile(profile_url, api_key, payload) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/heyquarry/shopify_profile_sync/sync.rb', line 63

def post_profile(profile_url, api_key, payload)
  uri = URI(profile_url)
  request = Net::HTTP::Post.new(uri)
  request["Content-Type"] = "application/json"
  request["X-App-Api-Key"] = api_key
  request.body = JSON.generate(payload.transform_keys(&:to_s))

  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(request) }
  if response.is_a?(Net::HTTPSuccess)
    SyncResult.new(ok: true, shop_domain: payload[:shopDomain], status: response.code.to_i)
  else
    SyncResult.new(
      ok: false,
      shop_domain: payload[:shopDomain],
      status: response.code.to_i,
      error: response.body.to_s[0, 300].presence || response.message,
    )
  end
end

.post_profile_to_heyquarry(payload, api_key: nil, profile_url: nil) ⇒ Object



36
37
38
39
40
41
# File 'lib/heyquarry/shopify_profile_sync/sync.rb', line 36

def post_profile_to_heyquarry(payload, api_key: nil, profile_url: nil)
  resolved = resolve_options(api_key: api_key, profile_url: profile_url)
  return skipped("shopDomain is required") unless payload.is_a?(Hash) && payload[:shopDomain]

  post_profile(resolved[:profile_url], resolved[:api_key], payload)
end

.resolve_options(api_key:, profile_url:) ⇒ Object

Raises:

  • (ArgumentError)


43
44
45
46
47
48
49
# File 'lib/heyquarry/shopify_profile_sync/sync.rb', line 43

def resolve_options(api_key:, profile_url:)
  key = api_key || ENV["HEYQUARRY_APP_API_KEY"]
  raise ArgumentError, "HeyQuarry app API key is required. Pass api_key: or set HEYQUARRY_APP_API_KEY." if key.nil? || key.strip.empty?

  url = profile_url || ENV["HEYQUARRY_PROFILE_URL"] || DEFAULT_PROFILE_URL
  { api_key: key.strip, profile_url: url.sub(%r{/\z}, "") }
end

.skipped(message) ⇒ Object



83
84
85
# File 'lib/heyquarry/shopify_profile_sync/sync.rb', line 83

def skipped(message)
  SyncResult.new(ok: false, skipped: true, error: message)
end

.sync_from_admin_client(client, api_key: nil, profile_url: nil) ⇒ Object



26
27
28
29
30
31
32
33
34
# File 'lib/heyquarry/shopify_profile_sync/sync.rb', line 26

def sync_from_admin_client(client, api_key: nil, profile_url: nil)
  resolved = resolve_options(api_key: api_key, profile_url: profile_url)
  response = client.query(query: SHOP_PROFILE_QUERY)
  shop = response.body.dig("data", "shop")
  payload = ShopQuery.map_shop_to_payload(shop)
  return skipped("Shop profile missing myshopifyDomain") unless payload

  post_profile(resolved[:profile_url], resolved[:api_key], payload)
end

.sync_from_session(shop_domain:, access_token:, api_key: nil, profile_url: nil, admin_api_version: DEFAULT_ADMIN_API_VERSION) ⇒ Object



17
18
19
20
21
22
23
24
# File 'lib/heyquarry/shopify_profile_sync/sync.rb', line 17

def sync_from_session(shop_domain:, access_token:, api_key: nil, profile_url: nil, admin_api_version: DEFAULT_ADMIN_API_VERSION)
  resolved = resolve_options(api_key: api_key, profile_url: profile_url)
  shop = fetch_shop_from_session(shop_domain, access_token, admin_api_version)
  payload = ShopQuery.map_shop_to_payload(shop)
  return skipped("Shop profile missing myshopifyDomain") unless payload

  post_profile(resolved[:profile_url], resolved[:api_key], payload)
end