Revalidate getStaticProps after each bet

This commit is contained in:
James Grugett 2022-09-19 14:55:37 -05:00
parent 6f5d69ec9c
commit fb27fac524
4 changed files with 70 additions and 2 deletions

View File

@ -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`

View File

@ -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 (

View File

@ -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}`
}

View 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')
}
}