import { type IVtubersResponse, type IVtuberResponse, type IVtuber } from '@futureporn/types'; import { fpSlugify } from '@futureporn/utils'; import qs from 'qs'; import { getProminentColor } from '@futureporn/image'; import { getImage } from '@futureporn/scout/vtuber.js'; import { uploadFile } from '@futureporn/storage/s3.js'; /** * find or create vtuber in Strapi */ export async function upsertVtuber({ platform, userId, url, channel }: { platform: string, userId: string | null, url: string, channel: string }): Promise { let vtuberId console.log('>> # Step 1, upsertVtuber') // # Step 1. // First we find or create the vtuber // The vtuber may already be in the db, so we look for that record. All we need is the Vtuber ID. // If the vtuber is not in the db, we create the vtuber record. // GET /api/:pluralApiId?filters[field][operator]=value const findVtubersFilters = (() => { if (platform === 'chaturbate') { return { chaturbate: { $eq: url } } } else if (platform === 'fansly') { if (!userId) throw new Error('Fansly userId was undefined, but it is required.') return { fanslyId: { $eq: userId } } } })() console.log('>>>>> the following is findVtubersFilters.') console.log(findVtubersFilters) const findVtubersQueryString = qs.stringify({ filters: findVtubersFilters }, { encode: false }) console.log(`>>>>> platform=${platform}, url=${url}, userId=${userId}`) console.log('>> findVtuber') const findVtuberRes = await fetch(`${process.env.STRAPI_URL}/api/vtubers?${findVtubersQueryString}`, { method: 'GET', headers: { 'content-type': 'application/json' } }) const findVtuberJson = await findVtuberRes.json() as IVtubersResponse console.log('>> here is the vtuber json') console.log(findVtuberJson) if (findVtuberJson?.data && findVtuberJson.data.length > 0) { console.log('>> a vtuber was FOUND') if (findVtuberJson.data.length > 1) throw new Error('There were more than one vtuber matches in the response. There must only be one.'); const vtuber = findVtuberJson.data[0] if (!vtuber) throw new Error('vtuber did not have an id. vtuber must have an id.') console.log('here is the findVtuberJson (as follows)') console.log(findVtuberJson) console.log(`the matching vtuber has ID=${vtuber.id} (${vtuber.attributes.displayName})`) } if (!vtuberId) { console.log('>> vtuberId was not found so we create') /** * We are creating a vtuber record. * We need a few things. * * image URL * * themeColor * * To get an image, we have to do a few things. * * [x] download image from platform * * [x] get themeColor from image * * [x] upload image to b2 * * [x] get B2 cdn link to image * * To get themeColor, we need the image locally where we can then run */ // download image from platform // vtuber.getImage expects a vtuber object, which we don't have yet, so we create a dummy one const dummyVtuber: IVtuber = { id: 69, attributes: { slug: fpSlugify(channel), displayName: 'example', vods: [], description1: ' ', image: ' ', themeColor: ' ', fanslyId: (platform === 'fansly') ? (userId ? userId : undefined) : undefined } } const imageFile = await getImage(dummyVtuber) // get themeColor from image const themeColor = await getProminentColor(imageFile) // upload image to b2 const b2FileData = await uploadFile(imageFile) // get b2 cdn link to image const imageCdnLink = `${process.env.CDN_BUCKET_URL}/${b2FileData.Key}` console.log(`>>> createVtuberRes here we go 3-2-1, POST!`) const createVtuberRes = await fetch(`${process.env.STRAPI_URL}/api/vtubers`, { method: 'POST', headers: { 'authorization': `Bearer ${process.env.SCOUT_STRAPI_API_KEY}`, 'content-type': 'application/json' }, body: JSON.stringify({ data: { displayName: channel, fansly: (platform === 'fansly') ? url : null, fanslyId: (platform === 'fansly') ? userId : null, chaturbate: (platform === 'chaturbate') ? url : null, slug: fpSlugify(channel), description1: ' ', image: imageCdnLink, themeColor: themeColor || '#dde1ec' } }) }) const createVtuberJson = await createVtuberRes.json() as IVtuberResponse console.log('>> createVtuberJson as follows') console.log(JSON.stringify(createVtuberJson, null, 2)) if (createVtuberJson.data) { vtuberId = createVtuberJson.data.id console.log(`>>> vtuber created with id=${vtuberId}`) } } if (!vtuberId) throw new Error(`upsertVtuber failed to produce a vtuberId! This should not happen under normal circumstances.`); return vtuberId }