8000 readme · n00bdevel/example-ruby-app@0018a3c · GitHub
[go: up one dir, main page]

Skip to content

Commit 0018a3c

Browse files
committed
readme
1 parent ffdb058 commit 0018a3c

File tree

3 files changed

+88
-59
lines changed

3 files changed

+88
-59
lines changed

01 Getting Started/app.rb

Lines changed: 76 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
require 'httparty'
44
require 'dotenv'
55

6+
67
class GiftBasket < Sinatra::Base
8+
attr_reader :key,:secret,:tokens
79

810
def initialize
911
Dotenv.load
@@ -22,6 +24,7 @@ def initialize
2224
install_url = "http://#{shop}/admin/oauth/authorize?client_id=#{@key}"\
2325
"&scope=#{scopes}&redirect_uri=https://#{@app_url}/giftbasket/auth"
2426

27+
# redirect to the install_url
2528
redirect install_url
2629
end
2730

@@ -32,64 +35,17 @@ def initialize
3235
hmac = request.params['hmac']
3336

3437
# perform hmac validation to determine if the request is coming from Shopify
35-
h = request.params.reject{|k,_| k == 'hmac' || k == 'signature'}
36-
query = URI.escape(h.sort.collect{|k,v| "#{k}=#{v}"}.join('&'))
37-
digest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), @secret, query)
38-
39-
if not (hmac == digest)
40-
return [403, "Authentication failed. Digest provided was: #{digest}"]
41-
end
42-
43-
# if we don't have an access token for this particular shop,
44-
# we'll post the OAuth request and receive the token in the response
45-
if @tokens[shop].nil?
46-
url = "https://#{shop}/admin/oauth/access_token"
47-
48-
payload = {
49-
client_id: @key,
50-
client_secret: @secret,
51-
code: code}
52-
53-
response = HTTParty.post(url, body: payload)
54-
55-
# if the response is successful, obtain the token and store it in a hash
56-
if response.code == 200
57-
@tokens[shop] = response['access_token']
58-
else
59-
return [500, "Something went wrong."]
60-
end
61-
end
38+
validate_hmac(hmac,request)
6239

63-
# now that we have the token, we can instantiate a session
64-
session = ShopifyAPI::Session.new(shop, @tokens[shop])
65-
ShopifyAPI::Base.activate_session(session)
40+
# if no access token for this particular shop exist,
41+
# POST the OAuth request and receive the token in the response
42+
get_shop_access_token(shop,key,secret,code)
6643

67-
# create webhook for order creation if it doesn't exist
68-
if not ShopifyAPI::Webhook.find(:all).any?
69-
webhook = {
70-
topic: 'orders/create',
71-
address: "https://#{@app_url}/giftbasket/webhook/order_create",
72-
format: 'json'}
73-
74-
ShopifyAPI::Webhook.create(webhook)
75-
end
76-
77-
# redirect the merchant to the bulk editor
78-
bulk_edit_url = "https://www.shopify.com/admin/bulk"\
79-
"?resource_name=ProductVariant"\
80-
"&edit=metafields.test.ingredients:string"
44+
# subscribe to the order/create webhook
45+
create_order_webhook
8146

47+
# redirect to the bulk edit URL if there is a token and an activated session
8248
redirect bulk_edit_url
83-
84-
end
85-
86-
helpers do
87-
def verify_webhook(hmac, data)
88-
digest = OpenSSL::Digest.new('sha256')
89-
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, @secret, data)).strip
90-
91-
hmac == calculated_hmac
92-
end
9349
end
9450

9551
post '/giftbasket/webhook/order_create' do
@@ -140,6 +96,72 @@ def verify_webhook(hmac, data)
14096
return [200, "Webhook notification received successfully."]
14197
end
14298

99+
100+
helpers do
101+
def get_shop_access_token(shop,client_id,client_secret,code)
102+
if @tokens[shop].nil?
103+
url = "https://#{shop}/admin/oauth/access_token"
104+
105+
payload = {
106+
client_id: client_id,
107+
client_secret: client_secret,
108+
code: code}
109+
110+
response = HTTParty.post(url, body: payload)
111+
# if the response is successful, obtain the token and store it in a hash
112+
if response.code == 200
113+
@tokens[shop] = response['access_token']
114+
else
115+
return [500, "Something went wrong."]
116+
end
117+
118+
instantiate_session(shop)
119+
end
120+
end
121+
122+
def instantiate_session(shop)
123+
# now that the token is available, instantiate a session
124+
session = ShopifyAPI::Session.new(shop, @tokens[shop])
125+
ShopifyAPI::Base.activate_session(session)
126+
end
127+
128+
def validate_hmac(hmac,request)
129+
h = request.params.reject{|k,_| k == 'hmac' || k == 'signature'}
130+
query = URI.escape(h.sort.collect{|k,v| "#{k}=#{v}"}.join('&'))
131+
digest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), @secret, query)
132+
133+
if not (hmac == digest)
134+
return [403, "Authentication failed. Digest provided was: #{digest}"]
135+
end
136+
end
137+
138+
def verify_webhook(hmac, data)
139+
digest = OpenSSL::Digest.new('sha256')
140+
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, @secret, data)).strip
141+
142+
hmac == calculated_hmac
143+
end
144+
145+
def bulk_edit_url
146+
bulk_edit_url = "https://www.shopify.com/admin/bulk"\
147+
"?resource_name=ProductVariant"\
148+
"&edit=metafields.test.ingredients:string"
149+
return bulk_edit_url
150+
end
151+
152+
def create_order_webhook
153+
# create webhook for order creation if it doesn't exist
154+
if not ShopifyAPI::Webhook.find(:all).any?
155+
webhook = {
156+
topic: 'orders/create',
157+
address: "https://#{@app_url}/giftbasket/webhook/order_create",
158+
format: 'json'}
159+
160+
ShopifyAPI::Webhook.create(webhook)
161+
end
162+
end
163+
end
164+
143165
end
144166

145167
run GiftBasket.run!

02 Charging For Your App/app.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
require 'sinatra'
33
require 'httparty'
44
require 'dotenv'
5-
require 'pry'
65

76

87
class GiftBasket < Sinatra::Base
@@ -12,7 +11,7 @@ def initialize
1211
Dotenv.load
1312
@key = ENV['API_KEY']
1413
@secret = ENV['API_SECRET']
15-
@app_url = "jamie.ngrok.io"
14+
@app_url = "jamied.ngrok.io"
1615
@tokens = {}
1716
super
1817
end

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1-
# Example Shopify app in Ruby
1+
# Shopify App Examples
22

3-
This is an example Shopify application written in [Sinatra](https://github.com/sinatra/sinatra) solely for the purposes of introducing new developers to the Shopify API.
3+
This repository is home to the code examples highlighted in various [Shopify API tutorials](http://docs.myshopify.io/api/tutorials/). They are designed solely for the purposes of introducing new developers to the Shopify API. This apps are written in [Sinatra](https://github.com/sinatra/sinatra), but the concepts presented will also apply to developers building applications in other languages such as Python, Node.js and PHP.
4+
5+
## Tutorial index
6+
7+
#### 01 Getting Started
8+
- Building a public Shopify application ([tutorial](https://help.shopify.com/api/tutorials/building-public-app))
9+
10+
#### 02 - Charging For Your App
11+
- Billing API Tutorial ([tutorial](https://help.shopify.com/api/tutorials/adding-billing-to-your-app/))
412

513
## Credentials
614

7-
This example uses a `.env` file to store the application credentials. After cloning the repository, you'll need to create a file named `.env` in the same folder. The contents of the file should be as follows:
15+
This example uses a `.env` file to store the application credentials. After cloning the repository, you'll need to create a file named `.env` in the same folder of the tutorial. The contents of the file should be as follows:
816
```
917
API_KEY=YOUR_API_KEY
1018
API_SECRET=YOUR_SECRET_KEY

0 commit comments

Comments
 (0)
0