Call backend api to update speech in db

This commit is contained in:
Hongbo Wu 2022-08-26 15:41:06 +08:00
parent a8617f2605
commit 5a1dbb594e
3 changed files with 53 additions and 57 deletions

View file

@ -9,11 +9,7 @@ import { getPageById } from '../../elastic/pages'
import { Speech, SpeechState } from '../../entity/speech'
import { buildLogger } from '../../utils/logger'
import { getClaimsByToken } from '../../utils/auth'
import {
setSpeechFailure,
shouldSynthesize,
synthesize,
} from '../../services/speech'
import { shouldSynthesize, synthesize } from '../../services/speech'
import { readPushSubscription } from '../../datalayer/pubsub'
const logger = buildLogger('app.dispatch')
@ -79,58 +75,41 @@ export function speechServiceRouter() {
router.options('/', cors<express.Request>({ ...corsConfig, maxAge: 600 }))
// eslint-disable-next-line @typescript-eslint/no-misused-promises
router.post('/', async (req, res) => {
logger.info('Synthesize svc request', {
logger.info('Updating speech', {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
body: req.body,
})
let userId: string
const token = req.query.token as string
try {
if (!(await getClaimsByToken(token))) {
const claims = await getClaimsByToken(token)
if (!claims) {
logger.info('Unauthorized request', { token })
return res.status(200).send('UNAUTHORIZED')
return res.status(401).send('UNAUTHORIZED')
}
userId = claims.uid
} catch (error) {
logger.error('Unauthorized request', { token, error })
return res.status(200).send('UNAUTHORIZED')
return res.status(401).send('UNAUTHORIZED')
}
const { userId, speechId } = req.body as {
userId: string
const { speechId, audioFileName, speechMarksFileName } = req.body as {
speechId: string
audioFileName: string
speechMarksFileName: string
}
if (!userId || !speechId) {
return res.status(200).send('Invalid data')
if (!speechId || !audioFileName || !speechMarksFileName) {
return res.status(400).send('Invalid data')
}
logger.info(`Create article speech`, {
body: {
userId,
speechId,
},
labels: {
source: 'CreateArticleSpeech',
},
// set state to completed
await getRepository(Speech).update(speechId, {
audioFileName: audioFileName,
speechMarksFileName: speechMarksFileName,
state: SpeechState.COMPLETED,
})
const speech = await getRepository(Speech).findOneBy({
id: speechId,
user: { id: userId },
})
if (!speech) {
return res.status(200).send('Speech not found')
}
const page = await getPageById(speech.elasticPageId)
if (!page) {
await setSpeechFailure(speech.id)
return res.status(200).send('Page not found')
}
try {
await synthesize(page, speech)
} catch (error) {
logger.error(`Error synthesizing article`, { error })
res.status(500).send('Error synthesizing article')
}
res.send('OK')
})
return router

View file

@ -25,7 +25,6 @@
},
"dependencies": {
"@google-cloud/functions-framework": "3.1.2",
"@google-cloud/pubsub": "^2.18.4",
"@google-cloud/storage": "^6.4.1",
"@sentry/serverless": "^6.16.1",
"axios": "^0.27.2",

View file

@ -15,7 +15,8 @@ import {
SpeechSynthesisResult,
SpeechSynthesizer,
} from 'microsoft-cognitiveservices-speech-sdk'
import { PubSub } from '@google-cloud/pubsub'
import axios from 'axios'
import * as jwt from 'jsonwebtoken'
interface TextToSpeechInput {
id: string
@ -43,8 +44,6 @@ interface SpeechMark {
}
const storage = new Storage()
const pubsub = new PubSub()
const SPEECH_UPDATE_TOPIC = 'speech-update'
const uploadToBucket = async (
filePath: string,
@ -59,18 +58,25 @@ const createGCSFile = (bucket: string, filename: string): File => {
return storage.bucket(bucket).file(filename)
}
const updateSpeech = (
const updateSpeech = async (
speechId: string,
audioFileName: string,
speechMarksFileName: string
): Promise<string | undefined> => {
return pubsub
.topic(SPEECH_UPDATE_TOPIC)
.publishMessage({ json: { speechId, audioFileName, speechMarksFileName } })
.catch((err) => {
console.error('error publishing speech update:', err)
return undefined
})
speechMarksFileName: string,
token: string
): Promise<boolean> => {
if (!process.env.REST_BACKEND_ENDPOINT) {
throw new Error('backend rest api endpoint not exists')
}
const response = await axios.post(
`${process.env.REST_BACKEND_ENDPOINT}/svc/text-to-speech?token=${token}`,
{
speechId,
audioFileName,
speechMarksFileName,
}
)
return response.status === 200
}
const synthesizeTextToSpeech = async (
@ -375,17 +381,29 @@ const htmlElementToSsml = ({
export const textToSpeechHandler = Sentry.GCPFunction.wrapHttpFunction(
async (req, res) => {
console.debug('New text to speech request', req)
const token = req.query.token as string
if (!process.env.JWT_SECRET) {
console.error('JWT_SECRET not exists')
return res.status(500).send('JWT_SECRET not exists')
}
try {
jwt.verify(token, process.env.JWT_SECRET)
} catch (e) {
console.error(e)
return res.status(200).send('UNAUTHENTICATED')
}
const input = req.body as TextToSpeechInput
const { audioFileName, speechMarksFileName } = await synthesizeTextToSpeech(
input
)
const result = await updateSpeech(
const updated = await updateSpeech(
input.id,
audioFileName,
speechMarksFileName
speechMarksFileName,
token
)
if (!result) {
if (!updated) {
return res.status(500).send('Failed to update speech')
}
res.send('OK')