85 lines
2.9 KiB
TypeScript
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
|
|
}
|
|
|
|
}
|
|
|