130 lines
5.0 KiB
TypeScript
130 lines
5.0 KiB
TypeScript
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<number> {
|
|
|
|
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
|
|
} |