forked from anastasiak2512/basicDemo
/
app.rb
172 lines (136 loc) · 4.83 KB
/
app.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
require 'shopify_api'
require 'sinatra'
require 'httparty'
def alternating_characters?(s)
type = [/[aeiou]/, /[^aeiou]/].cycle
if s.start_with?(/[^aeiou]/)
type.next
end
s.chars.all? { |ch| ch.match?(type.next) }
end
alternating_characters?("ateciyu")
class GiftBasket < Sinatra::Base
attr_reader :tokens
API_KEY = ENV['API_KEY']
API_SECRET = ENV['API_SECRET']
APP_URL = "jamie.ngrok.io"
def initialize
@tokens = {}
super
end
get '/giftbasket/install' do
shop = request.params['shop']
scopes = "read_orders,read_products,write_products"
# construct the installation URL and redirect the merchant
install_url = "http://#{shop}/admin/oauth/authorize?client_id=#{API_KEY}"\
"&scope=#{scopes}&redirect_uri=https://#{APP_URL}/giftbasket/auth"
# redirect to the install_url
redirect install_url
end
get '/giftbasket/auth' do
# extract shop data from request parameters
shop = request.params['shop']
code = request.params['code']
hmac = request.params['hmac']
# perform hmac validation to determine if the request is coming from Shopify
validate_hmac(hmac,request)
# if no access token for this particular shop exist,
# POST the OAuth request and receive the token in the response
get_shop_access_token(shop,API_KEY,API_SECRET,code)
# create webhook for order creation if it doesn't exist
create_order_webhook
# now that the session is activated, redirect to the bulk edit page
redirect bulk_edit_url
end
post '/giftbasket/webhook/order_create' do
# inspect hmac value in header and verify webhook
hmac = request.env['HTTP_X_SHOPIFY_HMAC_SHA256']
request.body.rewind
data = request.body.read
webhook_ok = verify_webhook(hmac, data)
if webhook_ok
shop = request.env['HTTP_X_SHOPIFY_SHOP_DOMAIN']
token = @tokens[shop]
unless token.nil?
session = ShopifyAPI::Session.new(shop, token)
ShopifyAPI::Base.activate_session(session)
else
return [403, "You're not authorized to perform this action."]
end
else
return [403, "You're not authorized to perform this action."]
end
# parse the request body as JSON data
json_data = JSON.parse data
line_items = json_data['line_items']
line_items.each do |line_item|
variant_id = line_item['variant_id']
variant = ShopifyAPI::Variant.find(variant_id)
variant.metafields.each do |field|
if field.key == 'ingredients'
items = field.value.split(',')
items.each do |item|
gift_item = ShopifyAPI::Variant.find(item)
gift_item.inventory_quantity = gift_item.inventory_quantity - 1
gift_item.save
end
end
end
end
return [200, "Webhook notification received successfully."]
end
helpers do
def get_shop_access_token(shop,client_id,client_secret,code)
if @tokens[shop].nil?
url = "https://#{shop}/admin/oauth/access_token"
payload = {
client_id: client_id,
client_secret: client_secret,
code: code}
response = HTTParty.post(url, body: payload)
# if the response is successful, obtain the token and store it in a hash
if response.code == 200
@tokens[shop] = response['access_token']
else
return [500, "Something went wrong."]
end
instantiate_session(shop)
end
end
def instantiate_session(shop)
# now that the token is available, instantiate a session
session = ShopifyAPI::Session.new(shop, @tokens[shop])
ShopifyAPI::Base.activate_session(session)
end
def validate_hmac(hmac,request)
h = request.params.reject{|k,_| k == 'hmac' || k == 'signature'}
query = URI.escape(h.sort.collect{|k,v| "#{k}=#{v}"}.join('&'))
digest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), API_SECRET, query)
unless (hmac == digest)
return [403, "Authentication failed. Digest provided was: #{digest}"]
end
end
def verify_webhook(hmac, data)
digest = OpenSSL::Digest.new('sha256')
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, API_SECRET, data)).strip
hmac == calculated_hmac
end
def bulk_edit_url
bulk_edit_url = "https://www.shopify.com/admin/bulk"\
"?resource_name=ProductVariant"\
"&edit=metafields.test.ingredients:string"
return bulk_edit_url
end
def create_order_webhook
# create webhook for order creation if it doesn't exist
unless ShopifyAPI::Webhook.find(:all).any?
webhook = {
topic: 'orders/create',
address: "https://#{APP_URL}/giftbasket/webhook/order_create",
format: 'json'}
ShopifyAPI::Webhook.create(webhook)
end
end
end
end
run GiftBasket.run!