From bb0b9874e0cf21ae38e2d7b83f3dacde4ff15d05 Mon Sep 17 00:00:00 2001 From: Lee Parrish <30470292+LeeParrishMSFT@users.noreply.github.com> Date: Thu, 25 Mar 2021 14:52:51 -0500 Subject: [PATCH] Added support for Command activities --- .../bot/builder/ActivityHandler.java | 62 ++++++++++++++ .../bot/builder/ActivityHandlerTests.java | 48 +++++++++++ .../microsoft/bot/schema/ActivityTypes.java | 10 +++ .../bot/schema/CommandResultValue.java | 84 +++++++++++++++++++ .../microsoft/bot/schema/CommandValue.java | 61 ++++++++++++++ 5 files changed, 265 insertions(+) create mode 100644 libraries/bot-schema/src/main/java/com/microsoft/bot/schema/CommandResultValue.java create mode 100644 libraries/bot-schema/src/main/java/com/microsoft/bot/schema/CommandValue.java diff --git a/libraries/bot-builder/src/main/java/com/microsoft/bot/builder/ActivityHandler.java b/libraries/bot-builder/src/main/java/com/microsoft/bot/builder/ActivityHandler.java index e671f9edb..e9c4b6918 100644 --- a/libraries/bot-builder/src/main/java/com/microsoft/bot/builder/ActivityHandler.java +++ b/libraries/bot-builder/src/main/java/com/microsoft/bot/builder/ActivityHandler.java @@ -85,6 +85,12 @@ public CompletableFuture onTurn(TurnContext turnContext) { case ActivityTypes.INSTALLATION_UPDATE: return onInstallationUpdate(turnContext); + case ActivityTypes.COMMAND: + return onCommandActivity(turnContext); + + case ActivityTypes.COMMAND_RESULT: + return onCommandResultActivity(turnContext); + case ActivityTypes.END_OF_CONVERSATION: return onEndOfConversationActivity(turnContext); @@ -528,6 +534,62 @@ protected CompletableFuture onInstallationUpdate(TurnContext turnContext) } } + /** + * Invoked when a command activity is received when the base behavior of + * {@link ActivityHandler#onTurn(TurnContext)} is used. Commands are requests to perform an + * action and receivers typically respond with one or more commandResult + * activities. Receivers are also expected to explicitly reject unsupported + * command activities. + * + * @param turnContext A strongly-typed context Object for this + * turn. + * + * @return A task that represents the work queued to execute. + * + * When the {@link ActivityHandler#onTurn(TurnContext)} method receives a command activity, + * it calls this method. In a derived class, override this method to add + * logic that applies to all comand activities. Add logic to apply before + * the specific command-handling logic before the call to the base class + * {@link ActivityHandler#onCommandActivity(TurnContext)} method. Add + * logic to apply after the specific command-handling logic after the call + * to the base class + * {@link ActivityHandler#onCommandActivity(TurnContext)} method. Command + * activities communicate programmatic information from a client or channel + * to a bot. The meaning of an command activity is defined by the + * name property, which is meaningful within the scope of a channel. + */ + protected CompletableFuture onCommandActivity(TurnContext turnContext) { + return CompletableFuture.completedFuture(null); + } + + /** + * Invoked when a CommandResult activity is received when the + * base behavior of {@link ActivityHandler#onTurn(TurnContext)} is used. CommandResult + * activities can be used to communicate the result of a command execution. + * + * @param turnContext A strongly-typed context Object for this + * turn. + * + * @return A task that represents the work queued to execute. + * + * When the {@link ActivityHandler#onTurn(TurnContext)} method receives a CommandResult + * activity, it calls this method. In a derived class, override this method + * to add logic that applies to all comand activities. Add logic to apply + * before the specific CommandResult-handling logic before the call to the + * base class + * {@link ActivityHandler#onCommandResultActivity(TurnContext)} + * method. Add logic to apply after the specific CommandResult-handling + * logic after the call to the base class + * {@link ActivityHandler#onCommandResultActivity(TurnContext)} + * method. CommandResult activities communicate programmatic information + * from a client or channel to a bot. The meaning of an CommandResult + * activity is defined by the name property, + * which is meaningful within the scope of a channel. + */ + protected CompletableFuture onCommandResultActivity(TurnContext turnContext) { + return CompletableFuture.completedFuture(null); + } + /** * Override this in a derived class to provide logic specific to ActivityTypes.InstallationUpdate * activities with 'action' set to 'add'. diff --git a/libraries/bot-builder/src/test/java/com/microsoft/bot/builder/ActivityHandlerTests.java b/libraries/bot-builder/src/test/java/com/microsoft/bot/builder/ActivityHandlerTests.java index b6a5af8eb..6c8c30b2c 100644 --- a/libraries/bot-builder/src/test/java/com/microsoft/bot/builder/ActivityHandlerTests.java +++ b/libraries/bot-builder/src/test/java/com/microsoft/bot/builder/ActivityHandlerTests.java @@ -408,6 +408,42 @@ public void TestEventNullNameAsync() { Assert.assertEquals("onEvent", bot.getRecord().get(1)); } + @Test + public void TestCommandActivityType() { + Activity activity = new Activity(ActivityTypes.COMMAND); + activity.setName("application/test"); + CommandValue commandValue = new CommandValue(); + commandValue.setCommandId("Test"); + commandValue.setData(new Object()); + activity.setValue(commandValue); + + TurnContext turnContext = new TurnContextImpl(new NotImplementedAdapter(), activity); + + TestActivityHandler bot = new TestActivityHandler(); + bot.onTurn(turnContext).join(); + + Assert.assertEquals(bot.getRecord().size(), 1); + Assert.assertEquals("onCommandActivity", bot.record.get(0)); + } + + @Test + public void TestCommandResultActivityType() { + Activity activity = new Activity(ActivityTypes.COMMAND_RESULT); + activity.setName("application/test"); + CommandResultValue commandValue = new CommandResultValue(); + commandValue.setCommandId("Test"); + commandValue.setData(new Object()); + activity.setValue(commandValue); + + TurnContext turnContext = new TurnContextImpl(new NotImplementedAdapter(), activity); + + TestActivityHandler bot = new TestActivityHandler(); + bot.onTurn(turnContext).join(); + + Assert.assertEquals(bot.getRecord().size(), 1); + Assert.assertEquals("onCommandResultActivity", bot.record.get(0)); + } + @Test public void TestUnrecognizedActivityType() { Activity activity = new Activity() { @@ -570,5 +606,17 @@ protected CompletableFuture onUnrecognizedActivityType(TurnContext turnContext) return super.onUnrecognizedActivityType(turnContext); } + @Override + protected CompletableFuture onCommandActivity(TurnContext turnContext){ + record.add("onCommandActivity"); + return super.onCommandActivity(turnContext); + } + + @Override + protected CompletableFuture onCommandResultActivity(TurnContext turnContext) { + record.add("onCommandResultActivity"); + return super.onCommandResultActivity(turnContext); + } + } } diff --git a/libraries/bot-schema/src/main/java/com/microsoft/bot/schema/ActivityTypes.java b/libraries/bot-schema/src/main/java/com/microsoft/bot/schema/ActivityTypes.java index cfcf66abb..d6a350659 100644 --- a/libraries/bot-schema/src/main/java/com/microsoft/bot/schema/ActivityTypes.java +++ b/libraries/bot-schema/src/main/java/com/microsoft/bot/schema/ActivityTypes.java @@ -31,6 +31,16 @@ private ActivityTypes() { */ public static final String TYPING = "typing"; + /** + * Enum value for Command Activities. + */ + public static final String COMMAND = "command"; + + /** + * Enum value for Command Result Activities. + */ + public static final String COMMAND_RESULT = "commandResult"; + /** * Enum value endOfConversation. */ diff --git a/libraries/bot-schema/src/main/java/com/microsoft/bot/schema/CommandResultValue.java b/libraries/bot-schema/src/main/java/com/microsoft/bot/schema/CommandResultValue.java new file mode 100644 index 000000000..4818dca60 --- /dev/null +++ b/libraries/bot-schema/src/main/java/com/microsoft/bot/schema/CommandResultValue.java @@ -0,0 +1,84 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MT License. + +package com.microsoft.bot.schema; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * The value field of a CommandResultActivity contains metadata related + * to a command result.An optional extensible data payload may be included if + * defined by the command result activity name. The presence of an error field + * indicates that the original command failed to complete. + * @param The type of the CommandResultValue. + */ +public class CommandResultValue { + + @JsonProperty(value = "commandId") + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private String commandId; + + @JsonProperty(value = "data") + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private T data; + + @JsonProperty(value = "error") + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private Error error; + + /** + * Gets the id of the command. + * @return the CommandId value as a String. + */ + public String getCommandId() { + return this.commandId; + } + + /** + * Sets the id of the command. + * @param withCommandId The CommandId value. + */ + public void setCommandId(String withCommandId) { + this.commandId = withCommandId; + } + + /** + * Gets the data field containing optional parameters specific to + * this command result activity, as defined by the name. The value of the + * data field is a complex type. + * @return the Data value as a T. + */ + public T getData() { + return this.data; + } + + /** + * Sets the data field containing optional parameters specific to + * this command result activity, as defined by the name. The value of the + * data field is a complex type. + * @param withData The Data value. + */ + public void setData(T withData) { + this.data = withData; + } + + /** + * Gets the optional error, if the command result indicates a + * failure. + * @return the Error value as a getError(). + */ + public Error getError() { + return this.error; + } + + /** + * Sets the optional error, if the command result indicates a + * failure. + * @param withError The Error value. + */ + public void setError(Error withError) { + this.error = withError; + } + +} diff --git a/libraries/bot-schema/src/main/java/com/microsoft/bot/schema/CommandValue.java b/libraries/bot-schema/src/main/java/com/microsoft/bot/schema/CommandValue.java new file mode 100644 index 000000000..d80b9e708 --- /dev/null +++ b/libraries/bot-schema/src/main/java/com/microsoft/bot/schema/CommandValue.java @@ -0,0 +1,61 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MT License. + +package com.microsoft.bot.schema; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * The value field of a CommandActivity contains metadata related to a + * command.An optional extensible data payload may be included if defined by + * the command activity name. + * @param The type of the CommandValue. + */ +public class CommandValue { + + @JsonProperty(value = "commandId") + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private String commandId; + + @JsonProperty(value = "data") + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private T data; + + /** + * Gets the id of the command. + * @return the CommandId value as a String. + */ + public String getCommandId() { + return this.commandId; + } + + /** + * Sets the id of the command. + * @param withCommandId The CommandId value. + */ + public void setCommandId(String withCommandId) { + this.commandId = withCommandId; + } + + /** + * Gets the data field containing optional parameters specific to + * this command activity, as defined by the name. The value of the data + * field is a complex type. + * @return the Data value as a T. + */ + public T getData() { + return this.data; + } + + /** + * Sets the data field containing optional parameters specific to + * this command activity, as defined by the name. The value of the data + * field is a complex type. + * @param withData The Data value. + */ + public void setData(T withData) { + this.data = withData; + } + +}