Revalidate getStaticProps after each bet
This commit is contained in:
parent
6f5d69ec9c
commit
fb27fac524
|
@ -65,5 +65,6 @@ Adapted from https://firebase.google.com/docs/functions/get-started
|
||||||
|
|
||||||
Secrets are strings that shouldn't be checked into Git (eg API keys, passwords). We store these using [Google Secret Manager](https://console.cloud.google.com/security/secret-manager), which provides them as environment variables to functions that require them. Some useful workflows:
|
Secrets are strings that shouldn't be checked into Git (eg API keys, passwords). We store these using [Google Secret Manager](https://console.cloud.google.com/security/secret-manager), which provides them as environment variables to functions that require them. Some useful workflows:
|
||||||
|
|
||||||
- Set a secret: `$ firebase functions:secrets:set stripe.test_secret="THE-API-KEY"`
|
- Set a secret: `$ firebase functions:secrets:set STRIPE_APIKEY`
|
||||||
|
- Then, enter the secret in the prompt.
|
||||||
- Read a secret: `$ firebase functions:secrets:access STRIPE_APIKEY`
|
- Read a secret: `$ firebase functions:secrets:access STRIPE_APIKEY`
|
||||||
|
|
|
@ -3,7 +3,14 @@ import * as admin from 'firebase-admin'
|
||||||
import { keyBy, uniq } from 'lodash'
|
import { keyBy, uniq } from 'lodash'
|
||||||
|
|
||||||
import { Bet, LimitBet } from '../../common/bet'
|
import { Bet, LimitBet } from '../../common/bet'
|
||||||
import { getUser, getValues, isProd, log } from './utils'
|
import {
|
||||||
|
getContractPath,
|
||||||
|
getUser,
|
||||||
|
getValues,
|
||||||
|
isProd,
|
||||||
|
log,
|
||||||
|
revalidateStaticProps,
|
||||||
|
} from './utils'
|
||||||
import {
|
import {
|
||||||
createBetFillNotification,
|
createBetFillNotification,
|
||||||
createBettingStreakBonusNotification,
|
createBettingStreakBonusNotification,
|
||||||
|
@ -72,6 +79,8 @@ export const onCreateBet = functions
|
||||||
await updateBettingStreak(bettor, bet, contract, eventId)
|
await updateBettingStreak(bettor, bet, contract, eventId)
|
||||||
|
|
||||||
await firestore.collection('users').doc(bettor.id).update({ lastBetTime })
|
await firestore.collection('users').doc(bettor.id).update({ lastBetTime })
|
||||||
|
|
||||||
|
await revalidateStaticProps(getContractPath(contract))
|
||||||
})
|
})
|
||||||
|
|
||||||
const updateBettingStreak = async (
|
const updateBettingStreak = async (
|
||||||
|
|
|
@ -17,6 +17,18 @@ export const logMemory = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const revalidateStaticProps = async (
|
||||||
|
// Path after domain: e.g. "/JamesGrugett/will-pete-buttigieg-ever-be-us-pres"
|
||||||
|
pathToRevalidate: string
|
||||||
|
) => {
|
||||||
|
if (isProd()) {
|
||||||
|
const apiSecret = process.env.API_SECRET as string
|
||||||
|
const queryStr = `?pathToRevalidate=${pathToRevalidate}&apiSecret=${apiSecret}`
|
||||||
|
await fetch('https://manifold.markets' + queryStr)
|
||||||
|
console.log('Revalidated', pathToRevalidate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type UpdateSpec = {
|
export type UpdateSpec = {
|
||||||
doc: admin.firestore.DocumentReference
|
doc: admin.firestore.DocumentReference
|
||||||
fields: { [k: string]: unknown }
|
fields: { [k: string]: unknown }
|
||||||
|
@ -153,3 +165,7 @@ export const chargeUser = (
|
||||||
|
|
||||||
return updateUserBalance(userId, -charge, isAnte)
|
return updateUserBalance(userId, -charge, isAnte)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getContractPath = (contract: Contract) => {
|
||||||
|
return `/${contract.creatorUsername}/${contract.slug}`
|
||||||
|
}
|
||||||
|
|
42
web/pages/api/v0/revalidate.ts
Normal file
42
web/pages/api/v0/revalidate.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||||
|
import { z } from 'zod'
|
||||||
|
import { ValidationError } from './_types'
|
||||||
|
import { validate } from './_validate'
|
||||||
|
|
||||||
|
const queryParams = z
|
||||||
|
.object({
|
||||||
|
// This secret is stored in both Firebase and Vercel's environment variables, as API_SECRET.
|
||||||
|
apiSecret: z.string(),
|
||||||
|
// Path after domain: e.g. "/JamesGrugett/will-pete-buttigieg-ever-be-us-pres"
|
||||||
|
pathToRevalidate: z.string(),
|
||||||
|
})
|
||||||
|
.strict()
|
||||||
|
|
||||||
|
export default async function handler(
|
||||||
|
req: NextApiRequest,
|
||||||
|
res: NextApiResponse
|
||||||
|
) {
|
||||||
|
let params: z.infer<typeof queryParams>
|
||||||
|
try {
|
||||||
|
params = validate(queryParams, req.query)
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof ValidationError) {
|
||||||
|
return res.status(400).json(e)
|
||||||
|
}
|
||||||
|
console.error(`Unknown error during validation: ${e}`)
|
||||||
|
return res.status(500).json({ error: 'Unknown error during validation' })
|
||||||
|
}
|
||||||
|
|
||||||
|
const { apiSecret, pathToRevalidate } = params
|
||||||
|
|
||||||
|
if (apiSecret !== process.env.API_SECRET) {
|
||||||
|
return res.status(401).json({ message: 'Invalid api secret' })
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await res.revalidate(pathToRevalidate)
|
||||||
|
return res.json({ revalidated: true })
|
||||||
|
} catch (err) {
|
||||||
|
return res.status(500).send('Error revalidating')
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user