Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
b5f03cb
PR'ing achievement UI into the feature branch (#485)
kenny-io Mar 8, 2021
2853163
Clean up the logs
kenny-io Mar 8, 2021
a4133d1
feature (#472): add check reward function (#488)
bencodezen Mar 12, 2021
b5a1f15
config: update package-lock
bencodezen Mar 15, 2021
0625d9b
feature (#474): update reward status (#495)
bencodezen Mar 22, 2021
19ed5ac
feature (#457): scaffold price rule post request (#486)
bencodezen Mar 22, 2021
a49fa6a
Reward code UI update (#498)
kenny-io Apr 9, 2021
4c22095
build bump
Apr 9, 2021
da911a3
fix: make function path absolute
jlengstorf Apr 9, 2021
7c1f4e2
fix: add description variable
jlengstorf Apr 9, 2021
74f8154
chore: use esbuild
jlengstorf Apr 9, 2021
0c12908
config: add logging for errors
bencodezen Apr 15, 2021
42b6b6b
config: update package lock
bencodezen Apr 15, 2021
73f625e
fix: remove getUserAchievements on route change
bencodezen Apr 15, 2021
332013c
config: add log for payload
bencodezen Apr 15, 2021
48b06c7
config: update log for event data
bencodezen Apr 15, 2021
1c7f536
fix: use the current site’s auth function
jlengstorf Apr 15, 2021
246f7d1
chore: ignore README
jlengstorf Apr 15, 2021
c4113f3
fix: don’t fail if the achievement isn’t set
jlengstorf Apr 15, 2021
bdb4ae8
fix: use Next router
jlengstorf Apr 15, 2021
699ea2a
chore: update package.json
bencodezen Apr 15, 2021
d90f05f
config: add console log
bencodezen Apr 15, 2021
b6b1e3f
config: tag on then to inspect response
bencodezen Apr 15, 2021
3e9b36e
config: update package lock
bencodezen Apr 16, 2021
12185b1
fix: replace history
jlengstorf Apr 16, 2021
fe53123
fix: filter for valid rewards and fail gracefully if it’s invalid
jlengstorf Apr 16, 2021
ee6678c
wip: lots of logging for the Shopify webhook
jlengstorf Apr 16, 2021
a4391c6
fix: check for array length
jlengstorf Apr 16, 2021
33b37a7
fix: use the rewards array
jlengstorf Apr 16, 2021
33fd8a8
fix: compare codes correctly
jlengstorf Apr 16, 2021
46076ff
config: log discount code match
bencodezen Apr 19, 2021
844ffaf
refactor: update query names
bencodezen Apr 19, 2021
729e001
config: add log for mutation call
bencodezen Apr 19, 2021
e2b925f
fix: move return into async await
bencodezen Apr 19, 2021
332bd0f
refactor: use promise all strategy
bencodezen Apr 19, 2021
a69db83
feature: add event data to achievement
bencodezen Apr 19, 2021
b1eafb1
chore: cleanup logs
bencodezen Apr 19, 2021
335750f
chore: standardize casing on GraphQL queries
bencodezen Apr 19, 2021
9b199e2
feature: add achievement check
bencodezen Apr 19, 2021
def419d
refactor: clean up code and add some logs
bencodezen Apr 19, 2021
3165d93
wip: logging
jlengstorf Apr 21, 2021
f74acfd
fix: check the achievements array
jlengstorf Apr 21, 2021
a73f978
fix: put my thang down flip it and reverse it
jlengstorf Apr 21, 2021
8a55a29
fix: check for specific achievement type
jlengstorf Apr 21, 2021
365be4a
fix: logic is hard
jlengstorf Apr 21, 2021
8b2492d
Clean up HTML and add copy icon (#503)
kenny-io Apr 21, 2021
a3728d0
fix: prevent coupon code applying on multiple items
bencodezen Apr 22, 2021
4c32da4
fix: generate discount code with proper limitation (#505)
bencodezen Apr 27, 2021
fbff226
chore: remove console logs
jlengstorf May 5, 2021
19f6b82
fix: update mission status before checking for mission complete
jlengstorf May 5, 2021
572ce1f
fix: try to wrangle React timing
jlengstorf May 12, 2021
bd24e9d
config: add log
bencodezen May 28, 2021
47b030b
config: add more logs
bencodezen May 28, 2021
454b88c
fix: issue with reward creation because api changed
bencodezen May 28, 2021
fab2078
refactor: clean up logs
bencodezen May 28, 2021
6364c71
fix: update data format for achievement ui
bencodezen May 28, 2021
f422d9a
feature: removes link and sets target to new tab (#509)
tzmanics Jun 2, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ backend/dist/
backend/plugins/
out_functions
out_publish
README.md
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,5 @@ See our [contributing guidelines](./CONTRIBUTING.md) for more info about getting
## How to contribute mission!

Thinking about a technology or best practice that you would like to share with the community? Check out our [Content Contribution Guide](https://www.notion.so/netlify/Content-Contribution-Guide-7e8c17246a524dec85ffe9525084403c) to learn how ✲ ゚。.(✿╹◡╹)ノ ☆.。₀:_゚ ✲ ゚_:₀。


74 changes: 49 additions & 25 deletions functions/check-achievement.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,56 +77,80 @@ exports.handler = async (event) => {
const { new: newActivity } = payload.event.data;

if (newActivity.type !== 'mission-complete') {
console.log('!mission-complete');
return {
statusCode: 200,
body: 'ok',
};
}

const achievements = await postToHasura({
query: `mutation MyMutation(
const currentAchievements = await postToHasura({
query: `
query GetUserAchievements($user_id: String!) {
achievements(where: {user_id: {_eq: $user_id}}) {
id
type
}
}
`,
variables: {
user_id: newActivity.user_id,
},
});

if (
!currentAchievements.achievements.find(
(ach) => ach.type === 'mission-complete'
)
) {
const newAchievement = await postToHasura({
query: `mutation AddAchievement(
$app: String!,
$event_data: jsonb!,
$type: String!,
$user_id: String!,
$description: String!,
)
{
insert_achievements_one(object: {
app: $app,
event_data: $event_data,
type: $type,
user_id: $user_id
user_id: $user_id,
description: $description
}) {
app
event_data
timestamp
type
user_id
user_id,
description
}
}`,
variables: {
app: newActivity.app,
event_data: {},
type: 'mission-complete',
user_id: newActivity.user_id,
},
});
variables: {
app: newActivity.app,
event_data: newActivity.event_data,
type: 'mission-complete',
user_id: newActivity.user_id,
description:
'Work through every stage in a mission to earn credits in the Netlify Swag Store',
},
});

if (!achievements) {
if (!newAchievement) {
return {
statusCode: 200,
body: 'New achievement created!',
};
}
} else {
return {
statusCode: 500,
body: 'Oh no!',
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers':
'Origin, X-Requested-With, Content-Type, Accept',
},
body: 'Achievement already exists.',
};
}

return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers':
'Origin, X-Requested-With, Content-Type, Accept',
},
body: 'Totally Ok',
};
};
80 changes: 75 additions & 5 deletions functions/check-reward-status.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,82 @@
/*
/**
* This function is called by the Shopify webhook
* whenever an order is created.
*/

*/
const { postToHasura } = require('./util/postToHasura');

exports.handler = async (...args) => {
console.log(args);
exports.handler = async (event) => {
const payload = JSON.parse(event.body);
const { discount_codes: discountCodes } = payload;

const allRewards = await postToHasura({
query: `
query RewardsList {
rewards {
reward_data
id
}
}
`,
});

if (!discountCodes.length > 0) {
console.error('Failed to retrieve discount codes from Shopify');
return {
statusCode: 200,
body: 'Failed to retrieve discount codes from Shopify',
};
}

if (!allRewards.rewards.length > 0) {
console.error('Failed to retrieve rewards from Hasura');
return {
statusCode: 500,
body: 'Failed to retrieve rewards from Hasura',
};
}

const discountPromises = discountCodes.map(async (discountCode) => {
try {
const discountCodeMatch = allRewards.rewards.find(
(item) => item.reward_data.code === discountCode.code
);

if (discountCodeMatch) {
await postToHasura({
query: `
mutation UpdateRewardStatus($reward_id: Int!) {
update_rewards(
where: {id: {_eq: $reward_id}},
_set: {is_claimed: true}
) {
returning {
id
is_claimed
reward_data
}
}
}
`,
variables: {
reward_id: discountCodeMatch.id,
},
});
}
} catch (err) {
console.error('Failure to update rewards: ', err);

return {
statusCode: 500,
body: 'Reward check failed.',
};
}
});

await Promise.all(discountPromises);

return {
statusCode: 200,
body: 'ok',
body: 'Checked reward',
};
};
109 changes: 70 additions & 39 deletions functions/check-reward.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,81 @@
/*
const { postToHasura } = require('./util/postToHasura');
const {
createShopifyDiscountCode,
} = require('./util/createShopifyDiscountCode');

HOW THIS WORKS
exports.handler = async (event) => {
const payload = JSON.parse(event.body);
const { new: newAchievement } = payload.event.data;
const { discountCodeBasicCreate } = await createShopifyDiscountCode(
newAchievement.id
);
const { codeDiscountNode: shopifyDiscountCode } = discountCodeBasicCreate;

whenever a new entry in the achievement table is created, this
function will be called with a payload:

// TODO get a copy of Hasura's event payload
// this will look very similar to the check-achievement.js payload

if the achievement doesn't match Jamstack Explorers reward conditions,
return 200 OK

if it _might_ match JE reward conditions, check to see if it does,
then generate appropriate rewards:

- hit the Shopify API to generate a discount code

update the achievements table to include the reward:

{
...originalEvent,
data: {
...originalEvent.data,
rewards: [
...originalEvent.data.rewards,
{
type: 'swag_discount_code',
discount_code: <whatever Shopify generates>,
description: 'Free Sticker Pack for Completing a Mission',
// this is optional. if there's a next action for the reward, this URL takes them there
actionUrl: 'https://swag.netlify.com?code=<shopify_coupon_code>',
callToAction: 'Claim Your Sticker Pack',
}
]
/**
* Step 1: Check whether achievement meets criteria
* for generating a reward. If not, stop function
* and move on.
*/
if (newAchievement.type !== 'mission-complete') {
return {
statusCode: 200,
body: 'OK! No reward needed!',
};
}
}

OPEN QUESTION: can we extend JSONB with Hasura actions?
if (!shopifyDiscountCode) {
return {
statusCode: 500,
body: 'Unable to create Shopify reward.',
};
}

*/
/**
* Step 2: Send request to generate reward.
*/
const newReward = await postToHasura({
query: `
mutation AddReward(
$achievement_id: Int!,
$reward_type: String!,
$reward_data: jsonb!
) {
insert_rewards_one(object: {
achievement_id: $achievement_id,
reward_data: $reward_data,
type: $reward_type
}) {
achievement_id
id
reward_data
timestamp
type
}
}
`,
variables: {
achievement_id: newAchievement.id,
reward_type: 'sticker pack',
reward_data: {
...shopifyDiscountCode,
},
},
});

exports.handler = async (...args) => {
console.log(args);
if (!newReward) {
return {
statusCode: 500,
body: 'Oh no! Check reward ran into an error!',
};
}

return {
statusCode: 200,
body: 'ok',
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers':
'Origin, X-Requested-With, Content-Type, Accept',
},
body: 'Success! Reward was created successfully!',
};
};
37 changes: 37 additions & 0 deletions functions/get-user-achievement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const { postToHasura } = require('./util/postToHasura');

exports.handler = async (event) => {
const params = JSON.parse(event.body);
const achievements = await postToHasura({
query: `query GetUserAchievement($user_id: String) {
achievements(where: {user_id: {_eq: $user_id}, }) {
event_data
type
description
rewards{is_claimed id reward_data type }
}
}
`,

variables: {
user_id: `${params.user_id}`,
},
});

if (!achievements) {
return {
statusCode: 200,
body: "You don't have any achievements yet",
};
}

return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers':
'Origin, X-Requested-With, Content-Type, Accept',
},
body: JSON.stringify(achievements),
};
};
Loading