Skip to content

Instantly share code, notes, and snippets.

@ericdude4
Last active May 30, 2020 21:45
Show Gist options
  • Select an option

  • Save ericdude4/d98771f56fca81f40060926bc826a295 to your computer and use it in GitHub Desktop.

Select an option

Save ericdude4/d98771f56fca81f40060926bc826a295 to your computer and use it in GitHub Desktop.
Getting started with Shopifex

Create the shop schema where the installation data will be stored:

mix phx.gen.schema Shop shops url:string access_token:string scope:string
mix ecto.migrate

Add shopifex to your list of dependencies in mix.exs:

def deps do
  [
    # the rest of your dependencies
    {:shopifex, "~> 0.1.1"}
  ]
end

Then run mix deps.get

Open up config.ex and add the following, replacing the values based on your app

config :shopifex,
  app_name: "MyApp",
  shop_schema: MyApp.Shop,
  repo: MyApp.Repo,
  redirect_uri: "https://myapp123.ngrok.io/auth/install", # This should be in your Shopify app's whitelist
  webhook_uri: "https://myapp123.ngrok.io/webhook",
  scopes: "read_inventory,write_inventory,read_products,write_products,read_orders",
  api_key: "shopifyapikey123", # Change this value to your Shopify api key from before
  secret: "shopifyapisecret456", # Change this value to your Shopify api secret from before
  webhook_topics: ["app/uninstalled"]

Update your endpoint.ex to include the custom body parser. This is necessary for HMAC validation to work.

plug Plug.Parsers,
  parsers: [:urlencoded, :multipart, :json],
  pass: ["*/*"],
  body_reader: {ShopifexWeb.CacheBodyReader, :read_body, []},
  json_decoder: Phoenix.json_library()

Update your router.ex to look like this:

defmodule MyAppWeb.Router do
  use MyAppWeb, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug Shopifex.Plug.FetchFlash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
    plug Shopifex.Plug.LoadInIframe
  end

  # Ensures that a valid store is currently loaded in the session and is accessible in your controllers/templates as `conn.private.shop`
  pipeline :shopify_session do
    plug Shopifex.Plug.ShopifySession
  end

  # Make sure the incoming requests from Shopify are valid. For example, when the app is being installed, or the initial loading of your App inside of the Shopify admin panel.
  pipeline :shopify_entrypoint do
    plug Shopifex.Plug.ShopifyEntrypoint
  end

  # Ensures that the connection has a valid Shopify webhook HMAC token
  pipeline :shopify_webhook do
    plug Shopifex.Plug.ShopifyWebhook
  end

  scope "/auth", MyAppWeb do
    pipe_through [:browser, :shopify_entrypoint]
    get "/", AuthController, :auth
    get "/install", AuthController, :install
  end

  scope "/", MyAppWeb do
    pipe_through [:browser, :shopify_session]

    get "/", PageController, :index
  end

  scope "/webhook", MyAppWeb do
    pipe_through [:shopify_webhook]

    post "/", WebhookController, :action
  end
end

Create a new controller called auth_controller.ex to handle the initial iFrame load and installation

defmodule MyAppWeb.AuthController do
  use MyAppWeb, :controller
  use ShopifexWeb.AuthController

  # Thats it! Validation, installation are now handled for you :)
end

create another controller called webhook_controller.ex to handle incoming Shopify webhooks

defmodule MyAppWeb.WebhookController do
  use MyAppWeb, :controller
  use ShopifexWeb.WebhookController

  # add as many handle_topic/3 functions here as you like! This basic one handles app uninstallation
  def handle_topic(conn, shop, "app/uninstalled") do
    Shopifex.Shops.delete_shop(shop)

    conn
    |> send_resp(200, "success")
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment