fp/packages/fetchers/src/findOrCreateStream.ts
2024-09-20 19:01:21 -08:00

84 lines
2.8 KiB
TypeScript

import { configs } from "./config.ts"
import type { StreamResponse, VodRecord } from "@futureporn/types"
import { sub } from 'date-fns'
export async function findStream(vtuberId: string, lteDate: Date, gteDate: Date): Promise<string|null> {
const fetchUrl = `${configs.postgrestUrl}/streams?select=id&vtuber=eq.${vtuberId}&date=gte.${gteDate.toISOString()}&date=lte.${lteDate.toISOString()}`
const fetchOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Prefer': 'return=representation'
}
}
const res = await fetch(fetchUrl, fetchOptions)
if (!res.ok) {
const body = await res.text()
const msg = `findStream fetch failed. status=${res.status}, statusText=${res.statusText}, body=${body}`
console.error(msg)
throw new Error(msg)
}
const json = await res.json() as StreamResponse[]
if (!json || !json[0]) return null
return json[0].id
}
export async function createStream(): Promise<string|null> {
const payload = {
}
const fetchUrl = `${configs.postgrestUrl}/streams?select=id`
const fetchOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Prefer': 'return=representation',
'Authorization': `Bearer ${configs.automationUserJwt}`,
},
body: JSON.stringify(payload)
}
const res = await fetch(fetchUrl, fetchOptions)
if (!res.ok) {
const body = await res.text()
const msg = `createStream fetch failed. status=${res.status}, statusText=${res.statusText}, body=${body}`
console.error(msg)
throw new Error(msg)
}
const json = await res.json() as StreamResponse[]
if (!json || !json[0]) return null
return json[0].id
}
/**
* Find or create a stream in the database.
*
* We use the vtuberId and the date to find a stream taking place within the last n minutes.
*
* The stream date range that we accept is inclusive between date and (date-minutes)
*
* This is useful for eliminating duplicates, since a stream can be created by more than one input.
*
* - manual
* - email
* - twitter
*
*/
export default async function findOrCreateStream({ vtuberId, date, minutes = 15 }: { vtuberId: string, date: Date, minutes?: number }): Promise<string|null> {
console.info(`findOrCreateStream with vtuberId=${vtuberId}, date=${new Date(date).toISOString()}, minutes=${minutes}`)
if (!vtuberId) throw new Error(`findOrCreateStream requires vruberId passed in the options argument.`);
if (!date) throw new Error(`findOrCreateStream requires date passed in the options argument.`);
const gteDate = sub(date, { minutes })
const lteDate = date
const foundStream = await findStream(vtuberId, lteDate, gteDate)
if (!foundStream) {
return createStream()
} else {
return foundStream
}
}