1

The Problem:

I am struggeling to understand how to get tokens. I know why I should use them, but I just don't understand how to get them. All the samples that uses Tokens just fetch them from "https://webchat-mockbot.azurewebsites.net/directline/token" or something similar. How do I create this path in my bot?

Describe alternatives you have considered

I was able to create something which worked with my JS-Bot:

    const server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function() {
    console.log(`\n${ server.name } listening to ${ server.url }`);
    console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator');
    console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
});

server.post('/token-generate', async (_, res) => {
  console.log('requesting token ');
  try {
    const cres = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', {
      headers: { 
        authorization: `Bearer ${ process.env.DIRECT_LINE_SECRET }`
      },
      method: 'POST'
    });

    const json = await cres.json();


    if ('error' in json) {
      res.send(500);
    } else {
      res.send(json);
    }
  } catch (err) {
    res.send(500);
  }
});

But I don't find how to do this with my C#-Bot ( I switched to C# because I understand it better than JS).

In my C#-Bot there is only this:

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Integration.AspNet.Core;

namespace ComplianceBot.Controllers
{
    // This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot
    // implementation at runtime. Multiple different IBot implementations running at different endpoints can be
    // achieved by specifying a more specific type for the bot constructor argument.
    [Route("api/messages")]
    [ApiController]
    public class BotController : ControllerBase
    {
        private readonly IBotFrameworkHttpAdapter _adapter;
        private readonly IBot _bot;

        public BotController(IBotFrameworkHttpAdapter adapter, IBot bot)
        {
            _adapter = adapter;
            _bot = bot;
        }

        [HttpGet, HttpPost]
        public async Task PostAsync()
        {
            // Delegate the processing of the HTTP POST to the adapter.
            // The adapter will invoke the bot.
            await _adapter.ProcessAsync(Request, Response, _bot);
        }
    }
}

Can I add a new Route here? like [Route("directline/token")] ?

I know I could do this with an extra "token-server" (I don't know how to realise it, but I know that would work), but if possible I'd like to do this with my already existing c#-bot as I did it with my JS-Bot.

BeschtPlaier
  • 133
  • 13

1 Answers1

2

I have posted an answer which includes how to implement an API to get a direct line access token in C# bot and how to get this token, just refer to here. If you have any further questions, pls feel free to let me know .

Update :

My code is based on this demo . If you are using .net core, pls create a TokenController.cs under /Controllers folder:

enter image description here

Code of TokenController.cs :

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace Microsoft.BotBuilderSamples.Controllers
{

    [Route("api/token")]
    [ApiController]
    public class TokenController : ControllerBase
    {


        [HttpGet]
        public async Task<ObjectResult> getToken()
        {
            var secret = "<direct line secret here>";

            HttpClient client = new HttpClient();

            HttpRequestMessage request = new HttpRequestMessage(
                HttpMethod.Post,
                $"https://directline.botframework.com/v3/directline/tokens/generate");

            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", secret);

            var userId = $"dl_{Guid.NewGuid()}";

            request.Content = new StringContent(
                Newtonsoft.Json.JsonConvert.SerializeObject(
                    new { User = new { Id = userId } }),
                    Encoding.UTF8,
                    "application/json");

            var response = await client.SendAsync(request);
            string token = String.Empty;

            if (response.IsSuccessStatusCode)
            {
                var body = await response.Content.ReadAsStringAsync();
                token = JsonConvert.DeserializeObject<DirectLineToken>(body).token;
            }

            var config = new ChatConfig()
            {
                token = token,
                userId = userId
            };

            return Ok(config);
        }
    }
    public class DirectLineToken
    {
        public string conversationId { get; set; }
        public string token { get; set; }
        public int expires_in { get; set; }
    }
    public class ChatConfig
    {
        public string token { get; set; }
        public string userId { get; set; }
    }
}

Run the project after you replace secret with your own direct line secret. You will be able to get token by url: http://localhost:3978/api/token on local :

enter image description here

Stanley Gong
  • 11,522
  • 1
  • 8
  • 16
  • exactly what I was searching for. Didn't find it because the original question is different. Thanks a lot! – BeschtPlaier Jan 17 '20 at 10:45
  • it seems like this code isn't working anymore. I get some Errors: VS Code doesn't understand "ApiController" and "IHttpActionResult", but i just copy pasted your code – BeschtPlaier Jan 17 '20 at 11:00
  • Hi @BeschtPlaier I am using VS to code. Seems you are using .net core. but this demo is coded by .net fremework. Are you still facing this issue? If you are still working on it pls let me know and I'll work a demo by .net core for you. – Stanley Gong Jan 20 '20 at 01:20
  • yea I am still working on it. That would be really great! I really need this to work and I am just not able to figure it out by myself as I am an c# beginner :( – BeschtPlaier Jan 20 '20 at 06:13
  • 2
    Hi @BeschtPlaier , I have updated my answer , pls have a try – Stanley Gong Jan 20 '20 at 07:07