Files
cloudflare-workers/tts/tts-bot.ts
T
2023-03-17 11:44:05 +11:00

128 lines
3.6 KiB
TypeScript

import { Router } from 'itty-router'
const router = Router()
const botToken = BOT_TOKEN;
const chatId = CHAT_ID;
const ttsKey = TTS_KEY
const format = "audio-16khz-128kbitrate-mono-mp3";
// const defaultVoice = 'zh-CN-XiaoxiaoNeural'; //female
const defaultVoice = 'zh-CN-YunfengNeural'
// male
// zh-CN-YunfengNeural
async function sendToAzure(text: string, voice: string, format: string) {
const endpoint = `https://australiaeast.tts.speech.microsoft.com/cognitiveservices/v1`
const body = `<speak version="1.0" xml:lang="${voice}"><voice xml:lang="${voice}" xml:gender="Female" name="${voice}">${text}</voice></speak>`
const response = await fetch(`${endpoint}`, {
method: 'POST',
headers: {
'Ocp-Apim-Subscription-Key': ttsKey,
'Content-Type': 'application/ssml+xml',
'X-Microsoft-OutputFormat': format,
'User-Agent': 'curl'
},
body,
})
if (!response.ok) {
throw new Error(`Failed to generate speech: ${response.statusText}`)
}
return response.arrayBuffer()
}
async function sendVoice(chatId: number | string, voice: ArrayBuffer, caption?: string): Promise<boolean> {
const apiUrl = `https://api.telegram.org/bot${botToken}/sendVoice`;
const formData = new FormData();
formData.append('chat_id', chatId.toString());
formData.append('voice', new Blob([voice], { type: 'audio/mpeg' }), 'voice.mp3');
if (caption) {
formData.append('caption', caption);
}
const response = await fetch(apiUrl, {
method: 'POST',
body: formData,
});
const responseBody = await response.json();
if (responseBody.ok) {
return true;
} else {
console.error(`Telegram API returned error ${responseBody.error_code}: ${responseBody.description}`);
return false;
}
}
// Define the request handler
async function handleBotRequest(request) {
// Parse the request body as JSON
const requestBody = await request.json();
if (!requestBody.message) {
return new Response('Error: No valid message founded', { status: 400 });
}
const text = requestBody.message.text;
var audioData;
try {
// Generate the audio file from the input text
audioData = await sendToAzure(text, defaultVoice, format);
} catch (err) {
await new Response('Error: something went wrong', { status: 500 });
}
if (await sendVoice(chatId, audioData)) {
return new Response(audioData, {
headers: {
'Content-Type': 'audio/mpeg',
'Content-Disposition': 'attachment; filename="audio.mp3"',
},
});
}
return new Response('Error: something went wrong', { status: 500 });
}
async function handleRequest(request: Request): Promise<Response> {
try {
const params = request.query;
if (!params) {
return new Response('Error: No valid params provided', { status: 400 });
}
var voice = params.voice
const haha = params.haha
const text = params.text
if (haha != "hahaJunv") {
return new Response('Error: something went wrong, haha', { status: 500 });
}
if (voice == null) {
voice = defaultVoice
}
const audioData = await sendToAzure(text, voice, format)
return new Response(audioData, {
headers: {
'Content-Type': 'audio/mpeg',
},
})
} catch (error) {
console.log(error)
return new Response(error.message || 'Internal Server Error', {
status: 500,
})
}
}
// Define the Cloudflare Worker entry point
// addEventListener('fetch', event => {
// event.respondWith(handleRequest(event.request));
// });
router.post('/bot', handleBotRequest)
router.get('/tts', handleRequest)
addEventListener('fetch', event => {
event.respondWith(router.handle(event.request))
})