Shopify — это быстрорастущая платформа электронной коммерции, которая каждый месяц добавляет тысячи новых продавцов.
Самое замечательное в платформе Shopify заключается в том, что Shopify открыто заявила, что не заинтересована в решении каждой проблемы для своих продавцов. Вместо этого они создали свои API и App Store, чтобы независимые разработчики могли создавать (и оплачивать) функции, которые хотят их продавцы.
Это означает, что есть возможность расширить и настроить Shopify с помощью приложений Shopify, независимо от того, есть ли у вас собственный магазин Shopify, который вы хотите улучшить, или вы хотите создать приложение Shopify как бизнес.
Приложения Shopify также не обязательно должны быть сложными. Приложение Shopify — это просто часть программного обеспечения, которая интегрируется с REST API Shopify. Shopify делает инструменты и наборы для разработки программного обеспечения (SDK) доступными, чтобы упростить создание приложения, но любая программа может стать приложением Shopify с небольшой интеграцией.
В этой статье я собираюсь показать вам, как создать простое приложение Shopify, и я сделаю несколько сложных вещей, чтобы научить вас API и приложениям Shopify. Обязательно ознакомьтесь с ресурсами в конце, чтобы найти лучшие способы уменьшить количество необходимых усилий.
Частные приложения против публичных приложений
Прежде чем мы начнем, необходимо изучить одну важную концепцию Shopify. Ваш выбор станет основой всей разработки приложений, которую вы делаете.
В Shopify есть два типа приложений:
- Общедоступные приложения , которые работают с несколькими магазинами, могут быть перечислены в магазине приложений Shopify и иметь доступ к большинству API.
- Частные приложения , которые работают с одним магазином, не перечислены в магазине приложений Shopify, не могут быть встроены в панель управления Shopify и имеют ограниченный доступ к API.
Большое техническое различие между ними заключается в том, что общедоступные приложения проходят проверку подлинности с использованием OAuth, что требует дополнительной настройки и запутанной «настройки нового пользователя». Приватные приложения аутентифицируются с использованием двух ключей для одного магазина, которые действуют как имя пользователя и пароль для конкретного приложения.
Поскольку проверка подлинности магазина является одной из первых вещей, которые вам нужно сделать, важно принять правильное решение в начале.
Чтобы уменьшить сложность, мы собираемся создать наше приложение как частное приложение. Таким образом, нам не нужно беспокоиться о конфигурации OAuth и ее сложности.
Создание приложения для тегов повторных клиентов
Для нашего примера приложения Shopify мы собираемся создать приложение командной строки, которое поможет магазину определить, кто является его постоянным клиентом. Это будет сделано с помощью API клиента.
Затем он помечает тех постоянных клиентов, чтобы мы могли легко найти их в админ-панели Shopify. Подобные сценарии командной строки отлично подходят для автоматизации и бэк-офиса. Обычно они запускаются автоматически, поэтому нет реального пользовательского интерфейса или ввода данных пользователем.
Мы также собираемся использовать Ruby для этого приложения. Хотя вы можете использовать любой язык, который поддерживает вызовы HTTP REST, сам Shopify использует Ruby и Ruby on Rails и поддерживает официальные библиотеки для Ruby.
1. Регистрация вашего нового приложения в Shopify
Первым шагом к созданию приложения является регистрация его в Shopify. Поскольку это частное приложение, мы должны войти в наш магазин Shopify, перейти в раздел « Приложения », нажать « Частные приложения» , а затем нажать « Создать новое частное приложение» .
Название приложения используется только для справки и вообще не используется в коде.
После создания мы получим несколько ключей API для использования.
- Ключ API: это идентификатор приложения и действует как имя пользователя для API.
- Пароль приложения: это секретный пароль, который аутентифицирует наше приложение.
- Общий секрет: он используется Shopify для подписи некоторых API. Мы не используем его в этом приложении.
(Вы можете зарегистрироваться в программе Shopify Partner, которая дает вам возможность создавать публичные приложения и бесплатные магазины разработки. Я настоятельно рекомендую это всем, даже если вы планируете интегрировать только с одним магазином Shopify, потому что это позволит вы тестируете свое приложение за пределами вашего живого магазина.)
После регистрации приложения мы можем начать писать код.
2. Настройка Ruby Gems
Это проект Ruby, и мы хотим начать с создания Gemfile
котором перечислены все RubyGems, которые мы собираемся использовать. Двумя важными из них являются shopify_api
и dotenv
.
01
02
03
04
05
06
07
08
09
10
11
12
|
source ‘https://rubygems.org’
# Script
gem ‘shopify_api’
gem ‘dotenv’
gem ‘rake’
# Debugging
gem ‘pry’
# Testing
gem ‘minitest’
|
shopify_api
камень shopify_api
включает классы ActiveResource
для API Shopify. Это означает, что вам не нужно беспокоиться о написании кода для HTTP-запросов и ответов; библиотека будет выполнять вызовы API и возвращать вам объекты Ruby для работы с ними. Shopify также предоставляет не-Ruby библиотеки; проверьте ресурсы в нижней части этой статьи для вашего языка.
dotenv
камень dotenv
— важный драгоценный камень, потому что он позволит нам создать специальный файл ( .env
), который содержит конфигурацию нашего приложения, которая загружается в приложение при .env
. Цель этого состоит в том, чтобы мы могли опубликовать приложение и его код, не включая конфиденциальные данные, такие как наш ключ API и пароль.
Этот файл .env
определяет несколько переменных, которые будут экспортироваться в наше приложение как часть среды выполнения (доступной в ENV
Ruby).
1
2
3
4
5
6
7
8
|
# 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»
|
Теперь, когда гемы настроены, их можно установить, используя bundle install
.
3. Интерфейс командной строки
Мы хотели бы, чтобы это приложение работало: пользователь может запустить скрипт в командной строке, например, bundle exec ruby tag_customers.rb
, и он автоматически bundle exec ruby tag_customers.rb
всех повторных клиентов в Shopify.
Давайте начнем с создания пустого скрипта и загрузки необходимых нам библиотек.
1
2
3
4
5
|
#!/usr/bin/env ruby
require ‘pry’
require ‘shopify_api’
require ‘dotenv’
Dotenv.load
|
Обратите внимание, как мы сразу называем Dotenv.load
. Это делает экспорт переменной из нашего файла .env
так что с этого момента мы можем использовать эту конфигурацию.
Мы также собираемся создать простой класс для хранения логики, а затем вызвать его в конце, чтобы выполнить его, используя __FILE__ == $PROGRAM_NAME
Ruby __FILE__ == $PROGRAM_NAME
.
1
2
3
4
5
6
7
|
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 Connection
Теперь, когда у нас есть все необходимое для запуска нашего приложения, давайте добавим соединение с API Shopify. Поскольку все основано на магазине, захват его данных прекрасно работает как проверка соединения. Для этого нам нужно сделать несколько вещей:
- Настройте
shopify_api
для использования нашего магазина Shopify и аутентификации. - Сделайте вызов API для Shopify.
- Проверьте результаты.
При работе с частными приложениями в shopify_api
мы можем настроить аутентификацию нашего магазина в базовом URL с помощью HTTP Basic. Базовый URL построен так:
- HTTPS
- HTTP Basic username, который является ключом API нашего приложения
- Основной пароль HTTP, который является паролем нашего приложения
- Субдомен SHOP_NAME.myshopify.com, который уникален для каждого магазина
- Подкаталог / admin, где находятся все API
Собрав все это вместе, вот результат:
https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:[email protected]/admin
Чтобы настроить это в нашем скрипте, мы ShopifyAPI::Base
этот базовый URL и назначим его ShopifyAPI::Base
.
1
2
3
4
5
6
7
8
9
|
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.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#!/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
:
- создать HTTP-запрос для данных магазина по адресу https: // 123456: [email protected]/admin/shop.json
- получить ответ
- в случае успеха конвертируйте ответ JSON в объект
ShopifyAPI::Shop
Если запрос был успешным, наш скрипт выведет окончательный результат в командную строку. Если бы произошла ошибка, как в нашей аутентификации или в API, то shopify_api
вызовет исключение и завершит наше приложение с сообщением об ошибке.
1
2
|
$ bundle exec ruby tag_customers.rb
#<ShopifyAPI::Shop:0x00000002670b40 @attributes={«id»=>8431627, «name»=>»Little Stream Software Dev», «email»=>»[email protected]», «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»=>»[email protected]», «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»
|
5. Список клиентов
Теперь, когда соединение работает, мы можем использовать другой API, чтобы получить список клиентов магазина. Еще раз, shopify_api
делает это просто:
01
02
03
04
05
06
07
08
09
10
|
class TagCustomers
# …
# Downloads the customers from Shopify
def customers
ShopifyAPI::Customer.all
end
# …
end
|
В этом случае нам нужны все клиенты магазина, поэтому мы используем ShopifyAPI::Customer.all
, который за кулисами вызывает API клиента Shopify и возвращает массив объектов клиентов.
6. Пометка повторных клиентов
Поскольку мы хотим помечать только тех клиентов, которые разместили более одного заказа, нам нужно добавить еще один метод для пометки постоянных клиентов.
Если вы посмотрите на объекты Customer или в документации API Shopify, вы увидите, что в Shopify есть поле с именем orders_count
которое уже отслеживает, сколько заказов разместил клиент. Это хорошая новость для нашего приложения, потому что в системах электронной коммерции обычно есть тысячи или миллионы заказов. Если бы мы хотели искать клиентов с повторными заказами, нам нужно было бы загрузить и посчитать все эти заказы. Поскольку Shopify имеет это поле, мы можем полностью сосредоточиться на покупателях.
Всякий раз, когда вы работаете с любым API, всегда полезно прочитать документацию по API и посмотреть на данные, которые вы получаете от него. Иногда вы найдете лучший способ выполнить то, что вы пытаетесь сделать.
Давайте добавим метод, который проверяет orders_count
и делает тегирование.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
# 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
, который использует API Shopify для получения всех клиентов магазина.
Мы немедленно начинаем перебирать каждую запись о клиенте, которую мы получаем ( each
).
Поскольку shopify_api
преобразовал JSON клиента в объект Ruby, мы можем проверить customer.orders_count
и посмотреть, сколько у них заказов. Мы имеем дело только с клиентами, у которых есть более одного заказа, поэтому, используя условное условие if
мы можем игнорировать клиентов с 0 или 1 заказом.
Для постоянных клиентов мы добавляем тег «repeat», а затем вызываем метод save
для объекта Ruby. Этот метод через shopify_api
выполняет вызов API для обновления записи клиента.
Вокруг этого тегирования и save
вызова еще одно условие. Прежде чем мы потратим время и вызов API для обновления клиента новым тегом, мы должны проверить, есть ли у него тег «repeat» уже. Если они это сделают, мы можем пропустить их и перейти к следующему клиенту. Ограничение вызовов API только теми записями, которые необходимо обновить, ускорит работу нашего приложения и не позволит ему превышать ограничения вызовов API Shopify.
Наконец, для постоянных клиентов мы добавляем их в тот массив tagged_customers
мы создали в начале, чтобы метод возвращал его.
7. Вызов класса из командной строки
1
2
3
4
5
|
# 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
при выполнении нашего скрипта. Мы даже добавим туда немного содержимого, чтобы напечатать в командной строке, сколько постоянных клиентов было помечено.
1
2
|
$ bundle exec ruby tag_customers.rb
Tagged 1 customers with ‘repeat’
|
Окончательный код
01
02
03
04
05
06
07
08
09
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
|
#!/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
, мы используем три отдельных API-интерфейса Shopify:
- ПОЛУЧИТЬ магазин
- ПОЛУЧИТЬ Клиентов
- ПОСТАВИТЬ клиента
Будущие улучшения
Этот скрипт хорош и решает проблему довольно легко, но всегда есть возможности для улучшения.
Одним из существенных улучшений было бы изменить его на веб-приложение, работающее на сервере. Интерфейс может иметь кнопку для запуска методов тегирования, или тегирование может выполняться автоматически. Веб-приложение также может регистрировать, какие клиенты добавляли тег каждый раз, и мы могли просматривать прошлые запуски и видеть постоянных клиентов магазина.
Если вы решили пойти по этому пути, обязательно ознакомьтесь с проектом shopify_app . Этот проект представляет собой библиотеку, которая shopify_api
гем shopify_api
и интегрирует его в Ruby on Rails вместе с OAuth. Это основной скелет, который вы хотите использовать, если вы создаете публичное приложение Shopify на основе Rails.
Еще одним улучшением в приложении будет пометка клиентов в зависимости от их заказа. Например, вы можете пометить клиентов, которые купили определенный продукт или потратили определенную сумму.
Это улучшение потребует получения заказов и позиций для каждого клиента, что делает его более сложным приложением из-за объема обработки данных.
Shopify Разработка библиотек и ресурсов
Shopify поддерживает несколько различных библиотек для своего API, и вы можете использовать несколько неофициальных сторонних библиотек. Вот небольшая коллекция из них:
Теперь вы должны лучше понять, как вы можете создать приложение Shopify. Вы видели, как подключиться к Shopify из Ruby, используя shopify_api
и аутентификацию частного приложения. Вы также узнали, как проверить соединение с помощью вызова API, а также один метод, чтобы ограничить использование API. Наконец, вы узнали, как легко обновлять объекты Shopify и вернуть эти изменения обратно в Shopify.
Хотя приложение имеет простую концепцию, все эти методы применимы к более крупным и сложным приложениям.