Cleanup - pass 1
This commit is contained in:
Родитель
a708abdcf9
Коммит
08589b677f
|
@ -13,19 +13,28 @@ import java.util.List;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* An implementation of the IBot interface intended for further subclassing.
|
||||
* Derive from this class to plug in code to handle particular Activity types.
|
||||
* An implementation of the {@link Bot} interface intended for further subclassing.
|
||||
* Derive from this class to plug in code to handle particular {@link Activity} types.
|
||||
* Pre and post processing of Activities can be plugged in by deriving and calling
|
||||
* the base class implementation.
|
||||
*/
|
||||
public class ActivityHandler implements Bot {
|
||||
/**
|
||||
* The OnTurnAsync function is called by the Adapter (for example, the {@link BotFrameworkAdapter} at
|
||||
* runtime in order to process an inbound Activity.
|
||||
* Called by the adapter (for example, a {@link BotFrameworkAdapter}) at runtime in order
|
||||
* to process an inbound {@link Activity}.
|
||||
*
|
||||
* <p>This method calls other methods in this class based on the type of the activity to
|
||||
* process, which allows a derived class to provide type-specific logic in a controlled way.</p>
|
||||
*
|
||||
* <p>In a derived class, override this method to add logic that applies to all activity types.
|
||||
* Add logic to apply before the type-specific logic before the call to the base class
|
||||
* {@link Bot#onTurn(TurnContext)} method.
|
||||
* Add logic to apply after the type-specific logic after the call to the base class
|
||||
* {@link Bot#onTurn(TurnContext)} method.</p>
|
||||
*
|
||||
* @param turnContext The context object for this turn. Provides information about the
|
||||
* incoming activity, and other data needed to process the activity.
|
||||
* @return
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<Void> onTurn(TurnContext turnContext) {
|
||||
|
@ -57,11 +66,10 @@ public class ActivityHandler implements Bot {
|
|||
}
|
||||
|
||||
/**
|
||||
* Invoked when a message activity is received from the user when the base behavior of
|
||||
* {@link #onTurn(TurnContext)} is used.
|
||||
* <p>
|
||||
* If overridden, this could potentially contain conversational logic.
|
||||
* By default, this method does nothing.
|
||||
* Override this in a derived class to provide logic specific to {@link ActivityTypes#MESSAGE}
|
||||
* activities, such as the conversational logic.
|
||||
*
|
||||
* When the {@link #onTurn(TurnContext)} method receives a message activity, it calls this method.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
|
@ -73,14 +81,15 @@ public class ActivityHandler implements Bot {
|
|||
/**
|
||||
* Invoked when a conversation update activity is received from the channel when the base behavior of
|
||||
* {@link #onTurn(TurnContext)} is used.
|
||||
* <p>
|
||||
* Conversation update activities are useful when it comes to responding to users being added to or removed
|
||||
* from the conversation.
|
||||
* <p>
|
||||
*
|
||||
* Conversation update activities are useful when it comes to responding to users being added to or
|
||||
* removed from the conversation.
|
||||
*
|
||||
* For example, a bot could respond to a user being added by greeting the user.
|
||||
* By default, this method will call {@link #onMembersAdded(List, TurnContext)} if any users have been added,
|
||||
* or {@link #onMembersRemoved(List, TurnContext)} if any users have been removed. The method checks the member
|
||||
* ID so that it only responds to updates regarding members other than the bot itself.
|
||||
* By default, this method will call {@link #onMembersAdded(List, TurnContext)} if any users have
|
||||
* been added or {@link #onMembersRemoved(List, TurnContext)} if any users have been removed. The
|
||||
* method checks the member ID so that it only responds to updates regarding members other than the
|
||||
* bot itself.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
|
@ -106,15 +115,15 @@ public class ActivityHandler implements Bot {
|
|||
}
|
||||
|
||||
/**
|
||||
* Invoked when members other than this bot (like a user) are added to the conversation when the base behavior of
|
||||
* {@link #onConversationUpdateActivity(TurnContext)} is used.
|
||||
* <p>
|
||||
* If overridden, this could potentially send a greeting message to the user instead of waiting for the user to
|
||||
* send a message first.
|
||||
* <p>
|
||||
* By default, this method does nothing.
|
||||
* Override this in a derived class to provide logic for when members other than the bot
|
||||
* join the conversation, such as your bot's welcome logic.
|
||||
*
|
||||
* @param membersAdded A list of all the users that have been added in the conversation update.
|
||||
* <p>When the {@link #onConversationUpdateActivity(TurnContext)} method receives a conversation
|
||||
* update activity that indicates one or more users other than the bo are joining the conversation,
|
||||
* it calls this method.</p>
|
||||
*
|
||||
* @param membersAdded A list of all the members added to the conversation, as described by
|
||||
* the conversation update activity.
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
|
@ -123,14 +132,15 @@ public class ActivityHandler implements Bot {
|
|||
}
|
||||
|
||||
/**
|
||||
* Invoked when members other than this bot (like a user) are removed from the conversation when the base
|
||||
* behavior of {@link #onConversationUpdateActivity(TurnContext)} is used.
|
||||
* <p>
|
||||
* This method could optionally be overridden to perform actions related to users leaving a group conversation.
|
||||
* <p>
|
||||
* By default, this method does nothing.
|
||||
* Override this in a derived class to provide logic for when members other than the bot
|
||||
* leave the conversation, such as your bot's good-bye logic.
|
||||
*
|
||||
* @param membersRemoved A list of all the users that have been removed in the conversation update.
|
||||
* <p>When the {@link #onConversationUpdateActivity(TurnContext)} method receives a conversation
|
||||
* update activity that indicates one or more users other than the bot are leaving the conversation,
|
||||
* it calls this method.</p>
|
||||
*
|
||||
* @param membersRemoved A list of all the members removed from the conversation, as described
|
||||
* by the conversation update activity.
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
|
@ -141,13 +151,22 @@ public class ActivityHandler implements Bot {
|
|||
/**
|
||||
* Invoked when an event activity is received from the connector when the base behavior of
|
||||
* {@link #onTurn(TurnContext)} is used.
|
||||
* <p>
|
||||
* Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a
|
||||
* previously sent activity. Message reactions are only supported by a few channels.
|
||||
* <p>
|
||||
* The activity that the message reaction corresponds to is indicated in the replyToId property.
|
||||
*
|
||||
* <p>Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a
|
||||
* previously sent activity. Message reactions are only supported by a few channels.</p>
|
||||
*
|
||||
* <p>The activity that the message reaction corresponds to is indicated in the replyToId property.
|
||||
* The value of this property is the activity id of a previously sent activity given back to the
|
||||
* bot as the response from a send call.
|
||||
* bot as the response from a send call.</p>
|
||||
*
|
||||
* <p>When the {@link #onTurn(TurnContext)} method receives a message reaction activity, it calls this
|
||||
* method. If the message reaction indicates that reactions were added to a message, it calls
|
||||
* {@link #onReactionsAdded(List, TurnContext)}. If the message reaction indicates that reactions were
|
||||
* removed from a message, it calls {@link #onReactionsRemoved(List, TurnContext)}.</p>
|
||||
*
|
||||
* <p>In a derived class, override this method to add logic that applies to all message reaction activities.
|
||||
* Add logic to apply before the reactions added or removed logic before the call to the base class
|
||||
* method. Add logic to apply after the reactions added or removed logic after the call to the base class.</p>
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
|
@ -172,7 +191,15 @@ public class ActivityHandler implements Bot {
|
|||
}
|
||||
|
||||
/**
|
||||
* Called when there have been Reactions added that reference a previous Activity.
|
||||
* Override this in a derived class to provide logic for when reactions to a previous activity
|
||||
* are added to the conversation.
|
||||
*
|
||||
* <p>Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a
|
||||
* previously sent message on the conversation. Message reactions are supported by only a few channels.
|
||||
* The activity that the message is in reaction to is identified by the activity's
|
||||
* {@link Activity#getReplyToId()} property. The value of this property is the activity ID
|
||||
* of a previously sent activity. When the bot sends an activity, the channel assigns an ID to it,
|
||||
* which is available in the {@link com.microsoft.bot.schema.ResourceResponse#getId} of the result.</p>
|
||||
*
|
||||
* @param messageReactions The list of reactions added.
|
||||
* @param turnContext The context object for this turn.
|
||||
|
@ -184,7 +211,15 @@ public class ActivityHandler implements Bot {
|
|||
}
|
||||
|
||||
/**
|
||||
* Called when there have been Reactions removed that reference a previous Activity.
|
||||
* Override this in a derived class to provide logic for when reactions to a previous activity
|
||||
* are removed from the conversation.
|
||||
*
|
||||
* <p>Message reactions correspond to the user adding a 'like' or 'sad' etc. (often an emoji) to a
|
||||
* previously sent message on the conversation. Message reactions are supported by only a few channels.
|
||||
* The activity that the message is in reaction to is identified by the activity's
|
||||
* {@link Activity#getReplyToId()} property. The value of this property is the activity ID
|
||||
* of a previously sent activity. When the bot sends an activity, the channel assigns an ID to it,
|
||||
* which is available in the {@link com.microsoft.bot.schema.ResourceResponse#getId} of the result.</p>
|
||||
*
|
||||
* @param messageReactions The list of reactions removed.
|
||||
* @param turnContext The context object for this turn.
|
||||
|
@ -198,12 +233,28 @@ public class ActivityHandler implements Bot {
|
|||
/**
|
||||
* Invoked when an event activity is received from the connector when the base behavior of
|
||||
* {@link #onTurn(TurnContext)} is used.
|
||||
* <p>
|
||||
* Event activities can be used to communicate many different things.
|
||||
* <p>
|
||||
* By default, this method will call {@link #onTokenResponseEvent(TurnContext)} if the
|
||||
*
|
||||
* <p>Event activities can be used to communicate many different things.</p>
|
||||
*
|
||||
* <p>By default, this method will call {@link #onTokenResponseEvent(TurnContext)} if the
|
||||
* activity's name is "tokens/response" or {@link #onEvent(TurnContext)} otherwise.
|
||||
* "tokens/response" event can be triggered by an {@link com.microsoft.bot.schema.OAuthCard}.
|
||||
* "tokens/response" event can be triggered by an {@link com.microsoft.bot.schema.OAuthCard}.</p>
|
||||
*
|
||||
* <p>When the {@link #onTurn(TurnContext)} method receives an event activity, it calls this method.</p>
|
||||
*
|
||||
* <p>If the event {@link Activity#getName} is `tokens/response`, it calls
|
||||
* {@link #onTokenResponseEvent(TurnContext)} otherwise, it calls {@link #onEvent(TurnContext)}.</p>
|
||||
*
|
||||
* <p>In a derived class, override this method to add logic that applies to all event activities.
|
||||
* Add logic to apply before the specific event-handling logic before the call to the base class
|
||||
* method. Add logic to apply after the specific event-handling logic after the call to the base class
|
||||
* method.</p>
|
||||
*
|
||||
* <p>Event activities communicate programmatic information from a client or channel to a bot.
|
||||
* The meaning of an event activity is defined by the {@link Activity#getName} property,
|
||||
* which is meaningful within the scope of a channel.
|
||||
* A `tokens/response` event can be triggered by an {@link com.microsoft.bot.schema.OAuthCard} or
|
||||
* an OAuth prompt.</p>
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
|
@ -219,10 +270,14 @@ public class ActivityHandler implements Bot {
|
|||
/**
|
||||
* Invoked when a "tokens/response" event is received when the base behavior of
|
||||
* {@link #onEventActivity(TurnContext)} is used.
|
||||
* <p>
|
||||
* If using an OAuthPrompt, override this method to forward this {@link Activity} to the current dialog.
|
||||
* <p>
|
||||
* By default, this method does nothing.
|
||||
*
|
||||
* <p>If using an OAuthPrompt, override this method to forward this {@link Activity} to the
|
||||
* current dialog.</p>
|
||||
*
|
||||
* <p>By default, this method does nothing.</p>
|
||||
*
|
||||
* When the {@link #onEventActivity(TurnContext)} method receives an event with a {@link Activity#getName()}
|
||||
* of `tokens/response`, it calls this method.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
|
@ -234,10 +289,13 @@ public class ActivityHandler implements Bot {
|
|||
/**
|
||||
* Invoked when an event other than tokens/response is received when the base behavior of
|
||||
* {@link #onEventActivity(TurnContext)} is used.
|
||||
* <p>
|
||||
* This method could optionally be overridden if the bot is meant to handle miscellaneous events.
|
||||
* <p>
|
||||
* By default, this method does nothing.
|
||||
*
|
||||
* <p>This method could optionally be overridden if the bot is meant to handle miscellaneous events.</p>
|
||||
*
|
||||
* <p>By default, this method does nothing.</p>
|
||||
*
|
||||
* When the {@link #onEventActivity(TurnContext)} method receives an event with a {@link Activity#getName()}
|
||||
* other than `tokens/response`, it calls this method.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
|
@ -250,11 +308,14 @@ public class ActivityHandler implements Bot {
|
|||
* Invoked when an activity other than a message, conversation update, or event is received
|
||||
* when the base behavior of {@link #onTurn(TurnContext)} is used.
|
||||
*
|
||||
* If overridden, this could potentially respond to any of the other activity types like
|
||||
* <p>If overridden, this could potentially respond to any of the other activity types like
|
||||
* {@link com.microsoft.bot.schema.ActivityTypes#CONTACT_RELATION_UPDATE} or
|
||||
* {@link com.microsoft.bot.schema.ActivityTypes#END_OF_CONVERSATION}.
|
||||
* <p>
|
||||
* By default, this method does nothing.
|
||||
* {@link com.microsoft.bot.schema.ActivityTypes#END_OF_CONVERSATION}.</p>
|
||||
*
|
||||
* <p>By default, this method does nothing.</p>
|
||||
*
|
||||
* <p>When the {@link #onTurn(TurnContext)} method receives an activity that is not a message,
|
||||
* conversation update, message reaction, or event activity, it calls this method.</p>
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
|
|
|
@ -10,24 +10,53 @@ import java.util.concurrent.CompletableFuture;
|
|||
* Middleware to automatically call .SaveChanges() at the end of the turn for all BotState class it is managing.
|
||||
*/
|
||||
public class AutoSaveStateMiddleware implements Middleware {
|
||||
/**
|
||||
* The list of state management objects managed by this object.
|
||||
*/
|
||||
private BotStateSet botStateSet;
|
||||
|
||||
public AutoSaveStateMiddleware(BotState ... botStates) {
|
||||
/**
|
||||
* Initializes a new instance of the AutoSaveStateMiddleware class.
|
||||
*
|
||||
* @param botStates Initial list of {@link BotState} objects to manage.
|
||||
*/
|
||||
public AutoSaveStateMiddleware(BotState... botStates) {
|
||||
botStateSet = new BotStateSet(Arrays.asList(botStates));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the AutoSaveStateMiddleware class.
|
||||
*
|
||||
* @param withBotStateSet Initial {@link BotStateSet} object to manage.
|
||||
*/
|
||||
public AutoSaveStateMiddleware(BotStateSet withBotStateSet) {
|
||||
botStateSet = withBotStateSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of state management objects managed by this object.
|
||||
*
|
||||
* @return The state management objects managed by this object.
|
||||
*/
|
||||
public BotStateSet getBotStateSet() {
|
||||
return botStateSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of state management objects managed by this object.
|
||||
*
|
||||
* @param withBotStateSet The state management objects managed by this object.
|
||||
*/
|
||||
public void setBotStateSet(BotStateSet withBotStateSet) {
|
||||
botStateSet = withBotStateSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a BotState to the list of sources to load.
|
||||
*
|
||||
* @param botState botState to manage.
|
||||
* @return botstateset for chaining more .use().
|
||||
*/
|
||||
public AutoSaveStateMiddleware add(BotState botState) {
|
||||
if (botState == null) {
|
||||
throw new IllegalArgumentException("botState cannot be null");
|
||||
|
|
|
@ -5,13 +5,11 @@ package com.microsoft.bot.builder;
|
|||
|
||||
import com.microsoft.bot.schema.Activity;
|
||||
import com.microsoft.bot.schema.ConversationReference;
|
||||
import com.microsoft.bot.schema.ConversationReferenceHelper;
|
||||
import com.microsoft.bot.schema.ResourceResponse;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Represents a bot adapter that can connect a bot to a service endpoint.
|
||||
|
@ -36,7 +34,7 @@ public abstract class BotAdapter {
|
|||
/**
|
||||
* The collection of middleware in the adapter's pipeline.
|
||||
*/
|
||||
protected final MiddlewareSet middlewareSet = new MiddlewareSet();
|
||||
private final MiddlewareSet middlewareSet = new MiddlewareSet();
|
||||
|
||||
/**
|
||||
* Error handler that can catch exceptions in the middleware or application.
|
||||
|
@ -44,20 +42,32 @@ public abstract class BotAdapter {
|
|||
private OnTurnErrorHandler onTurnError;
|
||||
|
||||
/**
|
||||
* Creates a default adapter.
|
||||
* Gets the error handler that can catch exceptions in the middleware or application.
|
||||
*
|
||||
* @return An error handler that can catch exceptions in the middleware or application.
|
||||
*/
|
||||
public BotAdapter() {
|
||||
super();
|
||||
}
|
||||
|
||||
public OnTurnErrorHandler getOnTurnError() {
|
||||
return onTurnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the error handler that can catch exceptions in the middleware or application.
|
||||
*
|
||||
* @param withTurnError An error handler that can catch exceptions in the middleware or application.
|
||||
*/
|
||||
public void setOnTurnError(OnTurnErrorHandler withTurnError) {
|
||||
onTurnError = withTurnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the collection of middleware in the adapter's pipeline.
|
||||
*
|
||||
* @return The middleware collection for the pipeline.
|
||||
*/
|
||||
protected MiddlewareSet getMiddlewareSet() {
|
||||
return middlewareSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds middleware to the adapter's pipeline.
|
||||
*
|
||||
|
@ -82,7 +92,8 @@ public abstract class BotAdapter {
|
|||
* the receiving channel assigned to the activities.
|
||||
* {@link TurnContext#onSendActivities(SendActivitiesHandler)}
|
||||
*/
|
||||
public abstract CompletableFuture<ResourceResponse[]> sendActivities(TurnContext context, List<Activity> activities);
|
||||
public abstract CompletableFuture<ResourceResponse[]> sendActivities(TurnContext context,
|
||||
List<Activity> activities);
|
||||
|
||||
/**
|
||||
* When overridden in a derived class, replaces an existing activity in the
|
||||
|
@ -98,7 +109,8 @@ public abstract class BotAdapter {
|
|||
* of the activity to replace.</p>
|
||||
* {@link TurnContext#onUpdateActivity(UpdateActivityHandler)}
|
||||
*/
|
||||
public abstract CompletableFuture<ResourceResponse> updateActivity(TurnContext context, Activity activity);
|
||||
public abstract CompletableFuture<ResourceResponse> updateActivity(TurnContext context,
|
||||
Activity activity);
|
||||
|
||||
/**
|
||||
* When overridden in a derived class, deletes an existing activity in the
|
||||
|
@ -113,7 +125,6 @@ public abstract class BotAdapter {
|
|||
*/
|
||||
public abstract CompletableFuture<Void> deleteActivity(TurnContext context, ConversationReference reference);
|
||||
|
||||
|
||||
/**
|
||||
* Starts activity processing for the current bot turn.
|
||||
*
|
||||
|
@ -121,7 +132,7 @@ public abstract class BotAdapter {
|
|||
* The adapter passes in the context object for the turn and a next delegate,
|
||||
* and the middleware calls the delegate to pass control to the next middleware
|
||||
* in the pipeline. Once control reaches the end of the pipeline, the adapter calls
|
||||
* the {@code callback} method. If a middleware component doesn’t call
|
||||
* the {@code callback} method. If a middleware component does not call
|
||||
* the next delegate, the adapter does not call any of the subsequent middleware’s
|
||||
* {@link Middleware#onTurn(TurnContext, NextDelegate)}
|
||||
* methods or the callback method, and the pipeline short circuits.
|
||||
|
@ -163,24 +174,22 @@ public abstract class BotAdapter {
|
|||
/**
|
||||
* Sends a proactive message to a conversation.
|
||||
*
|
||||
* @param botId The application ID of the bot. This paramter is ignored in
|
||||
* single tenant the Adpters (Console, Test, etc) but is critical to the BotFrameworkAdapter
|
||||
* @param botId The application ID of the bot. This parameter is ignored in
|
||||
* single tenant the Adapters (Console, Test, etc) but is critical to the BotFrameworkAdapter
|
||||
* which is multi-tenant aware.
|
||||
* @param reference A reference to the conversation to continue.
|
||||
* @param callback The method to call for the resulting bot turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* Call this method to proactively send a message to a conversation.
|
||||
* Most channels require a user to initaiate a conversation with a bot
|
||||
* Most channels require a user to initiate a conversation with a bot
|
||||
* before the bot can send activities to the user.
|
||||
* {@linkalso RunPipeline(TurnContext, Func { TurnContext, Task })}
|
||||
*
|
||||
* {@link #runPipeline(TurnContext, BotCallbackHandler)}
|
||||
*/
|
||||
public CompletableFuture<Void> continueConversation(String botId,
|
||||
ConversationReference reference,
|
||||
BotCallbackHandler callback) {
|
||||
|
||||
ConversationReferenceHelper conv = new ConversationReferenceHelper(reference);
|
||||
Activity activity = conv.getPostToBotMessage();
|
||||
|
||||
return runPipeline(new TurnContextImpl(this, activity), callback);
|
||||
return runPipeline(new TurnContextImpl(this, reference.getContinuationActivity()), callback);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ package com.microsoft.bot.builder;
|
|||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import com.microsoft.bot.builder.integration.AdapterIntegration;
|
||||
import com.microsoft.bot.connector.*;
|
||||
import com.microsoft.bot.connector.authentication.*;
|
||||
import com.microsoft.bot.connector.rest.RestConnectorClient;
|
||||
|
@ -31,6 +32,7 @@ import static java.util.concurrent.CompletableFuture.completedFuture;
|
|||
|
||||
/**
|
||||
* A bot adapter that can connect a bot to a service endpoint.
|
||||
*
|
||||
* The bot adapter encapsulates authentication processes and sends
|
||||
* activities to and receives activities from the Bot Connector Service. When your
|
||||
* bot receives an activity, the adapter creates a context object, passes it to your
|
||||
|
@ -47,15 +49,35 @@ import static java.util.concurrent.CompletableFuture.completedFuture;
|
|||
* {@link Bot}
|
||||
* {@link Middleware}
|
||||
*/
|
||||
public class BotFrameworkAdapter extends BotAdapter {
|
||||
private final static String InvokeResponseKey = "BotFrameworkAdapter.InvokeResponse";
|
||||
private final static String BotIdentityKey = "BotIdentity";
|
||||
public class BotFrameworkAdapter extends BotAdapter implements AdapterIntegration, UserTokenProvider {
|
||||
private static final String INVOKE_RESPONSE_KEY = "BotFrameworkAdapter.InvokeResponse";
|
||||
private static final String BOT_IDENTITY_KEY = "BotIdentity";
|
||||
private static final String CONNECTOR_CLIENT_KEY = "ConnectorClient";
|
||||
|
||||
/**
|
||||
* The credential provider.
|
||||
*/
|
||||
private final CredentialProvider credentialProvider;
|
||||
|
||||
/**
|
||||
* The channel provider.
|
||||
*/
|
||||
private ChannelProvider channelProvider;
|
||||
|
||||
/**
|
||||
* The authentication configuration.
|
||||
*/
|
||||
private AuthenticationConfiguration authConfiguration;
|
||||
|
||||
/**
|
||||
* Rest RetryStrategy.
|
||||
*/
|
||||
private final RetryStrategy connectorClientRetryStrategy;
|
||||
private Map<String, MicrosoftAppCredentials> appCredentialMap = new ConcurrentHashMap<String, MicrosoftAppCredentials>();
|
||||
|
||||
/**
|
||||
* AppCredentials dictionary.
|
||||
*/
|
||||
private Map<String, MicrosoftAppCredentials> appCredentialMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the {@link BotFrameworkAdapter} class,
|
||||
|
@ -173,11 +195,11 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
}};
|
||||
ClaimsIdentity claimsIdentity = new ClaimsIdentity("ExternalBearer", claims);
|
||||
|
||||
context.getTurnState().add(TurnContextStateNames.BOT_IDENTITY, claimsIdentity);
|
||||
context.getTurnState().add(BOT_IDENTITY_KEY, claimsIdentity);
|
||||
|
||||
return createConnectorClient(reference.getServiceUrl(), claimsIdentity)
|
||||
.thenCompose(connectorClient -> {
|
||||
context.getTurnState().add(TurnContextStateNames.CONNECTOR_CLIENT, connectorClient);
|
||||
context.getTurnState().add(CONNECTOR_CLIENT_KEY, connectorClient);
|
||||
return runPipeline(context, callback);
|
||||
});
|
||||
}
|
||||
|
@ -192,7 +214,7 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
* @return The updated adapter object.
|
||||
*/
|
||||
public BotFrameworkAdapter use(Middleware middleware) {
|
||||
super.middlewareSet.use(middleware);
|
||||
getMiddlewareSet().use(middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -213,8 +235,8 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
BotCallbackHandler callback) {
|
||||
BotAssert.activityNotNull(activity);
|
||||
|
||||
return JwtTokenValidation.authenticateRequest(activity,
|
||||
authHeader, credentialProvider, channelProvider, authConfiguration)
|
||||
return JwtTokenValidation.authenticateRequest(
|
||||
activity, authHeader, credentialProvider, channelProvider, authConfiguration)
|
||||
|
||||
.thenCompose(claimsIdentity -> processActivity(claimsIdentity, activity, callback));
|
||||
}
|
||||
|
@ -237,21 +259,21 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
BotAssert.activityNotNull(activity);
|
||||
|
||||
TurnContextImpl context = new TurnContextImpl(this, activity);
|
||||
context.getTurnState().add(TurnContextStateNames.BOT_IDENTITY, identity);
|
||||
context.getTurnState().add(BOT_IDENTITY_KEY, identity);
|
||||
|
||||
return createConnectorClient(activity.getServiceUrl(), identity)
|
||||
|
||||
// run pipeline
|
||||
.thenCompose(connectorClient -> {
|
||||
context.getTurnState().add(TurnContextStateNames.CONNECTOR_CLIENT, connectorClient);
|
||||
|
||||
context.getTurnState().add(CONNECTOR_CLIENT_KEY, connectorClient);
|
||||
return runPipeline(context, callback);
|
||||
})
|
||||
|
||||
// Handle Invoke scenarios, which deviate from the request/response model in that
|
||||
// the Bot will return a specific body and return code.
|
||||
.thenCompose(result -> {
|
||||
// Handle Invoke scenarios, which deviate from the request/response model in that
|
||||
// the Bot will return a specific body and return code.
|
||||
if (activity.isType(ActivityTypes.INVOKE)) {
|
||||
Activity invokeResponse = context.getTurnState().get(InvokeResponseKey);
|
||||
Activity invokeResponse = context.getTurnState().get(INVOKE_RESPONSE_KEY);
|
||||
if (invokeResponse == null) {
|
||||
throw new IllegalStateException("Bot failed to return a valid 'invokeResponse' activity.");
|
||||
} else {
|
||||
|
@ -311,22 +333,20 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
try {
|
||||
Thread.sleep(delayMs);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
//await(Task.Delay(delayMs));
|
||||
// No need to create a response. One will be created below.
|
||||
} else if (activity.isType(ActivityTypes.INVOKE_RESPONSE)) {
|
||||
context.getTurnState().add(InvokeResponseKey, activity);
|
||||
context.getTurnState().add(INVOKE_RESPONSE_KEY, activity);
|
||||
// No need to create a response. One will be created below.
|
||||
} else if (activity.isType(ActivityTypes.TRACE)
|
||||
&& !StringUtils.equals(activity.getChannelId(), Channels.EMULATOR)) {
|
||||
// if it is a Trace activity we only send to the channel if it's the emulator.
|
||||
} else if (!StringUtils.isEmpty(activity.getReplyToId())) {
|
||||
ConnectorClient connectorClient = context.getTurnState().get(
|
||||
TurnContextStateNames.CONNECTOR_CLIENT);
|
||||
ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY);
|
||||
response = connectorClient.getConversations().replyToActivity(activity).join();
|
||||
} else {
|
||||
ConnectorClient connectorClient = context.getTurnState().get(
|
||||
TurnContextStateNames.CONNECTOR_CLIENT);
|
||||
ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY);
|
||||
response = connectorClient.getConversations().sendToConversation(activity).join();
|
||||
}
|
||||
|
||||
|
@ -365,7 +385,7 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
*/
|
||||
@Override
|
||||
public CompletableFuture<ResourceResponse> updateActivity(TurnContext context, Activity activity) {
|
||||
ConnectorClient connectorClient = context.getTurnState().get(TurnContextStateNames.CONNECTOR_CLIENT);
|
||||
ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY);
|
||||
return connectorClient.getConversations().updateActivity(activity);
|
||||
}
|
||||
|
||||
|
@ -379,7 +399,7 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
*/
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteActivity(TurnContext context, ConversationReference reference) {
|
||||
ConnectorClient connectorClient = context.getTurnState().get(TurnContextStateNames.CONNECTOR_CLIENT);
|
||||
ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY);
|
||||
return connectorClient.getConversations().deleteActivity(
|
||||
reference.getConversation().getId(), reference.getActivityId());
|
||||
}
|
||||
|
@ -402,7 +422,7 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
"BotFrameworkAdapter.deleteConversationMember(): missing conversation.id");
|
||||
}
|
||||
|
||||
ConnectorClient connectorClient = context.getTurnState().get(TurnContextStateNames.CONNECTOR_CLIENT);
|
||||
ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY);
|
||||
String conversationId = context.getActivity().getConversation().getId();
|
||||
return connectorClient.getConversations().deleteConversationMember(conversationId, memberId);
|
||||
}
|
||||
|
@ -438,7 +458,7 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
throw new IllegalArgumentException("BotFrameworkAdapter.GetActivityMembers(): missing conversation.id");
|
||||
}
|
||||
|
||||
ConnectorClient connectorClient = context.getTurnState().get(TurnContextStateNames.CONNECTOR_CLIENT);
|
||||
ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY);
|
||||
String conversationId = context.getActivity().getConversation().getId();
|
||||
|
||||
return connectorClient.getConversations().getActivityMembers(conversationId, activityId);
|
||||
|
@ -459,7 +479,7 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
throw new IllegalArgumentException("BotFrameworkAdapter.GetActivityMembers(): missing conversation.id");
|
||||
}
|
||||
|
||||
ConnectorClient connectorClient = context.getTurnState().get("ConnectorClient");
|
||||
ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY);
|
||||
String conversationId = context.getActivity().getConversation().getId();
|
||||
|
||||
return connectorClient.getConversations().getConversationMembers(conversationId);
|
||||
|
@ -532,7 +552,7 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
* @return List of Members of the current conversation
|
||||
*/
|
||||
public CompletableFuture<ConversationsResult> getConversations(TurnContextImpl context) {
|
||||
ConnectorClient connectorClient = context.getTurnState().get(TurnContextStateNames.CONNECTOR_CLIENT);
|
||||
ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY);
|
||||
return connectorClient.getConversations().getConversations();
|
||||
}
|
||||
|
||||
|
@ -550,7 +570,7 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
* @return List of Members of the current conversation
|
||||
*/
|
||||
public CompletableFuture<ConversationsResult> getConversations(TurnContextImpl context, String continuationToken) {
|
||||
ConnectorClient connectorClient = context.getTurnState().get(TurnContextStateNames.CONNECTOR_CLIENT);
|
||||
ConnectorClient connectorClient = context.getTurnState().get(CONNECTOR_CLIENT_KEY);
|
||||
return connectorClient.getConversations().getConversations(continuationToken);
|
||||
}
|
||||
|
||||
|
@ -562,7 +582,8 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
* @param magicCode (Optional) Optional user entered code to validate.
|
||||
* @return Token Response
|
||||
*/
|
||||
public CompletableFuture<TokenResponse> getUserToken(TurnContextImpl context, String connectionName, String magicCode) {
|
||||
@Override
|
||||
public CompletableFuture<TokenResponse> getUserToken(TurnContext context, String connectionName, String magicCode) {
|
||||
BotAssert.contextNotNull(context);
|
||||
|
||||
if (context.getActivity().getFrom() == null || StringUtils.isEmpty(context.getActivity().getFrom().getId())) {
|
||||
|
@ -594,7 +615,8 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
* @param connectionName Name of the auth connection to use.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
public CompletableFuture<String> getOauthSignInLink(TurnContextImpl context, String connectionName) {
|
||||
@Override
|
||||
public CompletableFuture<String> getOauthSignInLink(TurnContext context, String connectionName) {
|
||||
BotAssert.contextNotNull(context);
|
||||
if (StringUtils.isEmpty(connectionName)) {
|
||||
throw new IllegalArgumentException("connectionName");
|
||||
|
@ -642,9 +664,15 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
* @param context Context for the current turn of conversation with the user.
|
||||
* @param connectionName Name of the auth connection to use.
|
||||
* @param userId The user id that will be associated with the token.
|
||||
* @param finalRedirect
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
public CompletableFuture<String> getOauthSignInLink(TurnContextImpl context, String connectionName, String userId) {
|
||||
@Override
|
||||
public CompletableFuture<String> getOauthSignInLink(TurnContext context,
|
||||
String connectionName,
|
||||
String userId,
|
||||
String finalRedirect) {
|
||||
|
||||
BotAssert.contextNotNull(context);
|
||||
if (StringUtils.isEmpty(connectionName)) {
|
||||
throw new IllegalArgumentException("connectionName");
|
||||
|
@ -699,7 +727,8 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
* @param connectionName Name of the auth connection to use.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
public CompletableFuture<Void> signOutUser(TurnContextImpl context, String connectionName) {
|
||||
@Override
|
||||
public CompletableFuture<Void> signOutUser(TurnContext context, String connectionName, String userId) {
|
||||
BotAssert.contextNotNull(context);
|
||||
if (StringUtils.isEmpty(connectionName)) {
|
||||
throw new IllegalArgumentException("connectionName");
|
||||
|
@ -708,8 +737,8 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
CompletableFuture<Void> result = new CompletableFuture<>();
|
||||
|
||||
try {
|
||||
ConnectorClient client = getOrCreateConnectorClient(context.getActivity().getServiceUrl());
|
||||
// TODO: signoutUser
|
||||
//ConnectorClient client = getOrCreateConnectorClient(context.getActivity().getServiceUrl());
|
||||
//return client.signOutUser(context.getActivity().getFrom().getId(), connectionName);
|
||||
result.completeExceptionally(new NotImplementedException("signOutUser"));
|
||||
return result;
|
||||
|
@ -724,11 +753,20 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
*
|
||||
* @param context Context for the current turn of conversation with the user.
|
||||
* @param userId The user Id for which token status is retrieved.
|
||||
* @param includeFilter
|
||||
* @return Array of {@link TokenStatus}.
|
||||
*/
|
||||
public CompletableFuture<TokenStatus[]> getTokenStatus(TurnContext context, String userId) {
|
||||
@Override
|
||||
public CompletableFuture<TokenStatus[]> getTokenStatus(TurnContext context, String userId, String includeFilter) {
|
||||
BotAssert.contextNotNull(context);
|
||||
if (StringUtils.isEmpty(userId)) {
|
||||
throw new IllegalArgumentException("userId");
|
||||
}
|
||||
|
||||
// TODO: getTokenStatus
|
||||
throw new NotImplementedException("getTokenStatus");
|
||||
CompletableFuture<TokenStatus[]> result = new CompletableFuture<>();
|
||||
result.completeExceptionally(new NotImplementedException("getTokenStatus"));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -737,13 +775,35 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
* @param context Context for the current turn of conversation with the user.
|
||||
* @param connectionName The name of the Azure Active Directory connection configured with this bot.
|
||||
* @param resourceUrls The list of resource URLs to retrieve tokens for.
|
||||
* @param userId The user Id for which tokens are retrieved. If passing in null the userId is taken
|
||||
* from the Activity in the TurnContext.
|
||||
* @return Map of resourceUrl to the corresponding {@link TokenResponse}.
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<Map<String, TokenResponse>> getAadTokens(TurnContext context,
|
||||
String connectionName,
|
||||
String[] resourceUrls) {
|
||||
String[] resourceUrls,
|
||||
String userId) {
|
||||
BotAssert.contextNotNull(context);
|
||||
if (StringUtils.isEmpty(connectionName)) {
|
||||
throw new IllegalArgumentException("connectionName");
|
||||
}
|
||||
|
||||
if (resourceUrls == null) {
|
||||
throw new IllegalArgumentException("resourceUrls");
|
||||
}
|
||||
|
||||
String effectiveUserId = userId;
|
||||
if (StringUtils.isEmpty(effectiveUserId)) {
|
||||
if (context.getActivity() != null && context.getActivity().getFrom() != null) {
|
||||
effectiveUserId = context.getActivity().getFrom().getId();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: getAadTokens
|
||||
throw new NotImplementedException("getAadTokens");
|
||||
CompletableFuture<Map<String, TokenResponse>> result = new CompletableFuture<>();
|
||||
result.completeExceptionally(new NotImplementedException("getAadTokens"));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -772,11 +832,9 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
MicrosoftAppCredentials credentials,
|
||||
ConversationParameters conversationParameters,
|
||||
BotCallbackHandler callback) {
|
||||
// Validate serviceUrl - can throw
|
||||
// TODO: all these joins are gross
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
//URI uri = new URI(serviceUrl);
|
||||
ConnectorClient connectorClient = null;
|
||||
ConnectorClient connectorClient;
|
||||
try {
|
||||
connectorClient = getOrCreateConnectorClient(serviceUrl, credentials);
|
||||
} catch (Throwable t) {
|
||||
|
@ -795,7 +853,9 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
eventActivity.setId((conversationResourceResponse.getActivityId() != null)
|
||||
? conversationResourceResponse.getActivityId()
|
||||
: UUID.randomUUID().toString());
|
||||
eventActivity.setConversation(new ConversationAccount(conversationResourceResponse.getId()));
|
||||
eventActivity.setConversation(new ConversationAccount(conversationResourceResponse.getId()) {{
|
||||
setTenantId(conversationParameters.getTenantId());
|
||||
}});
|
||||
eventActivity.setRecipient(conversationParameters.getBot());
|
||||
|
||||
TurnContextImpl context = new TurnContextImpl(this, eventActivity);
|
||||
|
@ -807,8 +867,8 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
}};
|
||||
ClaimsIdentity claimsIdentity = new ClaimsIdentity("anonymous", claims);
|
||||
|
||||
context.getTurnState().add(TurnContextStateNames.BOT_IDENTITY, claimsIdentity);
|
||||
context.getTurnState().add(TurnContextStateNames.CONNECTOR_CLIENT, connectorClient);
|
||||
context.getTurnState().add(BOT_IDENTITY_KEY, claimsIdentity);
|
||||
context.getTurnState().add(CONNECTOR_CLIENT_KEY, connectorClient);
|
||||
|
||||
return runPipeline(context, callback).join();
|
||||
}, ExecutorFactory.getExecutor());
|
||||
|
@ -848,7 +908,6 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
}
|
||||
|
||||
if (!StringUtils.isEmpty(reference.getConversation().getTenantId())) {
|
||||
// TODO: Not sure this is doing the same as dotnet. Test.
|
||||
// Putting tenantId in channelData is a temporary solution while we wait for the Teams API to be updated
|
||||
conversationParameters.setChannelData(new Object() {
|
||||
private String tenantId;
|
||||
|
@ -867,29 +926,31 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
* @return An OAuth client for the bot.
|
||||
*/
|
||||
protected CompletableFuture<OAuthClient> createOAuthClient(TurnContext turnContext) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
if (!OAuthClientConfig.emulateOAuthCards
|
||||
&& StringUtils.equalsIgnoreCase(turnContext.getActivity().getChannelId(), Channels.EMULATOR)
|
||||
&& credentialProvider.isAuthenticationDisabled().join()) {
|
||||
if (!OAuthClientConfig.emulateOAuthCards
|
||||
&& StringUtils.equalsIgnoreCase(turnContext.getActivity().getChannelId(), Channels.EMULATOR)
|
||||
&& credentialProvider.isAuthenticationDisabled().join()) {
|
||||
|
||||
OAuthClientConfig.emulateOAuthCards = true;
|
||||
}
|
||||
OAuthClientConfig.emulateOAuthCards = true;
|
||||
}
|
||||
|
||||
ConnectorClient connectorClient = turnContext.getTurnState().get(TurnContextStateNames.CONNECTOR_CLIENT);
|
||||
if (connectorClient == null) {
|
||||
throw new RuntimeException("An ConnectorClient is required in TurnState for this operation.");
|
||||
}
|
||||
ConnectorClient connectorClient = turnContext.getTurnState().get(CONNECTOR_CLIENT_KEY);
|
||||
if (connectorClient == null) {
|
||||
CompletableFuture<OAuthClient> result = new CompletableFuture<>();
|
||||
result.completeExceptionally(
|
||||
new RuntimeException("An ConnectorClient is required in TurnState for this operation."));
|
||||
return result;
|
||||
}
|
||||
|
||||
if (OAuthClientConfig.emulateOAuthCards) {
|
||||
// do not join task - we want this to run in the background.
|
||||
OAuthClient oAuthClient = new RestOAuthClient(
|
||||
turnContext.getActivity().getServiceUrl(), connectorClient.getRestClient().credentials());
|
||||
OAuthClientConfig.sendEmulateOAuthCards(oAuthClient, OAuthClientConfig.emulateOAuthCards);
|
||||
return oAuthClient;
|
||||
}
|
||||
if (OAuthClientConfig.emulateOAuthCards) {
|
||||
// do not join task - we want this to run in the background.
|
||||
OAuthClient oAuthClient = new RestOAuthClient(
|
||||
turnContext.getActivity().getServiceUrl(), connectorClient.getRestClient().credentials());
|
||||
return OAuthClientConfig.sendEmulateOAuthCards(oAuthClient, OAuthClientConfig.emulateOAuthCards)
|
||||
.thenApply(result -> oAuthClient);
|
||||
}
|
||||
|
||||
return new RestOAuthClient(OAuthClientConfig.OAUTHENDPOINT, connectorClient.getRestClient().credentials());
|
||||
});
|
||||
return CompletableFuture.completedFuture(
|
||||
new RestOAuthClient(OAuthClientConfig.OAUTHENDPOINT, connectorClient.getRestClient().credentials()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -922,12 +983,12 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
// For anonymous requests (requests with no header) appId is not set in claims.
|
||||
|
||||
Map.Entry<String, String> botAppIdClaim = claimsIdentity.claims().entrySet().stream()
|
||||
.filter(claim -> claim.getKey() == AuthenticationConstants.AUDIENCE_CLAIM)
|
||||
.filter(claim -> StringUtils.equals(claim.getKey(), AuthenticationConstants.AUDIENCE_CLAIM))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (botAppIdClaim == null) {
|
||||
botAppIdClaim = claimsIdentity.claims().entrySet().stream()
|
||||
.filter(claim -> claim.getKey() == AuthenticationConstants.APPID_CLAIM)
|
||||
.filter(claim -> StringUtils.equals(claim.getKey(), AuthenticationConstants.APPID_CLAIM))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
@ -957,7 +1018,7 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
private ConnectorClient getOrCreateConnectorClient(String serviceUrl, MicrosoftAppCredentials appCredentials)
|
||||
throws MalformedURLException, URISyntaxException {
|
||||
|
||||
RestConnectorClient connectorClient = null;
|
||||
RestConnectorClient connectorClient;
|
||||
if (appCredentials != null) {
|
||||
connectorClient = new RestConnectorClient(
|
||||
new URI(serviceUrl).toURL().toString(), appCredentials);
|
||||
|
@ -989,6 +1050,9 @@ public class BotFrameworkAdapter extends BotAdapter {
|
|||
return CompletableFuture.completedFuture(appCredentialMap.get(appId));
|
||||
}
|
||||
|
||||
// If app credentials were provided, use them as they are the preferred choice moving forward
|
||||
//TODO use AppCredentials
|
||||
|
||||
return credentialProvider.getAppPassword(appId)
|
||||
.thenApply(appPassword -> {
|
||||
MicrosoftAppCredentials appCredentials = new MicrosoftAppCredentials(appId, appPassword);
|
||||
|
|
|
@ -15,17 +15,30 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Reads and writes state for your bot to storage.
|
||||
* Defines a state management object and automates the reading and writing of associated state
|
||||
* properties to a storage layer.
|
||||
*
|
||||
* <p>Each state management object defines a scope for a storage layer. State properties are
|
||||
* created within a state management scope, and the Bot Framework defines these scopes:
|
||||
* {@link ConversationState}, {@link UserState}, and {@link PrivateConversationState}.
|
||||
* You can define additional scopes for your bot.</p>
|
||||
*/
|
||||
public abstract class BotState implements PropertyManager {
|
||||
/**
|
||||
* The key for the state cache.
|
||||
*/
|
||||
private String contextServiceKey;
|
||||
|
||||
/**
|
||||
* The storage layer this state management object will use.
|
||||
*/
|
||||
private Storage storage;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the BotState class.
|
||||
*
|
||||
* @param withStorage The storage provider to use.
|
||||
* @param withContextServiceKey The key for caching on the context services dictionary.
|
||||
* @param withContextServiceKey The key for the state cache for this BotState.
|
||||
*/
|
||||
public BotState(Storage withStorage, String withContextServiceKey) {
|
||||
if (withStorage == null) {
|
||||
|
@ -40,11 +53,12 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a property definition and register it with this BotState.
|
||||
* Creates a named state property within the scope of a BotState and returns
|
||||
* an accessor for the property.
|
||||
*
|
||||
* @param name name of property.
|
||||
* @param <T> type of property.
|
||||
* @return The created state property accessor.
|
||||
* @return A {@link StatePropertyAccessor} for the property.
|
||||
*/
|
||||
public <T extends Object> StatePropertyAccessor<T> createProperty(String name) {
|
||||
if (StringUtils.isEmpty(name)) {
|
||||
|
@ -55,7 +69,7 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Reads in the current state object and caches it in the context object for this turn.
|
||||
* Populates the state cache for this BotState from the storage layer.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
|
@ -68,7 +82,8 @@ public abstract class BotState implements PropertyManager {
|
|||
* Reads in the current state object and caches it in the context object for this turn.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @param force True to bypass the cache.
|
||||
* @param force true to overwrite any existing state cache; or false to load state from
|
||||
* storage only if the cache doesn't already exist.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
public CompletableFuture<Void> load(TurnContext turnContext, boolean force) {
|
||||
|
@ -90,8 +105,7 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* If it has changed, writes to storage the state object that is cached in the current
|
||||
* context object for this turn.
|
||||
* Writes the state cache for this BotState to the storage layer.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
|
@ -101,11 +115,11 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* If it has changed, writes to storage the state object that is cached in the current
|
||||
* context object for this turn.
|
||||
* Writes the state cache for this BotState to the storage layer.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @param force True to save state to storage whether or not there are changes.
|
||||
* @param force true to save the state cache to storage; or false to save state to storage
|
||||
* only if a property in the cache has changed.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
public CompletableFuture<Void> saveChanges(TurnContext turnContext, boolean force) {
|
||||
|
@ -131,7 +145,11 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Clears any state currently stored in this state scope.
|
||||
* Clears the state cache for this BotState.
|
||||
*
|
||||
* <p>This method clears the state cache in the turn context. Call
|
||||
* {@link #saveChanges(TurnContext, boolean)} to persist this
|
||||
* change in the storage layer.</p>
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
|
@ -169,7 +187,7 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the raw cached data from the TurnContext, this can be used for tracing scenarios.
|
||||
* Gets a copy of the raw cached data for this BotState from the turn context.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return A JSON representation of the cached state.
|
||||
|
@ -185,7 +203,8 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* When overridden in a derived class, gets the key to use when reading and writing state to and from storage.
|
||||
* When overridden in a derived class, gets the key to use when reading and writing state to
|
||||
* and from storage.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return The storage key.
|
||||
|
@ -193,12 +212,13 @@ public abstract class BotState implements PropertyManager {
|
|||
public abstract String getStorageKey(TurnContext turnContext);
|
||||
|
||||
/**
|
||||
* Gets a property from the state cache in the turn context.
|
||||
* Gets the value of a property from the state cache for this BotState.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @param propertyName The name of the property to get.
|
||||
* @param <T> The property type.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* @return A task that represents the work queued to execute. If the task is successful, the
|
||||
* result contains the property value.
|
||||
*/
|
||||
protected <T> CompletableFuture<T> getPropertyValue(TurnContext turnContext,
|
||||
String propertyName) {
|
||||
|
@ -215,7 +235,7 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deletes a property from the state cache in the turn context.
|
||||
* Deletes a property from the state cache for this BotState.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @param propertyName The name of the property to delete.
|
||||
|
@ -236,7 +256,7 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the value of a property in the state cache in the turn context.
|
||||
* Sets the value of a property in the state cache for this BotState.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @param propertyName The name of the property to set.
|
||||
|
@ -263,8 +283,19 @@ public abstract class BotState implements PropertyManager {
|
|||
* Internal cached bot state.
|
||||
*/
|
||||
private static class CachedBotState {
|
||||
/**
|
||||
* In memory cache of BotState properties.
|
||||
*/
|
||||
private Map<String, Object> state;
|
||||
|
||||
/**
|
||||
* Used to compute the hash of the state.
|
||||
*/
|
||||
private String hash;
|
||||
|
||||
/**
|
||||
* Object-JsonNode converter.
|
||||
*/
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
public CachedBotState() {
|
||||
|
@ -310,9 +341,9 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements IPropertyAccessor for an IPropertyContainer.
|
||||
* <p>
|
||||
* Note the semantic of this accessor are intended to be lazy, this means teh Get, Set and Delete
|
||||
* Implements StatePropertyAccessor for an PropertyContainer.
|
||||
*
|
||||
* <p>Note the semantic of this accessor are intended to be lazy, this means teh Get, Set and Delete
|
||||
* methods will first call LoadAsync. This will be a no-op if the data is already loaded.
|
||||
* The implication is you can just use this accessor in the application code directly without first calling LoadAsync
|
||||
* this approach works with the AutoSaveStateMiddleware which will save as needed at the end of a turn.
|
||||
|
@ -320,16 +351,30 @@ public abstract class BotState implements PropertyManager {
|
|||
* @param <T> type of value the propertyAccessor accesses.
|
||||
*/
|
||||
private static class BotStatePropertyAccessor<T> implements StatePropertyAccessor<T> {
|
||||
/**
|
||||
* The name of the property.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* The parent BotState.
|
||||
*/
|
||||
private BotState botState;
|
||||
|
||||
/**
|
||||
* StatePropertyAccessor constructor.
|
||||
*
|
||||
* @param withState The parent BotState.
|
||||
* @param withName The property name.
|
||||
*/
|
||||
public BotStatePropertyAccessor(BotState withState, String withName) {
|
||||
botState = withState;
|
||||
name = withName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property value. The semantics are intended to be lazy, note the use of LoadAsync at the start.
|
||||
* Get the property value. The semantics are intended to be lazy, note the use of
|
||||
* {@link BotState#load(TurnContext)} at the start.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @param defaultValueFactory Defines the default value. Invoked when no value been set for the requested
|
||||
|
@ -356,7 +401,8 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Delete the property. The semantics are intended to be lazy, note the use of LoadAsync at the start.
|
||||
* Delete the property. The semantics are intended to be lazy, note the use of
|
||||
* {@link BotState#load(TurnContext)} at the start.
|
||||
*
|
||||
* @param turnContext The turn context.
|
||||
* @return A task that represents the work queued to execute.
|
||||
|
@ -368,7 +414,8 @@ public abstract class BotState implements PropertyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the property value. The semantics are intended to be lazy, note the use of LoadAsync at the start.
|
||||
* Set the property value. The semantics are intended to be lazy, note the use of
|
||||
* {@link BotState#load(TurnContext)} at the start.
|
||||
*
|
||||
* @param turnContext The turn context.
|
||||
* @param value The value to set.
|
||||
|
@ -395,7 +442,6 @@ public abstract class BotState implements PropertyManager {
|
|||
*
|
||||
* @param withName Name of the property.
|
||||
*/
|
||||
@Override
|
||||
public void setName(String withName) {
|
||||
name = withName;
|
||||
}
|
||||
|
|
|
@ -5,17 +5,23 @@ package com.microsoft.bot.builder;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Manages a collection of botState and provides ability to load and save in parallel.
|
||||
*/
|
||||
public class BotStateSet {
|
||||
/**
|
||||
* List of BotStates managed by this BotStateSet.
|
||||
*/
|
||||
private List<BotState> botStates = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the BotStateSet class.
|
||||
*
|
||||
* @param withBotStates vArgs list of {@link BotState} objects to manage.
|
||||
*/
|
||||
public BotStateSet(BotState... withBotStates) {
|
||||
this(Arrays.asList(withBotStates));
|
||||
}
|
||||
|
@ -54,6 +60,10 @@ public class BotStateSet {
|
|||
* @return The updated BotStateSet, so you can fluently call add(BotState) multiple times.
|
||||
*/
|
||||
public BotStateSet add(BotState botState) {
|
||||
if (botState == null) {
|
||||
throw new IllegalArgumentException("botState");
|
||||
}
|
||||
|
||||
botStates.add(botState);
|
||||
return this;
|
||||
}
|
||||
|
@ -76,11 +86,8 @@ public class BotStateSet {
|
|||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
public CompletableFuture<Void> loadAll(TurnContext turnContext, boolean force) {
|
||||
List<CompletableFuture<Void>> loadFutures = botStates.stream()
|
||||
.map(future -> future.load(turnContext, force))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return CompletableFuture.allOf(loadFutures.toArray(new CompletableFuture[loadFutures.size()]));
|
||||
return CompletableFuture.allOf(botStates.stream()
|
||||
.map(future -> future.load(turnContext, force)).toArray(CompletableFuture[]::new));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,10 +108,7 @@ public class BotStateSet {
|
|||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
public CompletableFuture<Void> saveAllChanges(TurnContext turnContext, boolean force) {
|
||||
List<CompletableFuture<Void>> saveFutures = botStates.stream()
|
||||
.map(botState -> botState.saveChanges(turnContext, force))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return CompletableFuture.allOf(saveFutures.toArray(new CompletableFuture[saveFutures.size()]));
|
||||
return CompletableFuture.allOf(botStates.stream()
|
||||
.map(botState -> botState.saveChanges(turnContext, force)).toArray(CompletableFuture[]::new));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ public interface BotTelemetryClient {
|
|||
* @param properties Named string values you can use to classify and search for this availability telemetry.
|
||||
* @param metrics Additional values associated with this availability telemetry.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:ParameterNumber")
|
||||
void trackAvailability(String name,
|
||||
OffsetDateTime timeStamp,
|
||||
Duration duration,
|
||||
|
@ -65,6 +66,7 @@ public interface BotTelemetryClient {
|
|||
* @param resultCode Result code of dependency call execution.
|
||||
* @param success True if the dependency call was handled successfully.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:ParameterNumber")
|
||||
void trackDependency(String dependencyTypeName,
|
||||
String target,
|
||||
String dependencyName,
|
||||
|
|
|
@ -6,16 +6,24 @@ package com.microsoft.bot.builder;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* Handles persistence of a conversation state object using the conversation ID as part of the key.
|
||||
* Defines a state management object for conversation state.
|
||||
*/
|
||||
public class ConversationState extends BotState {
|
||||
/**
|
||||
* Creates a new {@link ConversationState} object.
|
||||
*
|
||||
* @param withStorage The storage layer to use.
|
||||
*/
|
||||
public ConversationState(Storage withStorage) {
|
||||
super(withStorage, ConversationState.class.getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key to use when reading and writing state to and from storage.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @return The storage key.
|
||||
*/
|
||||
@Override
|
||||
public String getStorageKey(TurnContext turnContext) {
|
||||
if (turnContext.getActivity() == null) {
|
||||
|
|
|
@ -15,82 +15,118 @@ import java.util.concurrent.CompletableFuture;
|
|||
* A TurnContext that wraps an untyped inner TurnContext.
|
||||
*/
|
||||
public class DelegatingTurnContext implements TurnContext {
|
||||
/**
|
||||
* The TurnContext being wrapped.
|
||||
*/
|
||||
private TurnContext innerTurnContext;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the DelegatingTurnContext class.
|
||||
* @param withTurnContext The TurnContext to wrap.
|
||||
*/
|
||||
public DelegatingTurnContext(TurnContext withTurnContext) {
|
||||
innerTurnContext = withTurnContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the inner context's activity.
|
||||
* @return The inner {@link TurnContext#getAdapter()}.
|
||||
*/
|
||||
@Override
|
||||
public BotAdapter getAdapter() {
|
||||
return innerTurnContext.getAdapter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the inner context's activity.
|
||||
* @return The inner {@link TurnContext#getTurnState()}.
|
||||
*/
|
||||
@Override
|
||||
public TurnContextStateCollection getTurnState() {
|
||||
return innerTurnContext.getTurnState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the inner context's activity.
|
||||
* @return The inner {@link TurnContext#getActivity()}.
|
||||
*/
|
||||
@Override
|
||||
public Activity getActivity() {
|
||||
return innerTurnContext.getActivity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the inner context's responded value.
|
||||
* @return The inner {@link TurnContext#getResponded()}.
|
||||
*/
|
||||
@Override
|
||||
public boolean getResponded() {
|
||||
return innerTurnContext.getResponded();
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
public CompletableFuture<ResourceResponse> sendActivity(String textReplyToSend) {
|
||||
return innerTurnContext.sendActivity(textReplyToSend);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
public CompletableFuture<ResourceResponse> sendActivity(String textReplyToSend, String speak) {
|
||||
return innerTurnContext.sendActivity(textReplyToSend, speak);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
public CompletableFuture<ResourceResponse> sendActivity(String textReplyToSend, String speak, InputHints inputHint) {
|
||||
public CompletableFuture<ResourceResponse> sendActivity(String textReplyToSend,
|
||||
String speak,
|
||||
InputHints inputHint) {
|
||||
return innerTurnContext.sendActivity(textReplyToSend, speak, inputHint);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
public CompletableFuture<ResourceResponse> sendActivity(Activity activity) {
|
||||
return innerTurnContext.sendActivity(activity);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
public CompletableFuture<ResourceResponse[]> sendActivities(List<Activity> activities) {
|
||||
return innerTurnContext.sendActivities(activities);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
public CompletableFuture<ResourceResponse> updateActivity(Activity activity) {
|
||||
return innerTurnContext.updateActivity(activity);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteActivity(String activityId) {
|
||||
return innerTurnContext.deleteActivity(activityId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteActivity(ConversationReference conversationReference) {
|
||||
return innerTurnContext.deleteActivity(conversationReference);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
public TurnContext onSendActivities(SendActivitiesHandler handler) {
|
||||
return innerTurnContext.onSendActivities(handler);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
public TurnContext onUpdateActivity(UpdateActivityHandler handler) {
|
||||
return innerTurnContext.onUpdateActivity(handler);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:DesignForExtension")
|
||||
@Override
|
||||
public TurnContext onDeleteActivity(DeleteActivityHandler handler) {
|
||||
return innerTurnContext.onDeleteActivity(handler);
|
||||
|
|
|
@ -5,31 +5,59 @@ package com.microsoft.bot.builder;
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Score plus any extra information about an intent.
|
||||
*/
|
||||
public class IntentScore {
|
||||
/**
|
||||
* Confidence in an intent.
|
||||
*/
|
||||
@JsonProperty
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private double score;
|
||||
|
||||
/**
|
||||
* Extra properties to include in the results.
|
||||
*/
|
||||
private HashMap<String, JsonNode> properties = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Gets confidence in an intent.
|
||||
* @return Confidence in an intent.
|
||||
*/
|
||||
public double getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets confidence in an intent.
|
||||
* @param withScore Confidence in an intent.
|
||||
*/
|
||||
public void setScore(double withScore) {
|
||||
score = withScore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets extra properties to include in the results.
|
||||
* @return Any extra properties to include in the results.
|
||||
*/
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets extra properties to include in the results.
|
||||
* @param key The key of the property.
|
||||
* @param value The JsonNode value of the property.
|
||||
*/
|
||||
@JsonAnySetter
|
||||
public void setProperties(String key, JsonNode value) {
|
||||
this.properties.put(key, value);
|
||||
|
|
|
@ -21,18 +21,34 @@ public class InvokeResponse {
|
|||
*/
|
||||
private Object body;
|
||||
|
||||
/**
|
||||
* Gets the HTTP status code for the response.
|
||||
* @return The HTTP status code.
|
||||
*/
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTTP status code for the response.
|
||||
* @param withStatus The HTTP status code.
|
||||
*/
|
||||
public void setStatus(int withStatus) {
|
||||
this.status = withStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the body content for the response.
|
||||
* @return The body content.
|
||||
*/
|
||||
public Object getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the body content for the response.
|
||||
* @param withBody The body content.
|
||||
*/
|
||||
public void setBody(Object withBody) {
|
||||
body = withBody;
|
||||
}
|
||||
|
|
|
@ -16,18 +16,52 @@ import java.util.Map;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* A storage layer that uses an in-memory dictionary.
|
||||
*/
|
||||
public class MemoryStorage implements Storage {
|
||||
/**
|
||||
* Special field for holding the type information for the top level
|
||||
* object being stored.
|
||||
*/
|
||||
private static final String TYPENAMEFORNONENTITY = "__type_name_";
|
||||
private final Object syncroot = new Object();
|
||||
private ObjectMapper objectMapper;
|
||||
private Map<String, JsonNode> memory;
|
||||
private Logger logger = LoggerFactory.getLogger(MemoryStorage.class);
|
||||
private int _eTag = 0;
|
||||
|
||||
/**
|
||||
* Concurrency sync.
|
||||
*/
|
||||
private final Object syncroot = new Object();
|
||||
|
||||
/**
|
||||
* To/From JSON.
|
||||
*/
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
/**
|
||||
* The internal map for storage.
|
||||
*/
|
||||
private Map<String, JsonNode> memory;
|
||||
|
||||
/**
|
||||
* The... ummm... logger.
|
||||
*/
|
||||
private Logger logger = LoggerFactory.getLogger(MemoryStorage.class);
|
||||
|
||||
/**
|
||||
* eTag counter.
|
||||
*/
|
||||
private int eTag = 0;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the MemoryStorage class.
|
||||
*/
|
||||
public MemoryStorage() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the MemoryStorage class.
|
||||
* @param values A pre-existing dictionary to use; or null to use a new one.
|
||||
*/
|
||||
public MemoryStorage(Map<String, JsonNode> values) {
|
||||
objectMapper = new ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
|
@ -37,6 +71,13 @@ public class MemoryStorage implements Storage {
|
|||
memory = values != null ? values : new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads storage items from storage.
|
||||
*
|
||||
* @param keys keys of the items to read
|
||||
* @return A task that represents the work queued to execute. If the activities
|
||||
* are successfully sent, the task result contains the items read, indexed by key.
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<Map<String, Object>> read(String[] keys) {
|
||||
if (keys == null) {
|
||||
|
@ -47,18 +88,14 @@ public class MemoryStorage implements Storage {
|
|||
synchronized (this.syncroot) {
|
||||
for (String key : keys) {
|
||||
if (memory.containsKey(key)) {
|
||||
Object state = memory.get(key);
|
||||
if (state != null) {
|
||||
JsonNode stateNode = memory.get(key);
|
||||
if (stateNode != null) {
|
||||
try {
|
||||
if (!(state instanceof JsonNode))
|
||||
throw new RuntimeException("DictionaryRead failed: entry not JsonNode");
|
||||
|
||||
JsonNode stateNode = (JsonNode) state;
|
||||
|
||||
// Check if type info is set for the class
|
||||
if (!(stateNode.hasNonNull(TYPENAMEFORNONENTITY))) {
|
||||
logger.error("Read failed: Type info not present for " + key);
|
||||
throw new RuntimeException(String.format("Read failed: Type info not present for key " + key));
|
||||
throw new RuntimeException(
|
||||
String.format("Read failed: Type info not present for key " + key));
|
||||
}
|
||||
String clsName = stateNode.get(TYPENAMEFORNONENTITY).textValue();
|
||||
|
||||
|
@ -68,7 +105,8 @@ public class MemoryStorage implements Storage {
|
|||
cls = Class.forName(clsName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.error("Read failed: Could not load class {}", clsName);
|
||||
throw new RuntimeException(String.format("Read failed: Could not load class %s", clsName));
|
||||
throw new RuntimeException(
|
||||
String.format("Read failed: Could not load class %s", clsName));
|
||||
}
|
||||
|
||||
// Populate dictionary
|
||||
|
@ -85,6 +123,12 @@ public class MemoryStorage implements Storage {
|
|||
return CompletableFuture.completedFuture(storeItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes storage items to storage.
|
||||
*
|
||||
* @param changes The items to write, indexed by key.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<Void> write(Map<String, Object> changes) {
|
||||
synchronized (this.syncroot) {
|
||||
|
@ -116,8 +160,8 @@ public class MemoryStorage implements Storage {
|
|||
logger.error(msg);
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
Integer newTag = _eTag++;
|
||||
((ObjectNode) newState).put("eTag", newTag.toString());
|
||||
int newTag = eTag++;
|
||||
((ObjectNode) newState).put("eTag", Integer.toString(newTag));
|
||||
}
|
||||
|
||||
memory.put(change.getKey(), newState);
|
||||
|
@ -127,6 +171,12 @@ public class MemoryStorage implements Storage {
|
|||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes storage items from storage.
|
||||
*
|
||||
* @param keys keys of the items to delete
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<Void> delete(String[] keys) {
|
||||
if (keys == null) {
|
||||
|
|
|
@ -3,11 +3,16 @@
|
|||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.*;
|
||||
import com.microsoft.bot.schema.ActionTypes;
|
||||
import com.microsoft.bot.schema.Activity;
|
||||
import com.microsoft.bot.schema.Attachment;
|
||||
import com.microsoft.bot.schema.AttachmentLayoutTypes;
|
||||
import com.microsoft.bot.schema.CardAction;
|
||||
import com.microsoft.bot.schema.InputHints;
|
||||
import com.microsoft.bot.schema.SuggestedActions;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -131,7 +136,7 @@ public final class MessageFactory {
|
|||
*
|
||||
* @param actions The card actions to include.
|
||||
* @param text Optional, the text of the message to send.
|
||||
* @return
|
||||
* @return A message activity that contains the suggested actions.
|
||||
*/
|
||||
public static Activity suggestedCardActions(List<CardAction> actions, String text) {
|
||||
return suggestedCardActions(actions, text, null, null);
|
||||
|
@ -145,7 +150,7 @@ public final class MessageFactory {
|
|||
* @param ssml Optional, text to be spoken by your bot on a speech-enable channel.
|
||||
* @param inputHint Optional, indicates whether your bot is accepting, expecting, or ignoring user input
|
||||
* after the message is delivered to the client. Default is {@link InputHints#ACCEPTING_INPUT}.
|
||||
* @return
|
||||
* @return A message activity that contains the suggested actions.
|
||||
*/
|
||||
public static Activity suggestedCardActions(List<CardAction> actions,
|
||||
String text,
|
||||
|
@ -158,7 +163,7 @@ public final class MessageFactory {
|
|||
Activity activity = Activity.createMessageActivity();
|
||||
setTextAndSpeech(activity, text, ssml, inputHint);
|
||||
|
||||
activity.setSuggestedActions(new SuggestedActions(actions.toArray(new CardAction[actions.size()])));
|
||||
activity.setSuggestedActions(new SuggestedActions(actions.toArray(new CardAction[0])));
|
||||
|
||||
return activity;
|
||||
}
|
||||
|
@ -282,7 +287,7 @@ public final class MessageFactory {
|
|||
setName(StringUtils.isEmpty(name) ? null : name);
|
||||
}};
|
||||
|
||||
return attachmentActivity(AttachmentLayoutTypes.LIST, Arrays.asList(attachment),
|
||||
return attachmentActivity(AttachmentLayoutTypes.LIST, Collections.singletonList(attachment),
|
||||
text, ssml, inputHint);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,27 +18,26 @@ import java.util.concurrent.CompletableFuture;
|
|||
* <p>For each activity, the adapter calls middleware in the order in which you
|
||||
* added it.</p>
|
||||
*
|
||||
* <example>
|
||||
* This defines middleware that sends "before" and "after" messages
|
||||
* before and after the adapter calls the bot's
|
||||
* {@link Bot#onTurn(TurnContext)} method.
|
||||
* <code>
|
||||
* This defines middleware that sends "before" and "after" messages before and after
|
||||
* the adapter calls the bot's {@link Bot#onTurn(TurnContext)} method.
|
||||
*
|
||||
* {@code
|
||||
* public class SampleMiddleware : Middleware
|
||||
* {
|
||||
* public async Task OnTurn(TurnContext context, MiddlewareSet.NextDelegate next)
|
||||
* {
|
||||
* context.SendActivity("before");
|
||||
* await next().ConfigureAwait(false);
|
||||
* context.SendActivity("after");
|
||||
* public async Task OnTurn(TurnContext context, MiddlewareSet.NextDelegate next)
|
||||
* {
|
||||
* context.SendActivity("before");
|
||||
* await next().ConfigureAwait(false);
|
||||
* context.SendActivity("after");
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
* </example>
|
||||
* {@linkalso Bot}
|
||||
*
|
||||
* {@link Bot}
|
||||
*/
|
||||
public interface Middleware {
|
||||
/**
|
||||
* Processess an incoming activity.
|
||||
* Processes an incoming activity.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @param next The delegate to call to continue the bot middleware pipeline.
|
||||
|
|
|
@ -4,13 +4,17 @@
|
|||
package com.microsoft.bot.builder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Contains an ordered set of {@link Middleware}.
|
||||
*/
|
||||
public class MiddlewareSet implements Middleware {
|
||||
private final ArrayList<Middleware> middleware = new ArrayList<>();
|
||||
/**
|
||||
* List of {@link Middleware} objects this class manages.
|
||||
*/
|
||||
private final List<Middleware> middlewareList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Adds a middleware object to the end of the set.
|
||||
|
@ -20,13 +24,29 @@ public class MiddlewareSet implements Middleware {
|
|||
*/
|
||||
public MiddlewareSet use(Middleware middleware) {
|
||||
BotAssert.middlewareNotNull(middleware);
|
||||
this.middleware.add(middleware);
|
||||
this.middlewareList.add(middleware);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes an incoming activity.
|
||||
*
|
||||
* @param turnContext The context object for this turn.
|
||||
* @param next The delegate to call to continue the bot middleware pipeline.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* Middleware calls the {@code next} delegate to pass control to
|
||||
* the next middleware in the pipeline. If middleware doesn’t call the next delegate,
|
||||
* the adapter does not call any of the subsequent middleware’s request handlers or the
|
||||
* bot’s receive handler, and the pipeline short circuits.
|
||||
* <p>The {@code context} provides information about the
|
||||
* incoming activity, and other data needed to process the activity.</p>
|
||||
* <p>
|
||||
* {@link TurnContext}
|
||||
* {@link com.microsoft.bot.schema.Activity}
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<Void> onTurn(TurnContext context, NextDelegate next) {
|
||||
return receiveActivityInternal(context, null)
|
||||
public CompletableFuture<Void> onTurn(TurnContext turnContext, NextDelegate next) {
|
||||
return receiveActivityInternal(turnContext, null)
|
||||
.thenCompose((result) -> next.next());
|
||||
}
|
||||
|
||||
|
@ -49,7 +69,7 @@ public class MiddlewareSet implements Middleware {
|
|||
BotCallbackHandler callback,
|
||||
int nextMiddlewareIndex) {
|
||||
// Check if we're at the end of the middleware list yet
|
||||
if (nextMiddlewareIndex == middleware.size()) {
|
||||
if (nextMiddlewareIndex == middlewareList.size()) {
|
||||
// If all the Middleware ran, the "leading edge" of the tree is now complete.
|
||||
// This means it's time to run any developer specified callback.
|
||||
// Once this callback is done, the "trailing edge" calls are then completed. This
|
||||
|
@ -68,7 +88,7 @@ public class MiddlewareSet implements Middleware {
|
|||
}
|
||||
|
||||
// Get the next piece of middleware
|
||||
Middleware nextMiddleware = middleware.get(nextMiddlewareIndex);
|
||||
Middleware nextMiddleware = middlewareList.get(nextMiddlewareIndex);
|
||||
|
||||
// Execute the next middleware passing a closure that will recurse back into this method at the
|
||||
// next piece of middleware as the NextDelegate
|
||||
|
|
|
@ -8,13 +8,29 @@ import java.time.OffsetDateTime;
|
|||
import java.util.Map;
|
||||
|
||||
public class NullBotTelemetryClient implements BotTelemetryClient {
|
||||
@SuppressWarnings("checkstyle:ParameterNumber")
|
||||
@Override
|
||||
public void trackAvailability(String name, OffsetDateTime timeStamp, Duration duration, String runLocation, boolean success, String message, Map<String, String> properties, Map<String, Double> metrics) {
|
||||
public void trackAvailability(String name,
|
||||
OffsetDateTime timeStamp,
|
||||
Duration duration,
|
||||
String runLocation,
|
||||
boolean success,
|
||||
String message,
|
||||
Map<String, String> properties,
|
||||
Map<String, Double> metrics) {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:ParameterNumber")
|
||||
@Override
|
||||
public void trackDependency(String dependencyTypeName, String target, String dependencyName, String data, OffsetDateTime startTime, Duration duration, String resultCode, boolean success) {
|
||||
public void trackDependency(String dependencyTypeName,
|
||||
String target,
|
||||
String dependencyName,
|
||||
String data,
|
||||
OffsetDateTime startTime,
|
||||
Duration duration,
|
||||
String resultCode,
|
||||
boolean success) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -23,18 +23,34 @@ public class PagedResult<T> {
|
|||
*/
|
||||
private String continuationToken;
|
||||
|
||||
/**
|
||||
* Gets the page of items.
|
||||
* @return The List of items.
|
||||
*/
|
||||
public List<T> getItems() {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the page of items.
|
||||
* @param value The List of items.
|
||||
*/
|
||||
public void setItems(List<T> value) {
|
||||
this.items = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token for retrieving the next page of results.
|
||||
* @return The Continuation Token to pass to get the next page of results.
|
||||
*/
|
||||
public String getContinuationToken() {
|
||||
return continuationToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the token for retrieving the next page of results.
|
||||
* @param withValue The Continuation Token to pass to get the next page of results.
|
||||
*/
|
||||
public void setContinuationToken(String withValue) {
|
||||
continuationToken = withValue;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,16 @@
|
|||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* PropertyManager defines implementation of a source of named properties.
|
||||
*/
|
||||
public interface PropertyManager {
|
||||
/**
|
||||
* Creates a managed state property accessor for a property.
|
||||
*
|
||||
* @param name The name of the property accessor.
|
||||
* @param <T> The property value type.
|
||||
* @return A state property accessor for the property.
|
||||
*/
|
||||
<T> StatePropertyAccessor<T> createProperty(String name);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,15 @@ package com.microsoft.bot.builder;
|
|||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Interface for Recognizers.
|
||||
*/
|
||||
public interface Recognizer {
|
||||
/**
|
||||
* Runs an utterance through a recognizer and returns a generic recognizer result.
|
||||
*
|
||||
* @param turnContext Turn context.
|
||||
* @return Analysis of utterance.
|
||||
*/
|
||||
CompletableFuture<RecognizerResult> recognize(TurnContext turnContext);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,13 @@
|
|||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* Can convert from a generic recognizer result to a strongly typed one.
|
||||
*/
|
||||
public interface RecognizerConvert {
|
||||
/**
|
||||
* Convert recognizer result.
|
||||
* @param result Result to convert.
|
||||
*/
|
||||
void convert(Object result);
|
||||
}
|
||||
|
|
|
@ -5,23 +5,51 @@ package com.microsoft.bot.builder;
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Contains recognition results generated by an {@link Recognizer}.
|
||||
*/
|
||||
public class RecognizerResult implements RecognizerConvert {
|
||||
@JsonProperty
|
||||
/**
|
||||
* Object with each top-level recognized entity as a key.
|
||||
*/
|
||||
@JsonProperty(value = "entities")
|
||||
JsonNode entities;
|
||||
@JsonProperty
|
||||
|
||||
/**
|
||||
* Original text to recognizer.
|
||||
*/
|
||||
@JsonProperty(value = "text")
|
||||
private String text;
|
||||
@JsonProperty
|
||||
|
||||
/**
|
||||
* Text modified by recognizer.
|
||||
*/
|
||||
@JsonProperty(value = "alteredText")
|
||||
private String alteredText;
|
||||
@JsonProperty
|
||||
|
||||
/**
|
||||
* Mapping from intent to information about the intent.
|
||||
*/
|
||||
@JsonProperty(value = "intents")
|
||||
private Map<String, IntentScore> intents;
|
||||
|
||||
/**
|
||||
* Additional properties.
|
||||
*/
|
||||
private HashMap<String, JsonNode> properties = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Return the top scoring intent and its score.
|
||||
* @return The top scoring intent and score.
|
||||
*/
|
||||
@JsonIgnore
|
||||
public IntentScore getTopScoringIntent() {
|
||||
if (getIntents() == null) {
|
||||
throw new IllegalArgumentException("RecognizerResult.Intents cannot be null");
|
||||
|
@ -38,43 +66,91 @@ public class RecognizerResult implements RecognizerConvert {
|
|||
return topIntent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the input text to recognize.
|
||||
* @return The original text.
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
/**
|
||||
* Sets the input text to recognize.
|
||||
* @param withText The text to recognize.
|
||||
*/
|
||||
public void setText(String withText) {
|
||||
text = withText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the input text as modified by the recognizer, for example for spelling correction.
|
||||
* @return Text modified by recognizer.
|
||||
*/
|
||||
public String getAlteredText() {
|
||||
return alteredText;
|
||||
}
|
||||
|
||||
public void setAlteredText(String alteredText) {
|
||||
this.alteredText = alteredText;
|
||||
/**
|
||||
* Sets the input text as modified by the recognizer, for example for spelling correction.
|
||||
* @param withAlteredText Text modified by recognizer.
|
||||
*/
|
||||
public void setAlteredText(String withAlteredText) {
|
||||
alteredText = withAlteredText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recognized intents, with the intent as key and the confidence as value.
|
||||
* @return Mapping from intent to information about the intent.
|
||||
*/
|
||||
public Map<String, IntentScore> getIntents() {
|
||||
return intents;
|
||||
}
|
||||
|
||||
public void setIntents(Map<String, IntentScore> intents) {
|
||||
this.intents = intents;
|
||||
/**
|
||||
* Sets the recognized intents, with the intent as key and the confidence as value.
|
||||
* @param withIntents Mapping from intent to information about the intent.
|
||||
*/
|
||||
public void setIntents(Map<String, IntentScore> withIntents) {
|
||||
intents = withIntents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recognized top-level entities.
|
||||
* @return Object with each top-level recognized entity as a key.
|
||||
*/
|
||||
public JsonNode getEntities() {
|
||||
return entities;
|
||||
}
|
||||
|
||||
public void setEntities(JsonNode entities) {
|
||||
this.entities = entities;
|
||||
/**
|
||||
* Sets the recognized top-level entities.
|
||||
* @param withEntities Object with each top-level recognized entity as a key.
|
||||
*/
|
||||
public void setEntities(JsonNode withEntities) {
|
||||
entities = withEntities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets properties that are not otherwise defined by the RecognizerResult type but that
|
||||
* might appear in the REST JSON object.
|
||||
* @return The extended properties for the object.
|
||||
*/
|
||||
@JsonAnyGetter
|
||||
public Map<String, JsonNode> getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets properties that are not otherwise defined by the RecognizerResult type but that
|
||||
* might appear in the REST JSON object.
|
||||
*
|
||||
* <p>With this, properties not represented in the defined type are not dropped when
|
||||
* the JSON object is deserialized, but are instead stored in this property. Such properties
|
||||
* will be written to a JSON object when the instance is serialized.</p>
|
||||
*
|
||||
* @param key The property key.
|
||||
* @param value The property value.
|
||||
*/
|
||||
@JsonAnySetter
|
||||
public void setProperties(String key, JsonNode value) {
|
||||
this.properties.put(key, value);
|
||||
|
|
|
@ -3,19 +3,49 @@
|
|||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* This enumeration is used by TrackTrace to identify severity level.
|
||||
*/
|
||||
public enum Severity {
|
||||
/**
|
||||
* Verbose severity level.
|
||||
*/
|
||||
VERBOSE(0),
|
||||
|
||||
/**
|
||||
* Information severity level.
|
||||
*/
|
||||
INFORMATION(1),
|
||||
|
||||
/**
|
||||
* Warning severity level.
|
||||
*/
|
||||
WARNING(2),
|
||||
|
||||
/**
|
||||
* Error severity level.
|
||||
*/
|
||||
ERROR(3),
|
||||
|
||||
/**
|
||||
* Critical severity level.
|
||||
*/
|
||||
CRITICAL(4);
|
||||
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* Constructs with an in value.
|
||||
* @param witValue
|
||||
*/
|
||||
Severity(int witValue) {
|
||||
value = witValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* For converion to int.
|
||||
* @return The int value of this enum.
|
||||
*/
|
||||
public int getSeverity() {
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -6,14 +6,40 @@ package com.microsoft.bot.builder;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Interface which defines methods for how you can get data from a property source such as BotState.
|
||||
* @param <T> type of the property.
|
||||
*/
|
||||
public interface StatePropertyAccessor<T> extends StatePropertyInfo {
|
||||
/**
|
||||
* Get the property value from the source.
|
||||
* @param turnContext TurnContext.
|
||||
* @return A task representing the result of the asynchronous operation.
|
||||
*/
|
||||
default CompletableFuture<T> get(TurnContext turnContext) {
|
||||
return get(turnContext, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property value from the source.
|
||||
* @param turnContext TurnContext.
|
||||
* @param defaultValueFactory Function which defines the property value to be returned if no value has been set.
|
||||
* @return A task representing the result of the asynchronous operation.
|
||||
*/
|
||||
CompletableFuture<T> get(TurnContext turnContext, Supplier<T> defaultValueFactory);
|
||||
|
||||
/**
|
||||
* Delete the property from the source.
|
||||
* @param turnContext TurnContext.
|
||||
* @return A task representing the result of the asynchronous operation.
|
||||
*/
|
||||
CompletableFuture<Void> delete(TurnContext turnContext);
|
||||
|
||||
/**
|
||||
* Set the property value on the source.
|
||||
* @param turnContext TurnContext.
|
||||
* @param value The value to set.
|
||||
* @return A task representing the result of the asynchronous operation.
|
||||
*/
|
||||
CompletableFuture<Void> set(TurnContext turnContext, T value);
|
||||
}
|
||||
|
|
|
@ -3,8 +3,13 @@
|
|||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
/**
|
||||
* This is metadata about the property including policy info.
|
||||
*/
|
||||
public interface StatePropertyInfo {
|
||||
/**
|
||||
* Gets the name of the property.
|
||||
* @return The name of the property.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
void setName(String withName);
|
||||
}
|
||||
|
|
|
@ -6,26 +6,32 @@ package com.microsoft.bot.builder;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Defines the interface for a storage layer.
|
||||
*/
|
||||
public interface Storage {
|
||||
/**
|
||||
* Read StoreItems from storage
|
||||
* Reads storage items from storage.
|
||||
*
|
||||
* @param keys keys of the storeItems to read
|
||||
* @return StoreItem dictionary
|
||||
* @param keys keys of the items to read
|
||||
* @return A task that represents the work queued to execute. If the activities
|
||||
* are successfully sent, the task result contains the items read, indexed by key.
|
||||
*/
|
||||
CompletableFuture<Map<String, Object>> read(String[] keys);
|
||||
|
||||
/**
|
||||
* Write StoreItems to storage
|
||||
* Writes storage items to storage.
|
||||
*
|
||||
* @param changes
|
||||
* @param changes The items to write, indexed by key.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
CompletableFuture<Void> write(Map<String, Object> changes);
|
||||
|
||||
/**
|
||||
* Delete StoreItems from storage
|
||||
* Deletes storage items from storage.
|
||||
*
|
||||
* @param keys keys of the storeItems to delete
|
||||
* @param keys keys of the items to delete
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
CompletableFuture<Void> delete(String[] keys);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,10 @@ public class TelemetryLoggerMiddleware implements Middleware {
|
|||
logPersonalInformation = withLogPersonalInformation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently configured BotTelemetryClient that logs the event.
|
||||
* @return The {@link BotTelemetryClient} being used to log events.
|
||||
*/
|
||||
public BotTelemetryClient getTelemetryClient() {
|
||||
return telemetryClient;
|
||||
}
|
||||
|
@ -46,7 +50,7 @@ public class TelemetryLoggerMiddleware implements Middleware {
|
|||
*
|
||||
* @param context The context object for this turn.
|
||||
* @param next The delegate to call to continue the bot middleware pipeline.
|
||||
* @return
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<Void> onTurn(TurnContext context, NextDelegate next) {
|
||||
|
@ -67,7 +71,8 @@ public class TelemetryLoggerMiddleware implements Middleware {
|
|||
|
||||
// hook up update activity pipeline
|
||||
context.onUpdateActivity((updateContext, updateActivity, updateNext) -> updateNext.get()
|
||||
.thenCombine(onUpdateActivity(updateActivity), (resourceResponse, updateResult) -> resourceResponse));
|
||||
.thenCombine(
|
||||
onUpdateActivity(updateActivity), (resourceResponse, updateResult) -> resourceResponse));
|
||||
|
||||
// hook up delete activity pipeline
|
||||
context.onDeleteActivity((deleteContext, deleteReference, deleteNext) -> deleteNext.get()
|
||||
|
|
|
@ -20,7 +20,7 @@ public class TranscriptInfo {
|
|||
/**
|
||||
* Date conversation was started.
|
||||
*/
|
||||
private OffsetDateTime created = OffsetDateTime.now();
|
||||
private OffsetDateTime created;
|
||||
|
||||
public TranscriptInfo(String withId, String withChannelId, OffsetDateTime withCreated) {
|
||||
id = withId;
|
||||
|
@ -28,27 +28,51 @@ public class TranscriptInfo {
|
|||
created = withCreated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ID of the channel in which the conversation occurred.
|
||||
* @return The ID of the channel in which the conversation occurred.
|
||||
*/
|
||||
public String channelId() {
|
||||
return this.channelId;
|
||||
return channelId;
|
||||
}
|
||||
|
||||
public void setChannelId(String withValue) {
|
||||
channelId = withValue;
|
||||
/**
|
||||
* Sets the ID of the channel in which the conversation occurred.
|
||||
* @param withChannelId The ID of the channel in which the conversation occurred.
|
||||
*/
|
||||
public void setChannelId(String withChannelId) {
|
||||
channelId = withChannelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ID of the conversation.
|
||||
* @return The ID of the conversation.
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String witValue) {
|
||||
id = witValue;
|
||||
/**
|
||||
* Sets the ID of the conversation.
|
||||
* @param withId The ID of the conversation.
|
||||
*/
|
||||
public void setId(String withId) {
|
||||
id = withId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the date the conversation began.
|
||||
* @return The date then conversation began.
|
||||
*/
|
||||
public OffsetDateTime getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(OffsetDateTime withValue) {
|
||||
created = withValue;
|
||||
/**
|
||||
* Sets the date the conversation began.
|
||||
* @param withCreated The date then conversation began.
|
||||
*/
|
||||
public void setCreated(OffsetDateTime withCreated) {
|
||||
created = withCreated;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,16 +25,26 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||
*/
|
||||
public class TranscriptLoggerMiddleware implements Middleware {
|
||||
private static final Logger logger = LoggerFactory.getLogger(TranscriptLoggerMiddleware.class);
|
||||
// https://github.com/FasterXML/jackson-databind/wiki/Serialization-Features
|
||||
|
||||
/**
|
||||
* To/From JSON.
|
||||
*/
|
||||
private static ObjectMapper mapper;
|
||||
|
||||
static {
|
||||
mapper = new ObjectMapper()
|
||||
.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
mapper.findAndRegisterModules();
|
||||
.enable(SerializationFeature.INDENT_OUTPUT)
|
||||
.findAndRegisterModules();
|
||||
}
|
||||
|
||||
/**
|
||||
* The TranscriptLogger to log to.
|
||||
*/
|
||||
private TranscriptLogger transcriptLogger;
|
||||
|
||||
/**
|
||||
* Activity queue.
|
||||
*/
|
||||
private Queue<Activity> transcript = new ConcurrentLinkedQueue<Activity>();
|
||||
|
||||
/**
|
||||
|
@ -52,11 +62,11 @@ public class TranscriptLoggerMiddleware implements Middleware {
|
|||
}
|
||||
|
||||
/**
|
||||
* initialization for middleware turn.
|
||||
* Records incoming and outgoing activities to the conversation store.
|
||||
*
|
||||
* @param context
|
||||
* @param next
|
||||
* @return
|
||||
* @param context The context object for this turn.
|
||||
* @param next The delegate to call to continue the bot middleware pipeline.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<Void> onTurn(TurnContext context, NextDelegate next) {
|
||||
|
|
|
@ -31,7 +31,7 @@ public interface TranscriptStore extends TranscriptLogger {
|
|||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation.
|
||||
* @param continuationToken
|
||||
* @param continuationToken The continuation token (if available).
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the task completes successfully, the result contains the matching activities.
|
||||
*/
|
||||
|
@ -46,7 +46,7 @@ public interface TranscriptStore extends TranscriptLogger {
|
|||
*
|
||||
* @param channelId The ID of the channel the conversation is in.
|
||||
* @param conversationId The ID of the conversation.
|
||||
* @param continuationToken
|
||||
* @param continuationToken The continuation token (if available).
|
||||
* @param startDate A cutoff date. Activities older than this date are not included.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the task completes successfully, the result contains the matching activities.
|
||||
|
@ -70,7 +70,7 @@ public interface TranscriptStore extends TranscriptLogger {
|
|||
* Gets the conversations on a channel from the store.
|
||||
*
|
||||
* @param channelId The ID of the channel.
|
||||
* @param continuationToken
|
||||
* @param continuationToken The continuation token (if available).
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
CompletableFuture<PagedResult<TranscriptInfo>> listTranscripts(String channelId, String continuationToken);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
import com.microsoft.bot.schema.Activity;
|
||||
|
@ -12,11 +13,13 @@ import java.util.concurrent.CompletableFuture;
|
|||
|
||||
/**
|
||||
* Provides context for a turn of a bot.
|
||||
* Context provides information needed to process an incoming activity.
|
||||
*
|
||||
* <p>Context provides information needed to process an incoming activity.
|
||||
* The context object is created by a {@link BotAdapter} and persists for the
|
||||
* length of the turn.
|
||||
* {@linkalso Bot}
|
||||
* {@linkalso Middleware}
|
||||
* length of the turn.</p>
|
||||
*
|
||||
* {@link Bot}
|
||||
* {@link Middleware}
|
||||
*/
|
||||
public interface TurnContext {
|
||||
/**
|
||||
|
@ -42,66 +45,80 @@ public interface TurnContext {
|
|||
return turnContext.sendActivity(turnContext.getActivity().createTrace(name, value, valueType, label));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the bot adapter that created this context object.
|
||||
* @return The bot adapter that created this context object.
|
||||
*/
|
||||
BotAdapter getAdapter();
|
||||
|
||||
/**
|
||||
* Gets the services registered on this context object.
|
||||
* Gets the collection of values cached with the context object for the lifetime of the turn.
|
||||
* @return The collection of services registered on this context object.
|
||||
*/
|
||||
TurnContextStateCollection getTurnState();
|
||||
|
||||
/**
|
||||
* Incoming request
|
||||
* Gets the activity for this turn of the bot.
|
||||
* @return The activity for this turn of the bot.
|
||||
*/
|
||||
Activity getActivity();
|
||||
|
||||
/**
|
||||
* Indicates whether at least one response was sent for the current turn.
|
||||
*
|
||||
* @return {@code true} if at least one response was sent for the current turn.
|
||||
* Gets a value indicating whether at least one response was sent for the current turn.
|
||||
* @return {@code true} if at least one response was sent for the current turn; otherwise, {@code false}.
|
||||
*/
|
||||
boolean getResponded();
|
||||
|
||||
/**
|
||||
* Sends a message activity to the sender of the incoming activity.
|
||||
*
|
||||
* @param textReplyToSend The text of the message to send.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* <p>If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* channel assigned to the activity.</p>
|
||||
*
|
||||
* <p>See the channel's documentation for limits imposed upon the contents of
|
||||
* {@code textReplyToSend}.</p>
|
||||
* <p>To control various characteristics of your bot's speech such as voice,
|
||||
* rate, volume, pronunciation, and pitch, specify {@code speak} in
|
||||
* Speech Synthesis Markup Language (SSML) format.</p>
|
||||
*
|
||||
* @param textReplyToSend The text of the message to send.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
CompletableFuture<ResourceResponse> sendActivity(String textReplyToSend);
|
||||
|
||||
/**
|
||||
* Sends a message activity to the sender of the incoming activity.
|
||||
*
|
||||
* <p>If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.</p>
|
||||
*
|
||||
* <p>See the channel's documentation for limits imposed upon the contents of
|
||||
* {@code textReplyToSend}.</p>
|
||||
*
|
||||
* <p>To control various characteristics of your bot's speech such as voice,
|
||||
* rate, volume, pronunciation, and pitch, specify {@code speak} in
|
||||
* Speech Synthesis Markup Language (SSML) format.</p>
|
||||
*
|
||||
* @param textReplyToSend The text of the message to send.
|
||||
* @param speak Optional, text to be spoken by your bot on a speech-enabled
|
||||
* channel.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* <p>See the channel's documentation for limits imposed upon the contents of
|
||||
* {@code textReplyToSend}.</p>
|
||||
* <p>To control various characteristics of your bot's speech such as voice,
|
||||
* rate, volume, pronunciation, and pitch, specify {@code speak} in
|
||||
* Speech Synthesis Markup Language (SSML) format.</p>
|
||||
*/
|
||||
CompletableFuture<ResourceResponse> sendActivity(String textReplyToSend, String speak);
|
||||
|
||||
/**
|
||||
* Sends a message activity to the sender of the incoming activity.
|
||||
*
|
||||
* <p>If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.</p>
|
||||
*
|
||||
* <p>See the channel's documentation for limits imposed upon the contents of
|
||||
* {@code textReplyToSend}.</p>
|
||||
*
|
||||
* <p>To control various characteristics of your bot's speech such as voice,
|
||||
* rate, volume, pronunciation, and pitch, specify {@code speak} in
|
||||
* Speech Synthesis Markup Language (SSML) format.</p>
|
||||
*
|
||||
* @param textReplyToSend The text of the message to send.
|
||||
* @param speak Optional, text to be spoken by your bot on a speech-enabled
|
||||
* channel.
|
||||
|
@ -110,14 +127,6 @@ public interface TurnContext {
|
|||
* One of: "acceptingInput", "ignoringInput", or "expectingInput".
|
||||
* Default is "acceptingInput".
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* <p>See the channel's documentation for limits imposed upon the contents of
|
||||
* {@code textReplyToSend}.</p>
|
||||
* <p>To control various characteristics of your bot's speech such as voice,
|
||||
* rate, volume, pronunciation, and pitch, specify {@code speak} in
|
||||
* Speech Synthesis Markup Language (SSML) format.</p>
|
||||
*/
|
||||
CompletableFuture<ResourceResponse> sendActivity(String textReplyToSend, String speak, InputHints inputHint);
|
||||
|
||||
|
@ -133,26 +142,29 @@ public interface TurnContext {
|
|||
CompletableFuture<ResourceResponse> sendActivity(Activity activity);
|
||||
|
||||
/**
|
||||
* Sends a set of activities to the sender of the incoming activity.
|
||||
* Sends a list of activities to the sender of the incoming activity.
|
||||
*
|
||||
* <p>If the activities are successfully sent, the task result contains
|
||||
* an array of {@link ResourceResponse} objects containing the IDs that
|
||||
* the receiving channel assigned to the activities.</p>
|
||||
*
|
||||
* @param activities The activities to send.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activities are successfully sent, the task result contains
|
||||
* an array of {@link ResourceResponse} objects containing the IDs that
|
||||
* the receiving channel assigned to the activities.
|
||||
*/
|
||||
CompletableFuture<ResourceResponse[]> sendActivities(List<Activity> activities);
|
||||
|
||||
/**
|
||||
* Replaces an existing activity.
|
||||
*
|
||||
* @param withActivity New replacement activity.
|
||||
* @return A task that represents the work queued to execute.
|
||||
* If the activity is successfully sent, the task result contains
|
||||
* <p>If the activity is successfully sent, the task result contains
|
||||
* a {@link ResourceResponse} object containing the ID that the receiving
|
||||
* channel assigned to the activity.
|
||||
* channel assigned to the activity.</p>
|
||||
*
|
||||
* <p>Before calling this, set the ID of the replacement activity to the ID
|
||||
* of the activity to replace.</p>
|
||||
*
|
||||
* @param withActivity New replacement activity.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
CompletableFuture<ResourceResponse> updateActivity(Activity withActivity);
|
||||
|
||||
|
@ -177,35 +189,38 @@ public interface TurnContext {
|
|||
/**
|
||||
* Adds a response handler for send activity operations.
|
||||
*
|
||||
* <p>When the context's {@link #sendActivity(Activity)}
|
||||
* or {@link #sendActivities(List)} methods are called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.</p>
|
||||
*
|
||||
* @param handler The handler to add to the context object.
|
||||
* @return The updated context object.
|
||||
* When the context's {@link #sendActivity(Activity)}
|
||||
* or {@link #sendActivities(List<Activity>)} methods are called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.
|
||||
*/
|
||||
TurnContext onSendActivities(SendActivitiesHandler handler);
|
||||
|
||||
/**
|
||||
* Adds a response handler for update activity operations.
|
||||
*
|
||||
* <p>When the context's {@link #updateActivity(Activity)} is called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.</p>
|
||||
*
|
||||
* @param handler The handler to add to the context object.
|
||||
* @return The updated context object.
|
||||
* When the context's {@link #updateActivity(Activity)} is called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.
|
||||
*/
|
||||
TurnContext onUpdateActivity(UpdateActivityHandler handler);
|
||||
|
||||
/**
|
||||
* Adds a response handler for delete activity operations.
|
||||
*
|
||||
* <p>When the context's {@link #deleteActivity(String)} is called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.</p>
|
||||
*
|
||||
* @param handler The handler to add to the context object.
|
||||
* @return The updated context object.
|
||||
* @throws NullPointerException {@code handler} is {@code null}.
|
||||
* When the context's {@link #deleteActivity(String)} is called,
|
||||
* the adapter calls the registered handlers in the order in which they were
|
||||
* added to the context object.
|
||||
*/
|
||||
TurnContext onDeleteActivity(DeleteActivityHandler handler);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,13 @@ public class TurnContextStateCollection implements AutoCloseable {
|
|||
return get(type.getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a value to the turn's context.
|
||||
* @param key The name of the value.
|
||||
* @param value The value to add.
|
||||
* @param <T> The type of the value.
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public <T> void add(String key, T value) throws IllegalArgumentException {
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("key");
|
||||
|
@ -69,10 +76,19 @@ public class TurnContextStateCollection implements AutoCloseable {
|
|||
add(value.getClass().getSimpleName(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a value.
|
||||
* @param key The name of the value to remove.
|
||||
*/
|
||||
public void remove(String key) {
|
||||
state.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a value.
|
||||
* @param key The name of the value to replace.
|
||||
* @param value The new value.
|
||||
*/
|
||||
public void replace(String key, Object value) {
|
||||
state.remove(key);
|
||||
add(key, value);
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder;
|
||||
|
||||
public final class TurnContextStateNames {
|
||||
public static final String BOT_IDENTITY = "BotIdentity";
|
||||
public static final String CONNECTOR_CLIENT = "ConnectorClient";
|
||||
|
||||
private TurnContextStateNames() {
|
||||
|
||||
}
|
||||
}
|
|
@ -19,8 +19,8 @@ public interface UserTokenProvider {
|
|||
* @return Token Response.
|
||||
*/
|
||||
CompletableFuture<TokenResponse> getUserToken(TurnContext turnContext,
|
||||
String connectionName,
|
||||
String magicCode);
|
||||
String connectionName,
|
||||
String magicCode);
|
||||
|
||||
/**
|
||||
* Get the raw signin link to be sent to the user for signin for a connection name.
|
||||
|
@ -30,9 +30,7 @@ public interface UserTokenProvider {
|
|||
* @return A task that represents the work queued to execute. If the task completes successfully,
|
||||
* the result contains the raw signin link.
|
||||
*/
|
||||
default CompletableFuture<String> getOauthSignInLink(TurnContext turnContext, String connectionName) {
|
||||
return getOauthSignInLink(turnContext, connectionName, null, null);
|
||||
}
|
||||
CompletableFuture<String> getOauthSignInLink(TurnContext turnContext, String connectionName);
|
||||
|
||||
/**
|
||||
* Get the raw signin link to be sent to the user for signin for a connection name.
|
||||
|
@ -45,9 +43,9 @@ public interface UserTokenProvider {
|
|||
* the result contains the raw signin link.
|
||||
*/
|
||||
CompletableFuture<String> getOauthSignInLink(TurnContext turnContext,
|
||||
String connectionName,
|
||||
String userId,
|
||||
String finalRedirect);
|
||||
String connectionName,
|
||||
String userId,
|
||||
String finalRedirect);
|
||||
|
||||
/**
|
||||
* Signs the user out with the token server.
|
||||
|
@ -100,8 +98,8 @@ public interface UserTokenProvider {
|
|||
* @return Dictionary of resourceUrl to the corresponding TokenResponse.
|
||||
*/
|
||||
default CompletableFuture<Map<String, TokenResponse>> getAadTokens(TurnContext turnContext,
|
||||
String connectionName,
|
||||
String[] resourceUrls) {
|
||||
String connectionName,
|
||||
String[] resourceUrls) {
|
||||
return getAadTokens(turnContext, connectionName, resourceUrls, null);
|
||||
}
|
||||
|
||||
|
@ -116,7 +114,7 @@ public interface UserTokenProvider {
|
|||
* @return Dictionary of resourceUrl to the corresponding TokenResponse.
|
||||
*/
|
||||
CompletableFuture<Map<String, TokenResponse>> getAadTokens(TurnContext turnContext,
|
||||
String connectionName,
|
||||
String[] resourceUrls,
|
||||
String userId);
|
||||
String connectionName,
|
||||
String[] resourceUrls,
|
||||
String userId);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package com.microsoft.bot.builder.integration;
|
||||
|
||||
import com.microsoft.bot.builder.BotCallbackHandler;
|
||||
import com.microsoft.bot.builder.InvokeResponse;
|
||||
import com.microsoft.bot.schema.Activity;
|
||||
import com.microsoft.bot.schema.ConversationReference;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* An interface that defines the contract between web service integration pieces and the bot adapter.
|
||||
*/
|
||||
public interface AdapterIntegration {
|
||||
/**
|
||||
* Creates a turn context and runs the middleware pipeline for an incoming activity.
|
||||
*
|
||||
* @param authHeader The HTTP authentication header of the request.
|
||||
* @param activity The incoming activity.
|
||||
* @param callback The code to run at the end of the adapter's middleware pipeline.
|
||||
* @return A task that represents the work queued to execute. If the activity type
|
||||
* was 'Invoke' and the corresponding key (channelId + activityId) was found
|
||||
* then an InvokeResponse is returned, otherwise null is returned.
|
||||
*/
|
||||
CompletableFuture<InvokeResponse> processActivity(
|
||||
String authHeader,
|
||||
Activity activity,
|
||||
BotCallbackHandler callback);
|
||||
|
||||
/**
|
||||
* Sends a proactive message to a conversation.
|
||||
*
|
||||
* <p>Call this method to proactively send a message to a conversation.
|
||||
* Most _channels require a user to initiate a conversation with a bot
|
||||
* before the bot can send activities to the user.</p>
|
||||
*
|
||||
* @param botId The application ID of the bot. This parameter is ignored in single tenant
|
||||
* the Adapters (Console, Test, etc) but is critical to the BotFrameworkAdapter
|
||||
* which is multi-tenant aware.
|
||||
* @param reference A reference to the conversation to continue.
|
||||
* @param callback The method to call for the resulting bot turn.
|
||||
* @return A task that represents the work queued to execute.
|
||||
*/
|
||||
CompletableFuture<Void> continueConversation(
|
||||
String botId,
|
||||
ConversationReference reference,
|
||||
BotCallbackHandler callback);
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for
|
||||
* license information.
|
||||
*/
|
||||
|
||||
package com.microsoft.bot.schema;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ConversationReferenceHelper {
|
||||
private ConversationReference reference;
|
||||
|
||||
public ConversationReferenceHelper(ConversationReference withReference) {
|
||||
this.reference = withReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link Activity} from conversation reference as it is posted to bot.
|
||||
*/
|
||||
public Activity getPostToBotMessage() {
|
||||
Activity activity = new Activity();
|
||||
activity.setType(ActivityTypes.MESSAGE);
|
||||
activity.setId(UUID.randomUUID().toString());
|
||||
activity.setRecipient(new ChannelAccount(
|
||||
reference.getBot().getId(),
|
||||
reference.getBot().getName()));
|
||||
activity.setChannelId(reference.getChannelId());
|
||||
activity.setServiceUrl(reference.getServiceUrl());
|
||||
activity.setConversation(new ConversationAccount(
|
||||
reference.getConversation().isGroup(),
|
||||
reference.getConversation().getId(),
|
||||
reference.getConversation().getName()));
|
||||
activity.setFrom(new ChannelAccount(
|
||||
reference.getUser().getId(),
|
||||
reference.getUser().getName()));
|
||||
|
||||
return activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link Activity} from conversation reference that can be posted to user as reply.
|
||||
*/
|
||||
public Activity getPostToUserMessage() {
|
||||
Activity msg = this.getPostToBotMessage();
|
||||
|
||||
// swap from and recipient
|
||||
msg.setFrom(msg.getRecipient());
|
||||
msg.setRecipient(msg.getFrom());
|
||||
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче