J'utilise Direct Line, MS Speech Service et Webchat.js sur un bot fonctionnant sur Botframework V4.
Je démarre le bot à partir d'une page Web en utilisant webchat.js en passant des valeurs à l'application principale comme ça
https: // github. com / microsoft / BotFramework-WebChat / tree / master / samples / 04.api / d.post-activity-event
Code utilisé pour instancier le bot sur le canal Web:
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
var studentProfile = await _studentProfileAccessor.GetAsync(turnContext, () => new StudentProfile(), cancellationToken);
DialogContext dc = await _dialogs.CreateContextAsync(turnContext, cancellationToken);
//Bot Channel Message Exchange Collection
if (turnContext.Activity.Name == "userName")
{
studentProfile.Name = turnContext.Activity.Value.ToString();
studentName = turnContext.Activity.Value.ToString();
}
if (turnContext.Activity.Name == "userGenre")
{
studentProfile.Gender = turnContext.Activity.Value.ToString();
conversationSessionID = turnContext.Activity.From.Id;
if (conversationSessionID.ToLower() == "user")
{
var myConversationSessionID = turnContext.Activity.Id;
if (myConversationSessionID.IndexOf("|") != -1)
{
conversationSessionID = myConversationSessionID.Substring(0, myConversationSessionID.IndexOf("|"));
}
}
studentGender = turnContext.Activity.Value.ToString();
//Variables persistance on DB
SessionVariable SessionVariable = new SessionVariable();
SessionVariable.AddSessionVariable(BellaMain.GlobalVariable.SystemID, BellaMain.GlobalVariable.CustomerID, conversationSessionID, "StudentName", studentName, "StudentGender", studentGender, "", "", "", "", "", "", "", "", "", "", "", 0);
}
if (turnContext.Activity.Name == "activityName")
{
if (turnContext.Activity.Value.ToString().ToLower() =="atividade2")
{
var message = $"**Olá {studentName}, bem vindo ao Quant Bot!**";
await turnContext.SendActivityAsync(message);
await dc.BeginDialogAsync(Activity2MainDialog, "activity2MainDialog", cancellationToken);
}
else
{
var message = $"**Olá {studentName}, bem vindo ao Quant Bot!**";
await turnContext.SendActivityAsync(message);
}
}
Extrait de code du bot a envoyé la collecte de données dans mon bot:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>FTD Bit_Bot</title>
</head>
<body style="background-color: #fff; background-image: url('img/FTDBackground.jpg');">
<div id="chatbot" role="main"
data-cb-width="320px"
data-cb-height="400px"
data-cb-border="1px solid #ededed"
data-cb-border-radius="0px"
data-cb-background-color="white"
data-cb-position="fixed"
data-cb-right="40px"
data-cb-bottom="100px"
data-cb-zIndex="1"
data-cb-bubble-background="rgba(217, 217, 217, 0.15)"
data-cb-bubble-from-user-background="#e22e2c"
data-cb-bubble-from-user-text-color="white"
data-cb-bubble-max-width="600"
data-cb-bot-avatar-image="http://demo.radical-thinking.net/bella/microsoft/chat-assets/img/Chat-in-day-Workshop-Icon.png"
data-cb-hide-send-box="false"
data-cb-hide-upload-button="true"
data-cb-send-box-button-color="#e22e2c"
data-cb-send-box-button-color-on-disabled="#CCC"
data-cb-send-box-button-color-on-focus="#333"
data-cb-send-box-button-color-on-hover="#333"
data-cb-send-box-height="30"
data-cb-suggested-action-text-color="black"
data-cb-suggested-action-border="solid 2px #e22e2c"
data-cb-suggested-action-height="30">
</div>
<!-- Include ajax library for speech service token request call -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<!-- Include webchat client functionality (https://github.com/Microsoft/BotFramework-WebChat) -->
<!-- Change to the latest directory to stop the 'No renderer for this activity' error. However the avatar won't show -->
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js" charset="utf-8"></script>
<script>
var chatbot = document.getElementById('chatbot');
// Style modifications
const styleOptions = {
// Colors
bubbleBackground: chatbot.dataset.cbBubbleBackground,
bubbleFromUserBackground: chatbot.dataset.cbBubbleFromUserBackground,
bubbleFromUserTextColor: chatbot.dataset.cbBubbleFromUserTextColor,
bubbleMaxWidth: parseInt(chatbot.dataset.cbBubbleMaxWidth), // maximum width of text message
// Avatar
botAvatarImage: chatbot.dataset.cbBotAvatarImage,
userAvatarInitials: '',
// Send box
hideSendBox: JSON.parse(chatbot.dataset.cbHideSendBox),
hideUploadButton: JSON.parse(chatbot.dataset.cbHideUploadButton),
sendBoxButtonColor: chatbot.dataset.cbSendBoxButtonColor,
sendBoxButtonColorOnDisabled: chatbot.dataset.cbSendBoxButtonColorOnDisabled,
sendBoxButtonColorOnFocus: chatbot.dataset.cbSendBoxButtonColorOnFocus,
sendBoxButtonColorOnHover: chatbot.dataset.cbSendBoxButtonColorOnHover,
sendBoxHeight: parseInt(chatbot.dataset.cbSendBoxHeight),
// Suggested actions
suggestedActionTextColor: chatbot.dataset.cbSuggestedActionTextColor,
suggestedActionBorder: chatbot.dataset.cbSuggestedActionBorder,
suggestedActionHeight: parseInt(chatbot.dataset.cbSuggestedActionHeight),
}
</script>
<script>
var chatbot = document.getElementById("chatbot");
//style tag start
var script = {
id: 'chatbotStyle',
type: 'text/css',
style: document.createElement('style'),
content: '@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,600"); ::-webkit-scrollbar{width:10px}::-webkit-scrollbar-track{background:#f1f1f1}::-webkit-scrollbar-thumb{background:#888}::-webkit-scrollbar-thumb:hover{background:#555} #chatbot{ font-family: Roboto, sans-serif; font-weight: 400; position: fixed; right: 10px; bottom: 20px; text-align: center; } #chatbot img{ margin: auto; } #chatbot small{ display: block; font-size: 9px; } .initLaunchPad{ cursor: pointer; text-align: center; transition: .4s all; } .botHeader{min-height:40px;background:#ededed;border-radius:6px 6px 0 0;display:flex;justify-content:space-between;align-items:center;padding:4px} .botHeader img{float:left;width:32px;height:32px; border-radius:50%;background-color:#f9f9f9}.botHeader h5{float:left;padding:0!important;margin:4px 0 3px 6px} .botHeader h5 small{font-size: 12px;} .botHeader > div{width:40%;display:flex;align-items:center;text-align:left;height:32px} #botClose{cursor:pointer;font-size:12px;font-weight:600;padding:6px 8px;border-radius:4px;background-color:#e22e2c;color:#fff; } #botContainer{ display: none; border-radius: 8px; border:1px solid #cbcbcb; transition:.4s all; width: 310px; height: 420px; max-width:420px; max-height: 420px; margin-bottom: 4px; } #botBody{ height: 366px; } ',
append: function () {
this.style.type = this.type;
this.style.appendChild(document.createTextNode(this.content));
document.head.appendChild(this.style);
}
}; script.append();
//style tag end
//initLaunchPad started
var initLaunchPad = document.createElement('div');
initLaunchPad.classList.add('initLaunchPad');
var initBotIcon = document.createElement('img');
initBotIcon.src = "https://farm5.staticflickr.com/4876/39891228293_13c532f352_o.gif";
initBotIcon.width = 86;
initLaunchPad.appendChild(initBotIcon);
chatbot.appendChild(initLaunchPad);
$(function getSpeechAuthToken() {
var params = {
// Request parameters
};
$.ajax({
url: "https://brazilsouth.api.cognitive.microsoft.com/sts/v1.0/issuetoken" + $.param(params),
beforeSend: function (xhrObj) {
// Request headers
xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key", "XXXXXX");
},
type: "POST",
// Request body
data: "{body}",
})
.done(function (data) {
speechAuthToken = data;
})
.fail(function () {
alert("error");
});
});
initBotIcon.addEventListener('click', function (e) {
e.preventDefault();
initLaunchPad.style.display = "none";
botContainer.style.display = "block";
/*Call bot API*/
(async function () {
const searchParams = new URLSearchParams(window.location.search);
//Speech Service Token Generation
const subscriptionKey = 'XXXXXX';
const region = 'brazilsouth';
let webSpeechPonyfillFactory;
//Speech Service Setting
webSpeechPonyfillFactory = await window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
credentials: {
authorizationToken: speechAuthToken,
region: region
}
});
//Direct-Line BotToken Generation
const res = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', { method: 'POST', headers: { Authorization: 'Bearer ' + 'XXXXXX' } });
const { token } = await res.json();
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token }),
store,
userID: "User",
styleOptions,
locale: 'pt-BR',
selectVoice: (voices, activity) =>
activity.locale === 'pt-BR'
? voices.find(({ name }) => /Daniel/iu.test(name))
: voices.find(({ name }) => /Daniel/iu.test(name)) ||
voices.find(({ name }) => /Daniel/iu.test(name)),
webSpeechPonyfillFactory
}, document.getElementById('botBody'));
document.querySelector('#botBody > *').focus();
var mainTag = chatbot.getElementsByClassName('main')[0];
mainTag.style.borderTop = chatbot.dataset.cbBorder;
})().catch(err => console.error(err));
//Bot Message Exchange Setting
const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'userName',
value: Paul
}
});
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'userGenre',
value: male
}
});
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'activityName',
value: chatBotMission
}
});
}
return next(action);
});
//initLaunchPad ended
var botContainer = document.createElement('div');
botContainer.id = "botContainer";
var botHeader = document.createElement('div');
botHeader.classList.add('botHeader');
var botClose = document.createElement('a');
botClose.id = "botClose";
botClose.innerText = "X";
botClose.title = "Close";
botHeader.innerHTML = "<div><img src='" + chatbot.dataset.cbBotAvatarImage + "'/> <h5>Bit_Bot <small>FTD Educação</small> </div></h5>";
botHeader.appendChild(botClose);
botClose.addEventListener('click', function (e) {
e.preventDefault();
initLaunchPad.style.display = "";
botContainer.style.display = "none";
return false;
});
botContainer.appendChild(botHeader);
var botBody = document.createElement('div');
botBody.id = "botBody";
botContainer.appendChild(botBody);
var poweredBy = document.createElement('div');
poweredBy.innerHTML = "<small>Powered by <img src='http://ainetw.com/img/icon.png' width=12 /> AI Networks</small>";
chatbot.appendChild(botContainer);
chatbot.appendChild(poweredBy);
</script>
</body>
</html>
L'application fonctionne bien mais quand il y a plus d'un utilisateur connecté, les données échangées sont plusieurs fois incompatibles, par exemple
Le client Web 1 envoie le nom d'utilisateur: Paul et le sexe: masculin ==> l'application reçoit Paul et l'homme
Webclient 2 envoie le nom d'utilisateur: Marie et le sexe: femme ==> l'application reçoit parfois Paul et un homme!? Il devrait recevoir Marie et la femme à la place
J'ai le sentiment que les données envoyées sont mises en mémoire tampon sur Azure ou ailleurs et doivent être effacées / actualisées chaque fois qu'une nouvelle instance de bot d'application Web démarre.
Est-ce que ça fait du sens? Comment peut-il être corrigé? Thx
3 Réponses :
Dans votre exemple, vous attribuez «User» à userID , qui est une chaîne statique.
L'attribution de l'ID utilisateur en tant que valeur statique n'est pas recommandée car cela entraînera le partage de l'état par tous les utilisateurs. Veuillez consulter l'API entrée de l'ID utilisateur pour en savoir plus informations. ( source )
Supprimez la partie userID de votre extrait ou remplacez "User" par quelque chose de dynamique. Sinon, l'état sera partagé, ce qui signifie que les données utilisateur sont partagées entre tous les utilisateurs accédant au bot.
userID: "User"
Thx! Le paramètre userID a été supprimé de la page d'instanciation du bot Web, par conséquent un ID utilisateur est maintenant généré aléatoirement. Cependant, cela ne fonctionne toujours pas. Lorsqu'un nouvel utilisateur instancie le bot, il voit les données de quelqu'un d'autre. Au moment où il actualise la page, il voit ses propres données. Les pensées?
J'ai également essayé de rendre l'ID utilisateur identique au jeton de ligne directe comme userID: token mais le problème persiste. Je me demandais que la collecte de données externes dans mon code de bot ne serait peut-être pas correcte. if (turnContext.Activity.Name == "userName") {studentProfile.Name = turnContext.Activity.Value.ToString (); studentName = turnContext.Activity.Value.ToString ()}
Si vous souhaitez voir le problème en action, veuillez essayer le lien ci-dessous. Modifiez le paramètre userName comme vous le souhaitez. Cela devrait bien fonctionner la première et la deuxième fois que la conversation commence (vous devriez voir le nom fourni dans la fenêtre de discussion). Cependant, il commence à mélanger les données après cela, même lorsqu'il est accédé à partir de différents appareils. https://bellamspt.azurewebsites.net/forms/Bit_Bot/Staging/ac tivities.html? userNa me = Mick & userGenre = Ma le & activity = atividad e2 # chargé
Premièrement, au cas où vous le feriez réellement, ne transmettez pas votre autorisation de ligne directe à votre client. Il s'agit d'un problème de sécurité majeur et vous vous exposez à une violation.
En ce qui concerne votre problème, pensez à générer l'unique userID et à le transmettre dans l'appel de jeton createDirectLine () . De cette manière, l'ID utilisateur sera intégré au jeton et ne sera pas spécifiquement une fonction de la page. Comme le jeton devrait être unique pour chaque utilisateur, cela devrait aider, sinon résoudre, votre problème de croisement d'utilisateur.
Si ce n'est pas le cas, je vous recommande de supprimer l'appel d'API Direct Line Direct de votre code de chat Web. Dans mon cas, j'ai mon propre serveur de génération de jetons que j'appelle depuis Web Chat. Le serveur de jetons appelle Direct Line lorsque l'API de mon serveur est appelée par Web Chat. Je génère également l'ID utilisateur dans le serveur de jetons afin qu'il soit intégré au jeton qui est ensuite renvoyé à Web Chat pour utilisation.
Si aucune de ces options ne résout votre problème, j'examinerai de plus près votre collecte de données externes, que vous avez mentionnée ailleurs.
J'espère de l'aide!
Merci! J'ai essayé deux approches pour randomiser le UserID. 1- Supprimez le UserID` de l'appel Webchat qui génère une clé d'ID utilisateur aléatoire; 2- Générer une variable UserID aléatoire qui est passée à l'appel WebChat.createDirectLine. Les deux n'ont pas réussi à isoler les sessions utilisateur. Il semble que WebChat ne parvienne pas à faire son travail correctement étant donné que des UserID aléatoires ont été générés par défaut, comme j'ai pu le voir sur l'outil de développement du navigateur.Même quand il n'y a qu'un seul utilisateur connecté au webchat, les utilisateurs doivent appuyer sur le bouton d'actualisation 2-3 fois avoir la variable injectée dans l'application bot.
Si vous souhaitez voir le problème en action, veuillez essayer le lien ci-dessous. Modifiez le paramètre userName comme vous le souhaitez. Cela devrait bien fonctionner la première et la deuxième fois que la conversation commence (vous devriez voir le nom fourni dans la fenêtre de discussion). Cependant, il commence à mélanger les données après cela, même lorsqu'il est accédé à partir de différents appareils. bellamspt.azurewebsites.net/forms/ Bit_Bot / Staging /…
Je me demandais simplement si vous auriez un exemple d'extrait de code à partager sur la façon dont vous avez supprimé l'appel d'API Direct Line Direct de votre code de chat Web. Merci!
Merci à tous pour votre soutien à ce sujet.
Partager comment nous avons trouvé une solution à l'affaire.
Nous avons d'abord supprimé l'entrée userID: "User" .
Ainsi, chaque session de bot aura son propre ID aléatoire.
Ensuite, nous avons créé une seule variable d'échange de données «site Web à bot».
Cela garantira que toutes les données seront envoyées en un seul cycle de navigateur.
Il semble que cela soit à l'origine du problème dans notre application.
Extrait de code comme suit:
var enviromentContextData = 'studentName = &' + userName + '& studentGender = |' + userGenre + '|';
// Paramètre d'échange de messages de bot
const store = window.WebChat.createStore ({}, ({dispatch}) => suivant => action => {
if (action.type === 'DIRECT_LINE / CONNECT_FULFILLED') {
envoi({
tapez: "WEB_CHAT / SEND_EVENT",
charge utile: {
nom: 'enviromentContextDataPass',
valeur: enviromentContextData
}
});
}
retourne suivant (action);
});
Pourriez-vous s'il vous plaît partager tout votre code utilisé pour intégrer votre WebChat? Surtout pour voir si vous définissez un
userID.Merci. Je viens de mettre à jour l'énoncé du problème avec l'intégralité du code d'instanciation de bot pour le canal Web.
Accepter / voter pour une réponse sert la plus grande communauté de Stack Overflow et toute personne ayant une question similaire. Si vous pensez que ma réponse était suffisante, veuillez «accepter» et voter pour. Sinon, dites-moi comment je peux vous aider!