借助 Business Messages 的语言区域和 Google 翻译的智能自动翻译功能,您可以与用户首选的语言聊天,以扩大代理的覆盖范围。本教程将向您介绍谷歌翻译与 Business Messages 网络钩子的概念验证集成。
所需条件
首先,您需要做好以下准备工作:
- 通过 Business Messages 完成全面批准的合作伙伴注册。请参阅注册为合作伙伴指南。
- Business Messages 代理,包括您的服务帐号密钥。如需创建代理,请参阅创建您的第一个代理指南。
- 一台安装了 Google Cloud SDK 和 Node.js(版本 10 或更高版本)的计算机。 确保您已在 Google Cloud SDK 中登录并设置您的有效项目 ID。
- 一台用于测试的 Android 或 iOS 设备。
获取代码
本教程介绍了与 Google 翻译集成的网络钩子示例。如需获取代码,请从 GitHub 克隆代码库:
git clone https://github.com/google-business-communications/bm-nodejs-translation-tutorial
导航到克隆的目录并将服务帐号密钥放入资源目录:
cp credentials.json bm-nodejs-translation-sample/resources/bm-agent-service-account-credentials.json
提示:如果您在设置或下载服务帐号密钥方面需要帮助,请参阅有关管理服务帐号的 Google Cloud 指南。
完成此操作后,即可部署代码:
gcloud app deploy
使用移动设备向代理发送一些消息。尝试使用不同语言发送消息,看看会发生什么情况。
设置 Translate API
示例代码随附了已安装 Translate API 的 Node 软件包。如果您对如何安装 Node 软件包,或如何以其他编程语言安装 Translate API 感兴趣,请参阅 Cloud Translate API 文档。
如需使用 Translate API,您需要导入该库并创建 Translate API 客户端。打开 routes/index.js
文件。相关行如下:
// Import the Translate API library.
const { Translate } = require("@google-cloud/translate").v2;
// Create a new Translate API client.
const translate = new Translate();
从现在开始,您可以在 Translate 对象上访问 Translate API 方法。
查看文件顶部附近创建的变量:
const SERVER_LANGUAGE = "en";
let currentLanguage = SERVER_LANGUAGE;
示例代码会将服务器语言存储为常量,因为它相对固定。不过,对话的当前语言可能会发生变化,因此系统会在 currentLanguage
变量中跟踪。
检测传入语言
示例代码会检测传入的语言是否发生更改,如果是,它会提示用户选择在对话中使用的语言。请在移动设备上以英语以外的语言输入给代理的消息,试试此功能。如果您不懂任何其他语言,请尝试输入“Hola”(这是西班牙语的“Hello”的西班牙语版本!)。
代理会给出提示,询问用户是否想要切换语言。提示符包含可供用户点击以切换到该语言的建议回复。
我们先来看看语言检测功能。
/**
* Detects input text language.
*
* @param {string} text The text received from the consumer.
* @param {Context} context The user message request context.
* @return A Promise with the detected language code.
*/
async function detectLanguage(text, context) {
return new Promise(function (resolve, reject) {
translate
.detect(text)
.then((result) => {
if (result && result.length > 0) {
if (result[0].confidence > CONFIDENCE_THRESHOLD) {
resolve(result[0].language);
}
resolve(bcp47.parse(context.resolvedLocale).language);
} else {
reject("No language detected");
}
})
.catch((err) => {
console.error("ERROR:", err);
reject(err);
});
});
}
此方法在翻译客户端上使用检测方法。由于 Translate API 可能会检测到多种语言,且其置信度不同(而且还支持多种输入),因此此方法会返回一组结果。该示例采用第一个结果,即置信度最高的结果。
使用已解析的语言区域
有时,翻译 API 无法非常准确地确定消息语言。例如,如果您的猫在键盘上运行并输入无意义的字符串,翻译 API 仍会尝试检测语言,但检测到的语言可能不正确。(毕竟,谷歌翻译还不支持猫咪语言!)Translate API 通过在 translate.detect
的结果中设置低置信度值来指明这一点。
在这种情况下,示例代码会回退到 Business Messages 解析的语言区域中的语言,这是 Business Messages API 根据消息上下文对该语言做出的最佳猜测。由于解析的语言区域采用 BCP-47 格式,因此您可以使用相应的 Node.js 软件包来解析语言区域的语言代码。
您可以通过向代理输入一长长的乱码字符串来测试此行为。在大多数情况下,不应看到更改语言的提示(除非解析的语言区域与当前语言不同)。代理只是说它不理解您的请求。
提示更改语言
在检测到语言已更改后,代理会返回更改语言的提示。
if (detectedLanguage != currentLanguage) {
translateText(
"Which language would you like to use?",
SERVER_LANGUAGE,
currentLanguage
).then((normalizedTranslationNotice) => {
sendResponse(
normalizedTranslationNotice,
conversationId,
[
...new Set([detectedLanguage, currentLanguage, SERVER_LANGUAGE]),
].map((x) => createSuggestedReply(x))
);
});
}
代码会创建一个提示,将其翻译成当前语言(如需了解详情,请参阅“出站邮件翻译”部分),然后发送包含建议回复的响应。用户可能会希望使用以下任意语言交谈:
- 检测到的传入语言。
- 当前的对话语言。
- 服务器的内置语言。
由于这三种语言可能存在重叠(例如,如果当前语言已经是服务器语言),服务器将使用 set 对象来移除重复项。然后,它会为每种语言创建一个建议的回复:
/**
* Create a suggested reply for a language code.
* @param {string} languageCode A ISO 6391 language code.
* @return {Suggestion} The suggestion object for switching to the language.
*/
function createSuggestedReply(languageCode) {
return {
reply: {
text: ISO6391.getNativeName(languageCode),
postbackData: SWITCH_LANGUAGE_POSTBACK + languageCode,
},
};
}
建议的回复会以用户所用语言显示该语言的名称。例如,西班牙语显示为“Español.”。如需从两位数语言代码获取语言的相关信息,您可以使用 Node.js 的 ISO-639-1 库。
请注意,当用户点击此建议时,系统会将回传数据发送到服务器。回传数据告诉服务器如何响应,并提供关于建议的上下文。
sendResponse
方法会在回复中附加这些建议对象:
let messageObject = {
…
suggestions: suggestedReplies,
};
更改对话的语言
现在,返回您的移动设备,然后根据之前的提示尝试点击新的语言选项。例如,如果您输入了“Hola”,请尝试在建议的回复中点击“Español”。
代理会用新语言响应。我们将在后续步骤中介绍如何翻译外发回复。现在,查看用于接收和处理您点击的建议回复的代码。
if (requestBody.suggestionResponse !== undefined) {
let postbackData = requestBody.suggestionResponse.postbackData;
if (postbackData.startsWith(SWITCH_LANGUAGE_POSTBACK)) {
let languageCode = postbackData.substr(SWITCH_LANGUAGE_POSTBACK.length);
currentLanguage = languageCode;
translateText(
"The language was set to " +
ISO6391.getName(languageCode) +
". Please repeat your request.",
SERVER_LANGUAGE,
languageCode
).then((translationNotice) => {
sendResponse(translationNotice, conversationId, []);
});
}
}
如果请求包含对建议的回复,服务器会使用回发数据来确定要执行的操作。在这种简单的情况下,服务器仅支持一种回传数据:SWITCH_LANGUAGE_POSTBACK,表示对话应该更改为紧跟紧跟在后面的语言代码中的语言。解析此语言代码后,服务器会发送消息,通知用户语言已更改。
入站邮件翻译
更改语言后,您可以在移动设备上以该语言向代理发送请求。尝试用新语言发送“帮助”一词。如果您将语言更改为西班牙语,请输入“ayuda”并发送消息。
服务器了解您的请求,并通过选项菜单进行回复。请尝试下列任一方法,查看硬编码的示例响应。
示例代码使用 translateText
方法翻译传入和传出的消息。立即查看:
/**
* Translates text to a given target language. No translation if source and
* target language match.
*
* @param {string} text the text to translate
* @param {string} sourceLanguage The language of the source text.
* @param {string} targetLanguage The target language.
* @return A Promise with the translated text.
*/
async function translateText(text, sourceLanguage, targetLanguage) {
if (sourceLanguage === targetLanguage) {
return new Promise(function (resolve, reject) {
resolve(text);
});
}
return new Promise(function (resolve, reject) {
translate
.translate(text, targetLanguage)
.then((result) => {
if (result && result.length > 0) {
resolve(result[0]);
} else {
reject("Could not translate message");
}
})
.catch((err) => {
console.error("ERROR:", err);
reject(err);
});
});
}
如果源语言与目标语言相同,则无需执行任何操作。否则,服务器在 Translate API 客户端上调用翻译方法。与检测方法一样,translate 方法可以接受多个输入。由于服务器仅提供一个输入,因此它会从 Translate API 获取第一个结果。
查看回调方法以当前语言响应传入消息的部分:
translateText(incomingMessage, currentLanguage, SERVER_LANGUAGE).then(
(normalizedMessage) => {
let serverResponse = chooseResponseMessage(normalizedMessage);
…
}
);
服务器使用 translateText
的输出来选择响应消息。下一部分将详细介绍选择响应消息并进行翻译的过程。
出站邮件翻译
服务器将收到的消息翻译成其原生英语后,必须选择、翻译并向用户请求发送适当的响应。示例代码使用了非常简单的架构,可以将关键字映射到响应。我们来看一下 chooseResponseMessage
方法。
/**
* Select a topically appropriate response based on the message
* content that the user sent to the agent.
*
* @param {string} incomingMessage The content of the message that the user typed in.
* @param {string} conversationId The unique id for this user and agent.
* @return {string} A response message.
*/
function chooseResponseMessage(incomingMessage) {
let responseMapping = {
balance: "Your current balance is $500.",
deposit: "Please enter your deposit amount.",
transfer:
"Please enter the account number where you wish to transfer the funds.",
withdraw: "Please enter the amount you wish to withdraw.",
help: "Please choose what you'd like to do: balance, deposit, transfer, or withdraw.",
};
for (const [key, value] of Object.entries(responseMapping)) {
if (incomingMessage.toLowerCase().includes(key)) {
return value;
}
}
return "I didn't understand your request. Please try again.";
}
此方案在服务器上仅支持英语,这意味着服务器必须翻译所有入站和出站消息。一个更复杂的系统可能支持多种语言,并以原生方式响应其他语言的请求。例如,如果您的代理支持西班牙语,则在响应映射中可能已经包含“ayuda”键。更复杂的系统可能依赖其他方法来选择合适的响应,如机器学习或评分算法。使用 Business Messages 创建更智能的响应的一种方法是与 Dialogflow 集成。
现在,查看用于将所选消息发回用户的代码。
let serverResponse = chooseResponseMessage(normalizedMessage);
translateText(
serverResponse,
SERVER_LANGUAGE,
currentLanguage
).then((normalizedResponse) => {
sendResponse(normalizedResponse, conversationId, []);
});
示例代码重复使用 translateText
方法将所选响应翻译为当前对话语言。然后,sendResponse
方法会创建新的 Message 对象并将其发送给用户。
总结
在本教程中,您学习了如何创建与 Cloud Translate API 的简单集成以及如何利用 Business Messages 语言区域功能覆盖更多用户。如果愿意,您可以将本教程中的示例代码用作自行集成的起点,也可以尝试一些新方法!以下是一些建议:
- 发送包含原始消息内容和自动翻译内容的双语消息。
- 在用户开始对话时,向用户显示受支持语言的完整菜单。
- 利用术语库等高级 Translate API 功能,可靠地翻译您的业务专用字词。
通过与 Translate API 集成,您可以利用高质量的机器翻译,以更多舒适的语言与更多用户交流。 您的客服人员可以开展更高效、更高效的对话,从而提高客户满意度和完成任务。