Skip to content

Instantly share code, notes, and snippets.

@panoply
Created August 26, 2020 22:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save panoply/ec9faea13a36f8a194012afbb145dd1b to your computer and use it in GitHub Desktop.
Save panoply/ec9faea13a36f8a194012afbb145dd1b to your computer and use it in GitHub Desktop.
Shopify Discounts API via Netlify functions
"querystring": "^0.2.0",
"shopify-api-node": "^3.4.3",
/*
Access-Control-Allow-Origin: *
const qs = require('querystring')
const Shopify = require('shopify-api-node');
const shopify = new Shopify({
shopName: 'shittify',
apiKey: '123456789abcdefghijklmnop',
password: '123456789abcdefghijklmno'
});
exports.handler = async (event, context) => {
// Only allow POST
if (event.httpMethod !== "POST") {
return { statusCode: 405, body: "Method Not Allowed" };
}
let response
try {
const { code } = event.queryStringParameters
const discount = await shopify.discountCode.lookup({ code })
response = await shopify.priceRule.get(discount.price_rule_id)
// handle response
} catch (err) {
return {
statusCode: err.statusCode || 500,
headers: {
'Access-Control-Allow-Origin': 'https://'
},
body: JSON.stringify({
error: err.message
})
}
}
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': 'https://'
},
body: JSON.stringify({
data: response
})
}
}
@keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.discount {
position: fixed;
z-index: 300;
height: 100%;
width: 100%;
top: 0;
bottom: 0;
right: 0;
left: 0;
visibility: hidden;
opacity: 0;
user-select: none;
background-color: rgba(255, 255, 255, 0.795);
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
&.discount-open {
visibility: visible;
opacity: 1;
transition: opacity 0.225s ease-in;
}
input {
border: 0;
// border-bottom: 0.01em solid $black-400;
background-color: transparent;
width: 200px;
font-size: $h1-font-size;
font-family: var(--heading-font-family);
margin-bottom: 15px;
&::placeholder {
color: $black-500;
text-transform: uppercase;
font-family: var(--heading-font-family);
}
}
.button {
color: $gray-600;
}
}
[build]
functions = "functions"
publish = "public"
[[headers]]
for = "/*"
[headers.values]
Access-Control-Allow-Origin = "*"
import { Controller } from 'stimulus'
import m from 'mithril'
/**
* Header
*
* @export
* @class Header
* @extends {Drawer}
*/
export class Discounts extends Controller {
/**
* Stimulus Targets
*
* @static
*/
static state = {}
/**
* Stimulus Targets
*
* @static
*/
static targets = [ 'toggle' ]
/**
* Stimulus Initialize
*/
initialize () {
this.overlay = document.createElement('div')
m.mount(this.overlay, this.render())
}
/**
* Stimulus Connect
*/
connect () {
document.body.appendChild(this.overlay)
// if (document.body.className !== 'template-collection') return
}
toggle (event) {
event.preventDefault()
this.overlay.firstElementChild.classList.add('discount-open')
}
async fetch (code) {
// Fetch data and remember product id
let param
try {
param = await m.request({
method: 'post',
url: 'https://......com/.netlify/functions/discounts', // netlify domain
params: { code }
})
Discounts.state = {
title: param.data.title,
value: param.data.value,
value_type: param.data.type
}
} catch (e) {
Discounts.state = {
error: 'Could not find a matching discount code!'
}
console.log(Discounts.state)
return
}
console.log(Discounts.state)
}
render () {
return {
onupdate: (vnode) => {
if (localStorage.getItem('user')) {
// vnode.dom.classList.remove('discount-open')
}
},
view: ({ state }) => m('.discount', {
onclick: (event) => event.target.remove('discount-open')
}, [
m('.d-flex.jc-center.ai-center.text-center.h-100', [
m('.col-auto', [
m('input.mb-4.d-inline[type=text]', {
placeholder: 'ENTER CODE',
oncreate: ({ dom }) => dom.focus(),
onkeyup () {
state.value = this.value
}
}),
m('button.d-block.m-auto.h5[type=button]', {
class: (Discounts?.state || state?.value?.length > 3) ? '' : 'button',
onclick: () => this.fetch(state.value)
}, 'APPLY'),
Discounts.state?.error
? m('small.text-red', Discounts.state.rules.error)
: Discounts.state?.title ? m('span', 'Success') : null
])
])
])
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment