Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions libraries/Microsoft.Bot.Builder/EventFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Bot.Schema;

namespace Microsoft.Bot.Builder
{
/// <summary>
/// Contains utility methods for creating various event types.
/// </summary>
public static class EventFactory
{
/// <summary>
/// Create handoff initiation event.
/// </summary>
/// <param name="turnContext">turn context.</param>
/// <param name="handoffContext">agent hub-specific context.</param>
/// <param name="transcript">transcript of the conversation.</param>
/// <returns>handoff event.</returns>
public static IEventActivity CreateHandoffInitiation(ITurnContext turnContext, object handoffContext, Transcript transcript = null)
{
if (turnContext == null)
{
throw new ArgumentNullException(nameof(turnContext));
}

var handoffEvent = CreateHandoffEvent(HandoffEventNames.InitiateHandoff, handoffContext, turnContext.Activity.Conversation);

handoffEvent.From = turnContext.Activity.From;
handoffEvent.RelatesTo = turnContext.Activity.GetConversationReference();
handoffEvent.ReplyToId = turnContext.Activity.Id;
handoffEvent.ServiceUrl = turnContext.Activity.ServiceUrl;
handoffEvent.ChannelId = turnContext.Activity.ChannelId;

if (transcript != null)
{
var attchment = new Attachment
{
Content = transcript,
ContentType = "application/json",
Name = "Transcript",
};
handoffEvent.Attachments.Add(attchment);
}

return handoffEvent;
}

/// <summary>
/// Create handoff status event.
/// </summary>
/// <param name="conversation">Conversation being handed over.</param>
/// <param name="state">State, possible values are: "accepted", "failed", "completed".</param>
/// <param name="message">Additional message for failed handoff.</param>
/// <returns>handoff event.</returns>
public static IEventActivity CreateHandoffStatus(ConversationAccount conversation, string state, string message = null)
{
if (conversation == null)
{
throw new ArgumentNullException(nameof(conversation));
}

if (state == null)
{
throw new ArgumentNullException(nameof(state));
}

object value;

if (string.IsNullOrEmpty(message))
{
value = new { state };
}
else
{
value = new { state, message };
}

var handoffEvent = CreateHandoffEvent(HandoffEventNames.HandoffStatus, value, conversation);
return handoffEvent;
}

private static Activity CreateHandoffEvent(string name, object value, ConversationAccount conversation)
{
var handoffEvent = Activity.CreateEventActivity() as Activity;

handoffEvent.Name = name;
handoffEvent.Value = value;
handoffEvent.Id = Guid.NewGuid().ToString();
handoffEvent.Timestamp = DateTime.UtcNow;
handoffEvent.Conversation = conversation;
handoffEvent.Attachments = new List<Attachment>();
handoffEvent.Entities = new List<Entity>();
return handoffEvent;
}
}
}
14 changes: 14 additions & 0 deletions libraries/Microsoft.Bot.Builder/HandoffEventNames.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Bot.Schema
{
/// <summary>
/// Defines values for handoff event names.
/// </summary>
public static class HandoffEventNames
{
public const string InitiateHandoff = "handoff.initiate";
public const string HandoffStatus = "handoff.status";
}
}
86 changes: 86 additions & 0 deletions tests/Microsoft.Bot.Builder.Tests/EventFactoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Adapters;
using Microsoft.Bot.Schema;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;

namespace Microsoft.Bot.Builder.Tests
{
[TestClass]
[TestCategory("Message")]
public class EventFactoryTests
{
public TestContext TestContext { get; set; }

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void HandoffInitiationNullTurnContext()
{
EventFactory.CreateHandoffInitiation(null, "some text");
}

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void HandoffStatusNullConversation()
{
EventFactory.CreateHandoffStatus(null, "accepted");
}

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void HandoffStatusNullStatus()
{
EventFactory.CreateHandoffStatus(new ConversationAccount(), null);
}

[TestMethod]
public void TestCreateHandoffInitiation()
{
var adapter = new TestAdapter(TestAdapter.CreateConversation(TestContext.TestName));
string fromID = "test";
var activity = new Activity
{
Type = ActivityTypes.Message,
Text = string.Empty,
Conversation = new ConversationAccount(),
Recipient = new ChannelAccount(),
From = new ChannelAccount(fromID),
ChannelId = "testchannel",
ServiceUrl = "http://myservice"
};
var context = new TurnContext(adapter, activity);

var transcript = new Transcript(new Activity[] { MessageFactory.Text("hello") });

Assert.IsNull(transcript.Activities[0].ChannelId);
Assert.IsNull(transcript.Activities[0].ServiceUrl);
Assert.IsNull(transcript.Activities[0].Conversation);

var handoffEvent = EventFactory.CreateHandoffInitiation(context, new { Skill = "any" }, transcript);
Assert.AreEqual(handoffEvent.Name, HandoffEventNames.InitiateHandoff);

Assert.AreEqual(handoffEvent.From.Id, fromID);
}

[TestMethod]
public void TestCreateHandoffStatus()
{
var state = "failed";
var message = "timed out";
var handoffEvent = EventFactory.CreateHandoffStatus(new ConversationAccount(), state, message);
Assert.AreEqual(handoffEvent.Name, HandoffEventNames.HandoffStatus);
string status = JsonConvert.SerializeObject(handoffEvent.Value, Formatting.None);
Assert.AreEqual(status, $"{{\"state\":\"{state}\",\"message\":\"{message}\"}}");
Assert.IsNotNull((handoffEvent as Activity).Attachments);
Assert.IsNotNull(handoffEvent.Id);
}
}
}