fp/packages/fetchers/src/findOrCreateStream.ts
CJ_Clippy 4d65294f7d
Some checks failed
ci / build (push) Failing after 1s
move fetchers to their own package
2024-09-05 21:39:08 -08:00

85 lines
2.9 KiB
TypeScript

import { configs } from "../../../services/bot/src/config.ts"
import type { Stream, VodRecord } from "@futureporn/types"
import { sub } from 'date-fns'
import { bot } from "../../../services/bot/src/bot.ts"
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}`
bot.logger.error(msg)
throw new Error(msg)
}
const json = await res.json() as Stream[]
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}`
bot.logger.error(msg)
throw new Error(msg)
}
const json = await res.json() as Stream[]
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> {
bot.logger.info(`findOrCreateStream with vtuberId=${vtuberId}, 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
}
}