feat(wechat): add WeChat voice reco API fallback for service account
Memind CI / Test, build, and release guards (push) Successful in 3m27s
Memind CI / Test, build, and release guards (push) Successful in 3m27s
When passive Recognition is empty, convert AMR to mp3 and call WeChat addvoicetorecofortext before the existing asr.tkmind.cn fallback. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+31
-2
@@ -12,6 +12,10 @@ import {
|
||||
persistWechatImage,
|
||||
uploadWechatGeneratedImage,
|
||||
} from './wechat-media.mjs';
|
||||
import {
|
||||
buildWechatVoiceRecoVoiceId,
|
||||
transcribeWechatVoiceViaRecoApi,
|
||||
} from './wechat-voice-reco.mjs';
|
||||
import { normalizeWechatName, resolveWechatAddressName } from './wechat/user/display-name.mjs';
|
||||
import { buildAckText } from './wechat/ack/ack-provider.mjs';
|
||||
import {
|
||||
@@ -1624,6 +1628,9 @@ export function createWechatMpService({
|
||||
requireFreshPageThumbnail,
|
||||
repairFreshPageThumbnail,
|
||||
asrTarget: config.asrTarget || DEFAULT_ASR_TARGET,
|
||||
wechatVoiceRecoApiEnabled: config.wechatVoiceRecoApiEnabled !== false,
|
||||
wechatVoiceRecoLang: config.wechatVoiceRecoLang || 'zh_CN',
|
||||
wechatVoiceRecoApiBase: config.wechatVoiceRecoApiBase || 'https://api.weixin.qq.com',
|
||||
};
|
||||
const deferredStore = createWechatCustomerServiceDeferredStore({ mysqlPool, logger });
|
||||
|
||||
@@ -2091,12 +2098,30 @@ export function createWechatMpService({
|
||||
}
|
||||
};
|
||||
|
||||
const transcribeWechatVoiceMedia = async (mediaId, format) => {
|
||||
const transcribeWechatVoiceMedia = async (mediaId, format, { msgId } = {}) => {
|
||||
if (!mediaId) return '';
|
||||
const accessToken = await getStableAccessToken();
|
||||
const downloaded = await downloadTemporaryMedia(accessToken, mediaId, { wechatFetch });
|
||||
if (!downloaded.buffer?.length) return '';
|
||||
|
||||
if (config.wechatVoiceRecoApiEnabled) {
|
||||
try {
|
||||
const recoText = await transcribeWechatVoiceViaRecoApi({
|
||||
accessToken,
|
||||
voiceBuffer: downloaded.buffer,
|
||||
format,
|
||||
voiceId: buildWechatVoiceRecoVoiceId({ msgId, mediaId }),
|
||||
lang: config.wechatVoiceRecoLang,
|
||||
apiBase: config.wechatVoiceRecoApiBase,
|
||||
wechatFetch,
|
||||
convertToMp3: config.wechatVoiceRecoConvertToMp3,
|
||||
});
|
||||
if (recoText) return recoText;
|
||||
} catch (err) {
|
||||
logger.warn?.('WeChat MP voice reco API failed:', err);
|
||||
}
|
||||
}
|
||||
|
||||
const extension = String(format ?? '').trim().toLowerCase() || 'amr';
|
||||
const form = new FormData();
|
||||
form.append(
|
||||
@@ -3577,7 +3602,11 @@ export function createWechatMpService({
|
||||
|
||||
if (intent.msgType === 'voice' && !intent.agentText.trim() && intent.media?.mediaId) {
|
||||
try {
|
||||
const fallbackText = await transcribeWechatVoiceMedia(intent.media.mediaId, intent.media.format);
|
||||
const fallbackText = await transcribeWechatVoiceMedia(
|
||||
intent.media.mediaId,
|
||||
intent.media.format,
|
||||
{ msgId: intent.msgId },
|
||||
);
|
||||
if (fallbackText) {
|
||||
intent.agentText = fallbackText;
|
||||
intent.displayText = `语音:${fallbackText}`;
|
||||
|
||||
Reference in New Issue
Block a user