Etsy
Setup
Add :etsy
to your mix.exs file
def deps do
[
{:etsy, "~> 1.0"}
]
end
Configure
You can set configuration using System environment variables or using elixir config.
The :consumer_key
and :consumer_secret
are the only required configs, but you
will most likely also want to also set the :scopes
and :callback
options.
config :etsy,
consumer_key: "xatfgj4rbod2al11h1j5ws6j",
consumer_secret: "a55ibdr2ee",
scopes: ~w(profile_r email_r transactions_r feedback_r),
callback: "https://sdc-encased-backend.ngrok.io/oauth/etsy"
See the env.example on how to set these configs using System environment variables.
Usage
Initiate the Oauth v1 flow by calling
Etsy.authorization_url/0
and getting the user to visit the generated login URL. Etsy.authorization_url/0
also
returns temporary credentials that you will need to store to be used after the user authorizes your application.
When the user authorizes your application, they will be redirected to your callback URL and
the oauth_token
and oauth_verifier
will provided to you as query params.
Pass the temporary credentials from step 1 and the oauth_verifier
to the Etsy.access_token/2
.
Here is an example of calling Etsy.authorization_url/0
# Generate authorization URL and get user to visit the login URL
iex(1)> Etsy.authorization_url()
{:ok,
{%Etsy.Credentials{
secret: "2935e1fb1a",
token: "e9a33f99be6eac893e6e3771e4c429"
},
"https://www.etsy.com/oauth/signin?oauth_consumer_key=REDACTED&oauth_token=e9a33f99be6eac893e6e3771e4c429&service=v2_prod&oauth_token=e9a33f99be6eac893e6e3771e4c429&oauth_token_secret=2935e1fb1a&oauth_callback_confirmed=true&oauth_consumer_key=REDACTED&oauth_callback=https://sdc-encased-backend.ngrok.io/oauth/etsy"}}
Here is an example of a Phoenix controller doing the whole Auth flow and using an ets to store the temporary credentials.
# ...
alias Etsy.Credentials
require Logger
@ets_table :etsy
def init(conn, _) do
# in your application.ex create an ets table to store temporary auth credentials
# :ets.new(:etsy, [:set, :public, :named_table])
# Generate an authorization url
case Etsy.authorization_url() do
{:ok, {%Credentials{token: token} = credentials, url}} ->
# Store temporary credentials in the ets table using the temporary token as the key
:ets.insert(@ets_table, {token, credentials})
# Send user to authorization url
redirect(conn, external: url)
error ->
Logger.error("Error generating authorization url. error: #{inspect(error)}")
:error
end
end
def callback(conn, %{"oauth_token" => oauth_token, "oauth_verifier" => oauth_verifier}) do
# Fetch temporary credentials from ets using the token
case :ets.lookup(@ets_table, oauth_token) do
[] ->
Logger.error("No credentials found in ets. Make sure you imitated the oauth flow.")
send_resp(conn, 400, "")
[{^oauth_token, credentials}] ->
case Etsy.access_token(credentials, oauth_verifier) do
{:ok, %Credentials{token: token, secret: secret}} ->
# Here you should store the User credentials in your database
# Example using these credentials to call the Etsy api
[token: token, secret: secret]
|> Credentials.new()
|> Etsy.scopes()
|> IO.inspect()
json(conn, "ok")
_ ->
send_resp(conn, 400, "")
end
error ->
Logger.error("Error looking up credentials in ets. error: #{inspect(error)}")
send_resp(conn, 400, "")
end
end
Etsy.access_token/2
will finish the hand shake and return the user's oauth token and secret which can be used for
all subsequent api calls.
If the user has already authorized your application, and you have their oauth token and oauth token secret stored,
just manually create an Etsy.Credentials
struct and use that to make api calls.
# get oauth stored token and secret from db
[token: "66ec3b28686...", secret: "1e51..."]
|> Etsy.Credentials.new()
|> Etsy.get("/users/__SELF__")
After you create the Etsy.Credentials
you can use them to call any Etsy
functions to hit the etsy's api
Examples
creds = Etsy.Credentials.new([token: "66ec3b28686...", secret: "1e51..."])
Etsy.scopes(creds) # Get current access's token scopes
Etsy.get(creds, "/users/__SELF__") # Get user info
{:ok, results} = Etsy.get(creds, "/users/__SELF__/shops") # Get user's shops
shop_id =
results
|> Map.get("results")
|> hd()
|> Map.get("shop_id")
Etsy.get(creds, "/shops/#{shop_id}/listings/active") # Get shops' active listings
Etsy.get(creds, "/users/__SELF__/shipping/templates") # Get User's shipping templates
shipping_template_id = 103831012072
Etsy.delete(creds, "/shipping/templates/#{shipping_template_id}") # Delete shipping template
{:ok, result} = Etsy.get(creds, "/countries/iso/US") # Get Country info
country_id =
result
|> Map.get("results")
|> hd()
|> Map.get("country_id")
{:ok, result} = Etsy.post(creds, "/shipping/templates", [
{"title", "test-shipping-template"},
{"origin_country_id", country_id},
{"primary_cost", "0.53"},
{"secondary_cost", "0.0"},
])
shipping_template_id =
result
|> Map.get("results")
|> hd()
|> Map.get("shipping_template_id")
# Create listing
Etsy.post(creds, "/listings", [
{"quantity", "1"},
{"title", "test-api-listing"},
{"shipping_template_id", shipping_template_id},
{"description", "test api created listing"},
{"price", "0.50"},
{"taxonomy_id", "1633"},
{"who_made", "i_did"},
{"is_supply", "false"},
{"when_made", "made_to_order"},
])
# Update Listing
listing_id = 851388163
products = """
[{"is_deleted":0,"offerings":[{"is_deleted":0,"is_enabled":1,"price":{"amount":50,"currency_code":"USD","currency_formatted_long":"$0.60 USD","currency_formatted_raw":"0.60","currency_formatted_short":"$0.60","divisor":100},"quantity":1}],"property_values":[],"sku":""}]
"""
Etsy.put(creds, "/listings/#{listing_id}/inventory", [
{"listing_id", listing_id},
{"products", products}
])