Create Bot for Microsoft Graph with DevOps 18: DirectLine

In this article, I explain DirectLine which you can hook your service to bot via REST endpoint.


As you know already, bot connector supports multiple channels such as Skype, Facebook, Email, etc. However if you want to connect other channels like WeChat, LINE or even your own application, you can use DirectLine. Does O365Bot uses it? Yes it is in function test project.


  • Authentication against REST endpoint
  • Start and end conversation
  • Send and receive messages (activities)
  • Support HTTP POST/GET or WebSocket


You cannot receive proactive message from the bot without WebSockets. The typical workflow is:

  1. Start a conversation and send message.
  2. Bot returns completed message only when all the code are executed. Therefore you cannot get the response real-time.
  3. Request for queued activities, which includes your own activity sent to the bot.


To avoid keep receiving old activities, you can specify “watermark” like paging.

Function Test

I use DirectLine in Function Test project in DirectLineHelper.cs.

Try WebSocket

As normal POST/GET methods are used inside O365bot, let’s try WebSocket in this article.

1. Add console application to O365 solution and name it “O365Bot.StreamClient“.

2. Add DirectLIne and WebSocketSharp from NuGet. Also add System.Configuration assembly.



3. Add DirectLine and UserId to app.config file.


4. Replace the code in Program.cs

using Microsoft.Bot.Connector.DirectLine;
using Newtonsoft.Json;
using System;
using System.Configuration;
using System.Linq;
using System.Threading.Tasks;
using WebSocketSharp;

namespace O365Bot.StreamClient
    class Program
        static string userId = ConfigurationManager.AppSettings["UserId"];
        static void Main(string[] args)

        private static async Task Run()

            var client = new DirectLineClient(ConfigurationManager.AppSettings["DirectLineSecret"]);
            // Create a conversation
            var conversation = await client.Conversations.StartConversationAsync();
            using (var webSocketClient = new WebSocket(conversation.StreamUrl))
                // Callback when message is received.
                webSocketClient.OnMessage += WebSocketClient_OnMessage;

                while (true)
                    var input = Console.ReadLine();
                    if (input == ConsoleKey.Enter.ToString())

                    Activity activity = new Activity()
                        From = new ChannelAccount(userId, userId),
                        Text = input,
                        Locale = "en-US",
                        Type = ActivityTypes.Message

                    await client.Conversations.PostActivityAsync(conversation.ConversationId, activity);

        private static void WebSocketClient_OnMessage(object sender, MessageEventArgs e)
            if (string.IsNullOrWhiteSpace(e.Data))
            var activitySet = JsonConvert.DeserializeObject<ActivitySet>(e.Data);

            foreach (var activity in activitySet.Activities.Where(x => x.From.Id != userId))
                // Process message

Run the app

Just run the app by pressing F5 to see how it works. It should work similar to what you have already, but when bot returns message, it received real-time.


DirectLine is powerful endpoint which you can enable bot anywhere, everywhere. There is another sample using DirectLine which connect LINE and BotFramework here.