Shopify是一个快速发展的电子商务平台,每月增加成千上万的新商人。
Shopify平台的妙处在于Shopify公开表示他们并不关心为商家解决所有问题。 取而代之的是,他们创建了自己的API和App Store,以便独立的开发人员可以构建商户想要的功能(并为其付费)。
这意味着您有机会使用Shopify应用程序扩展和自定义Shopify,无论您有自己要改善的Shopify商店还是想要将Shopify应用程序创建为企业。
Shopify应用程序也不需要很复杂。 Shopify应用只是与Shopify的REST API集成的一部分软件。 Shopify提供了工具和软件开发工具包(SDK),以简化构建应用程序的过程,但是任何程序只要稍加集成即可成为Shopify应用程序。
在本文中,我将向您展示如何构建一个简单的Shopify应用程序,为了向您介绍API和Shopify应用程序,我将以“艰难的方式”做一些事情。 确保最后检查资源,以找到减少所需工作量的最佳方法。
私人应用程式与公共应用程式
在我们开始之前,有一个重要的Shopify概念需要学习。 您的选择将构成您所做的所有应用程序开发。
在Shopify中,有两种类型的应用程序:
- 可以在Shopify应用商店中列出可以与多个商店一起使用的公共应用 ,并且可以访问大多数API。
- 与一个商店一起使用的私人应用未在Shopify应用商店中列出,无法嵌入到Shopify管理面板中,并且对API的访问权限有限。
两者之间的最大技术差异是使用OAuth对公共应用程序进行身份验证,这需要更多设置和令人困惑的“新用户设置”。 私人应用程序使用单个商店的两个密钥进行身份验证,其作用类似于特定于应用程序的用户名和密码。
由于此商店认证是您需要做的第一件事,因此在开始时做出正确的决定很重要。
为了降低复杂性,我们将把我们的应用程序构建为私有应用程序。 这样,我们就不必担心OAuth配置及其带来的复杂性。
构建一个应用程序以标记回头客
对于我们的示例Shopify应用,我们将构建一个命令行应用,以帮助商店查找回头客是谁。 它将通过使用客户API来实现。
然后它将标记这些回头客,以便我们可以在Shopify管理面板中轻松找到他们。 这样的命令行脚本非常适合自动化和后台工作。 通常,它们会被安排为自动运行,因此没有真正的UI或用户输入。
我们还将在该应用程序中使用Ruby。 虽然您可以使用支持HTTP REST调用的任何语言,但Shopify本身使用Ruby和Ruby on Rails,并且它维护Ruby的官方库。
1.向Shopify注册新应用
构建应用程序的第一步是在Shopify中进行注册。 由于这是私有应用程序,因此我们将登录到Shopify商店,转到“ 应用程序”部分,单击“ 私有应用程序” ,然后单击“ 创建新的私有应用程序” 。
该应用程序的名称仅用于参考,而在代码中完全没有使用。
创建完成后,我们将使用一些API密钥。
- API密钥:这是应用程序的标识符,其作用类似于API的用户名。
- 应用密码:这是对我们的应用进行身份验证的秘密密码。
- 共享密钥:Shopify使用它来签署一些API。 我们不在此应用中使用它。
(您可以注册Shopify合作伙伴计划,该计划使您能够创建公共应用和免费开发商店。即使您打算仅与一个Shopify商店集成,我也强烈建议所有人使用此程序,因为这样做可以您可以在在线商店之外测试应用。)
在注册该应用程序之后,我们可以开始编写一些代码。
2.设置Ruby Gems
这是一个Ruby项目,我们首先要创建一个Gemfile
,其中列出了我们将要使用的所有RubyGems。 两个重要的参数是shopify_api
和dotenv
。
source 'https://rubygems.org'
# Script
gem 'shopify_api'
gem 'dotenv'
gem 'rake'
# Debugging
gem 'pry'
# Testing
gem 'minitest'
shopify_api
gem包含Shopify API的ActiveResource
类。 这意味着您不必担心为HTTP请求和响应编写代码。 该库将为您执行API调用,并返回与您一起使用的Ruby对象。 Shopify也提供非Ruby库。 检查本文底部的资源以了解您的语言。
dotenv
gem是一个重要的gem,因为它将使我们创建一个特殊的文件( .env
),该文件包含我们的应用程序配置,该配置在运行时会加载到应用程序中。 这样做的目的是使我们可以发布应用及其代码,而不包含敏感数据,例如我们的API密钥和密码。
这个.env
文件定义了几个变量,这些变量将作为运行时环境的一部分导出到我们的应用程序中(可在Ruby的ENV
访问)。
# Your Shopify store's myshopify.com subdomain
export SHOP=example
# Your app's identifier, used as the username in the API
export SHOPIFY_API_KEY="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
# Your app's password
export SHOPIFY_PASSWORD="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
# Secret key that is used by Shopify to sign some APIs
export SHOPIFY_SHARED_SECRET="cccccccccccccccccccccccccccccccc"
现在已经配置好gem,可以使用bundler和bundle install
来安装它们。
3.命令行界面
我们希望该应用程序运行的方式是:用户可以在命令行上运行脚本,例如bundle exec ruby tag_customers.rb
,它将自动标记Shopify中的所有回头客。
首先创建一个空脚本并加载所需的库。
#!/usr/bin/env ruby
require 'pry'
require 'shopify_api'
require 'dotenv'
Dotenv.load
注意我们如何立即调用Dotenv.load
。 这样就可以从.env
文件中导出变量,因此从那时起我们就可以使用该配置了。
我们还将创建一个简单的类来保存逻辑,然后最后使用Ruby的__FILE__ == $PROGRAM_NAME
功能调用该类以执行该逻辑。
class TagCustomers
end
# Called when the file is run on the command line, but not in a require
if __FILE__ == $PROGRAM_NAME
TagCustomers.new
end
4. Shopify API连接
现在我们已经具备了运行应用程序所需的一切,现在让我们添加到Shopify API的连接。 由于所有内容都基于商店,因此获取其数据可以很好地用作连接测试。 为此,我们需要做一些事情:
- 配置
shopify_api
以使用我们的Shopify商店和身份验证。 - 对Shopify进行API调用。
- 检查结果。
在shopify_api
使用私人应用程序时,我们可以使用HTTP Basic在基本URL中配置商店的身份验证。 基本网址的构建如下:
- https
- HTTP基本用户名,这是我们应用程序的API密钥
- HTTP基本密码,这是我们的应用程序的密码
- SHOP_NAME.myshopify.com子域,对于每个商店都是唯一的
- / admin子目录,其中包含所有API
放在一起,结果如下:
https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb@example.myshopify.com/admin
要在脚本中进行配置,我们将组装此基本URL并将其分配给ShopifyAPI::Base
类。
class TagCustomers
attr_accessor :shop_url
# Configure the Shopify connection
def initialize
@shop_url = "https://#{ENV["SHOPIFY_API_KEY"]}:#{ENV["SHOPIFY_PASSWORD"]}@#{ENV["SHOP"]}.myshopify.com/admin"
ShopifyAPI::Base.site = @shop_url
end
end
注意如何再次使用ENV
将敏感数据保留在实际代码之外。 这也使用户可以更改SHOP变量,如果您有多个要在其上运行此脚本的商店,该变量将非常有用。
最后,让我们添加一种方法来从Shopify获取商店的详细信息。
#!/usr/bin/env ruby
require 'pry'
require 'shopify_api'
require 'dotenv'
Dotenv.load
class TagCustomers
attr_accessor :shop_url
# Configure the Shopify connection
def initialize
@shop_url = "https://#{ENV["SHOPIFY_API_KEY"]}:#{ENV["SHOPIFY_PASSWORD"]}@#{ENV["SHOP"]}.myshopify.com/admin"
ShopifyAPI::Base.site = @shop_url
end
# Tests the Shopify connection with a simple GET request
def test_connection
return ShopifyAPI::Shop.current
end
end
# Called when the file is run on the command line, but not in a require
if __FILE__ == $PROGRAM_NAME
puts TagCustomers.new.test_connection.inspect # Prints the result
end
使用ShopifyAPI::Shop.current
,我们让shopify_api
:
- 在https:// 123456:abcdef@your-shop-name.myshopify.com/admin/shop.json建立针对商店数据的HTTP请求
- 得到回应
- 如果成功,则将响应JSON转换为
ShopifyAPI::Shop
对象
如果请求成功,我们的脚本会将最终结果打印到命令行。 如果出现错误,例如我们的身份验证或API中的错误,那么shopify_api
将引发异常并以错误消息结束我们的应用程序。
$ bundle exec ruby tag_customers.rb
#<ShopifyAPI::Shop:0x00000002670b40 @attributes={"id"=>8431627, "name"=>"Little Stream Software Dev", "email"=>"edavis@littlestreamsoftware.com", "domain"=>"little-stream-software-dev.myshopify.com", "created_at"=>"2015-04-23T16:54:53-04:00", "province"=>"Oregon", "country"=>"US", "address1"=>"123 Main St", "zip"=>"97007", "city"=>"Aloha", "source"=>"littlestream", "phone"=>"5555555555", "updated_at"=>"2016-03-22T13:00:00-04:00", "customer_email"=>"shopify@littlestreamsoftware.com", "latitude"=>45.000000, "longitude"=>-122.000000, "primary_location_id"=>nil, "primary_locale"=>"en", "country_code"=>"US", "country_name"=>"United States", "currency"=>"USD", "timezone"=>"(GMT-05:00) Eastern Time (US & Canada)", "iana_timezone"=>"America/New_York", "shop_owner"=>"Eric Davis", "money_format"=>"$ {{amount}}", "money_with_currency_format"=>"$ {{amount}} USD", "province_code"=>"OR", "taxes_included"=>false, "tax_shipping"=>nil, "county_taxes"=>true, "plan_display_name"=>"affiliate", "plan_name"=>"affiliate", "has_discounts"=>true, "has_gift_cards"=>false, "myshopify_domain"=>"little-stream-software-dev.myshopify.com", "google_apps_domain"=>nil, "google_apps_login_enabled"=>nil, "money_in_emails_format"=>"${{amount}}", "money_with_currency_in_emails_format"=>"${{amount}} USD", "eligible_for_payments"=>true, "requires_extra_payments_agreement"=>false, "password_enabled"=>false, "has_storefront"=>true, "eligible_for_card_reader_giveaway"=>true, "setup_required"=>false, "force_ssl"=>false}, @prefix_options={}, @persisted=true>
5.客户清单
现在,连接正常了,我们可以使用另一个API来获取商店客户列表。 再一次, shopify_api
使这个变得简单:
class TagCustomers
# ...
# Downloads the customers from Shopify
def customers
ShopifyAPI::Customer.all
end
# ...
end
在这种情况下,我们需要所有商店的客户,因此我们使用ShopifyAPI::Customer.all
,它在后台调用Shopify的Customer API并返回一系列客户对象。
6.标记回头客
由于我们只想标记下了多个订单的客户,因此我们需要添加另一种方法来标记重复客户。
如果查看Customer对象或Shopify的API文档,您将看到Shopify有一个名为orders_count
的字段,该字段已经跟踪了客户下的订单数量。 这对于我们的应用程序来说是个好消息,因为在电子商务系统中通常有成千上万的订单。 如果我们要寻找重复订单的客户,则需要下载并计算所有这些订单。 由于Shopify拥有此领域,因此我们可以完全专注于客户。
无论何时使用任何API,阅读API文档并查看从中获得的数据总是很有用的。 有时,您会找到一种更好的方法来完成您要尝试执行的操作。
让我们添加一个检查orders_count
并进行标记的方法。
# Tags repeat customers with the tag "repeat"
def tag_repeat_customers
tagged_customers = []
customers.each do |customer|
if customer.orders_count > 1
unless customer.tags.include?("repeat")
customer.tags += "repeat"
customer.save
end
tagged_customers << customer
end
end
tagged_customers
end
这是应用程序的精髓,所以让我们对其进行部分分解。
首先,我们创建一个tagged_customers
数组。 如果您跳到方法的结尾,则可以看到返回的内容。 我们希望我们的应用程序让我们知道哪些客户被标记为重复客户,以便我们可以跟踪他们并在以后发现任何潜在问题(例如,客户被跳过)。
接下来,我们从更早的时候调用我们的customers
方法,该方法使用Shopify的API来获取所有商店的客户。
我们立即开始遍历返回的每个客户记录( each
)。
由于shopify_api
将客户JSON转换为Ruby对象,因此我们可以检查customer.orders_count
并查看他们有多少订单。 我们仅关注具有多个订单的客户,因此使用if
条件可以忽略具有0或1个订单的客户。
对于回头客,我们要添加“ repeat”标签,然后在Ruby对象上调用save
方法。 该方法通过shopify_api
进行API调用以更新客户记录。
围绕该标记和save
调用是另一个条件。 在花时间和API调用以使用新标签更新客户之前,我们应该检查一下他们是否已经具有“ repeat”标签。 如果他们这样做,我们可以跳过它们,然后转到下一个客户。 将API调用限制为仅需要更新的记录将使我们的应用运行得更快,并且还可以防止其达到Shopify的API调用限制。
最后,对于回头客,我们将它们添加到我们在开始时设置的tagged_customers
数组中,以便该方法将其返回。
7.从命令行调用类
# Called when the file is run on the command line, but not in a require
if __FILE__ == $PROGRAM_NAME
tagged = TagCustomers.new.tag_repeat_customers
puts "Tagged #{tagged.length} customers with 'repeat'"
end
剩下要做的就是在执行脚本时调用新的tag_repeat_customers
。 我们甚至会在此处添加一些内容,以在命令行上打印标记了多少回头客。
$ bundle exec ruby tag_customers.rb
Tagged 1 customers with 'repeat'
最终密码
#!/usr/bin/env ruby
require 'pry'
require 'shopify_api'
require 'dotenv'
Dotenv.load
class TagCustomers
attr_accessor :shop_url
# Configure the Shopify connection
def initialize
@shop_url = "https://#{ENV["SHOPIFY_API_KEY"]}:#{ENV["SHOPIFY_PASSWORD"]}@#{ENV["SHOP"]}.myshopify.com/admin"
ShopifyAPI::Base.site = @shop_url
end
# Tests the Shopify connection with a simple GET request
def test_connection
return ShopifyAPI::Shop.current
end
# Downloads the customers from Shopify
def customers
ShopifyAPI::Customer.all
end
# Tags repeat customers with the tag "repeat"
def tag_repeat_customers
tagged_customers = []
customers.each do |customer|
if customer.orders_count > 1
unless customer.tags.include?("repeat")
customer.tags += "repeat"
customer.save
end
tagged_customers << customer
end
end
tagged_customers
end
end
# Called when the file is run on the command line, but not in a require
if __FILE__ == $PROGRAM_NAME
tagged = TagCustomers.new.tag_repeat_customers
puts "Tagged #{tagged.length} customers with 'repeat'"
end
完成Shopify应用以标记客户
在大约50行代码中,我们创建了一个Shopify私人应用程序,该应用程序查找具有多个订单的客户并将其标记为“重复”。 在计算test_connection
部分时,我们在这里使用三个单独的Shopify API:
- 取得店铺
- 获取客户
- 放客户
未来的改进
这个脚本很好,很容易解决问题,但是总有改进的余地。
一个重大的改进就是将其更改为可以在服务器上运行的Web应用程序。 该界面可以具有一个用于运行标记方法的按钮,或者可以自动运行标记。 该Web应用程序还可以记录每次添加标签的客户,我们可以浏览过去的运行并查看商店的回头客。
如果您决定沿这条路线走,请确保签出shopify_app项目 。 该项目是一个包装shopify_api
gem并将其与OAuth集成到Ruby on Rails中的库。 如果要创建基于Rails的公共Shopify应用程序,这是您要使用的基本框架。
该应用程序的另一项改进是根据客户的订单标记客户。 例如,您可能想标记购买了特定产品或花费超过特定金额的客户。
这种改进将需要获取每个客户的订单和订单项,由于数据处理量大,这使其成为一个更加复杂的应用程序。
Shopify开发库和资源
Shopify为其API维护了几个不同的库 ,并且您也可以使用几个非官方的第三方库。 这是其中的一小部分:
现在,您应该对如何构建Shopify应用程序有更好的了解。 您已经了解了如何使用shopify_api
和Private App身份验证从Ruby连接到Shopify。 您还学习了如何使用API调用测试连接以及限制API使用率的一种技术。 最后,您了解了更新Shopify对象并将这些更改推回Shopify是多么容易。
尽管应用程序在概念上很简单,但是所有这些技术都适用于更大,更复杂的应用程序。
翻译自: https://code.tutsplus.com/articles/building-a-simple-shopify-app--cms-26198