I am developing a chatbot using V4 in C#; I have implemented an authentication functionality inside a waterfall dialog using OauthCard prompt, I want this oauth card prompt
The real issue is in your comment here:
Coming to Webchat it displayed me the following: [File of type 'application/vnd.microsoft.card.oauth']
which is caused by:
<div id="webchat" role="main">
<iframe src='https://webchat.botframework.com/embed/TestBotForOauthPrompt?s=<<Given my secretkey of web chat channel>>' style='min-width: 400px; width: 100%; min-height: 500px;'></iframe>
</div>
<script>
(async function () {
// In this demo, we are using Direct Line token from MockBot.
// To talk to your bot, you should use the token exchanged using your Direct Line secret.
// You should never put the Direct Line secret in the browser or client app.
// https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication
const res = await fetch('https://testbotforoauthprompt.azurewebsites.net//directline//token', { method: 'POST' });
const { token } = await res.json();
First issue: You're using both the iframe (<iframe src='https://webchat...
) and WebChat (<script> (async function ()...
).
Fix: Remove the iframe and just use the WebChat code. This isn't really documented anywhere, but the iFrame uses botchat
, which is an older version of WebChat, which doesn't work with OAuth and is what's giving you the [File of type...
error.
Second issue: You aren't getting a valid token
const res = await fetch('https://testbotforoauthprompt.azurewebsites.net//directline//token', { method: 'POST' });
That code returns a 404 because https://testbotforoauthprompt.azurewebsites.net/directline/token
doesn't exist.
You should follow the guide linked in the code comments, which would have you make a POST request to https://directline.botframework.com/v3/directline/tokens/generate
with Authorization: Bearer <YourSecretFromAzurePortal>
in the header.
Alternatively, you can use const token = <YourSecretFromAzurePortal>
directly, instead. Note that it isn't a good idea to use your secret directly. You should really set up a token server. This should get you started (note: this is the link I intended to use in my comment above), but it's a little more complex. If you just want something simple and don't care if your app secret gets out, go with the const token = <YourSecretFromAzurePortal>
method.
I just answered a similar question, here.
Token Generator
Regarding: this answer
If you want to keep your Secret private, you need to write your own token server. The first half of the linked answer explains a basic way to do this. You can either write your own, use the sample in that linked answer, or use the code from the blog posts that are linked in that answer.
Where to put the code is dependent on how you want it to run. The sample token server is entirely separate from the bot. The blog post samples show how to integrate it into your bot (although you can also host it separately).
The WebChat client makes a request to that token server, which makes a request to https://directline.botframework.com/v3/directline/tokens/generate
and returns the response, which is a valid DirectLine token.
However, in many cases you don't need the extra security of writing your own token server. The second half of the linked answer explains that the security risks of exposing your secret are minimal for many simple bots.
I recommend, for you (since you said you're fairly new to coding), that you don't write your own token server and just leave the secret exposed in const token = <Directline secret from azure portal direct line channel>;
(Note that I removed the {}
, since your token is a string
). If you really want to use a token server, you'll need to learn how to write a server in C#.
HTML File
The code you got from examplebot.azurewebsites...
uses Angular (I think). It's old. Don't use it.
You should base your HTML code off of one of the WebChat Samples.
It looks like your last code block does. Since there's been a lot of confusion, just use this:
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Web Chat: Custom style options</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--
For demonstration purposes, we are using the development branch of Web Chat at "/master/webchat.js".
When you are using Web Chat for production, you should use the latest stable release at "/latest/webchat.js",
or lock down on a specific version with the following format: "/4.1.0/webchat.js".
-->
<script src="https://cdn.botframework.com/botframework-webchat/master/webchat.js"></script>
<style>
html, body {
height: 100%
}
body {
margin: 0
}
#webchat {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="webchat" role="main"></div>
<script>
(async function () {
// In this demo, we are using Direct Line token from MockBot.
// To talk to your bot, you should use the token exchanged using your Direct Line secret.
// You should never put the Direct Line secret in the browser or client app.
// https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication
// Token is found by going to Azure Portal > Your Web App Bot > Channels > Web Chat - Edit > Secret Keys - Show
// It looks something like this: pD*********xI.8ZbgTHof3GL_nM5***********aggt5qLOBrigZ8
const token = '<Directline secret from azure portal durect line channel>';
// You can modify the style set by providing a limited set of style options
const styleOptions = {
botAvatarImage: 'https://docs.microsoft.com/en-us/azure/bot-service/v4sdk/media/logo_bot.svg?view=azure-bot-service-4.0',
botAvatarInitials: 'BF',
userAvatarImage: 'https://avatars1.githubusercontent.com/u/45868722?s=96&v=4',
userAvatarInitials: 'WC',
bubbleBackground: 'rgba(0, 0, 255, .1)',
bubbleFromUserBackground: 'rgba(0, 255, 0, .1)'
};
// We are using a customized store to add hooks to connect event
const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
// When we receive DIRECT_LINE/CONNECT_FULFILLED action, we will send an event activity using WEB_CHAT/SEND_EVENT
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'webchat/join',
value: { language: window.navigator.language }
}
});
}
return next(action);
});
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token }),
styleOptions
}, document.getElementById('webchat'));
document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));
</script>
</body>
</html>
Answering your questions
a. Correct. POST method is not working because there wasn't a token server at the link you were using.
b. Use the code I have above
c. Yes, you can style however you want. Welcome messages should work because of the 'DIRECT_LINE/CONNECT_FULFILLED'
code. You can add additional code from the WebChat samples to accomplish other things, yes.
d. Don't use the code that passes "bot" in getElementById
. Use the code from the WebChat samples or the code I posted
e. Remove the post method unless you're using a token server.
That's mostly right. See above responses.
Yes. Remove the POST method. Your code was very close!!
Ensure the token you use comes from here: