/// <summary> /// Invoked when the user opens the Messaging Extension or searching any content in it. /// </summary> /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param> /// <param name="query">Contains Messaging Extension query keywords.</param> /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param> /// <returns>Messaging extension response object to fill compose extension section.</returns> /// <remarks> /// https://docs.microsoft.com/en-us/dotnet/api/microsoft.bot.builder.teams.teamsactivityhandler.onteamsmessagingextensionqueryasync?view=botbuilder-dotnet-stable. /// </remarks> protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync( ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { try { turnContext = turnContext ?? throw new ArgumentNullException(nameof(turnContext)); this.RecordEvent(nameof(this.OnTeamsMessagingExtensionQueryAsync), turnContext); var activity = turnContext.Activity; var messagingExtensionQuery = JsonConvert.DeserializeObject <MessagingExtensionQuery>(activity.Value.ToString()); var searchQuery = this.messagingExtensionHelper.GetSearchResult(messagingExtensionQuery); return(new MessagingExtensionResponse { ComposeExtension = await this.messagingExtensionHelper.GetTeamPostSearchResultAsync(searchQuery, messagingExtensionQuery.CommandId, activity.From.AadObjectId, messagingExtensionQuery.QueryOptions.Count, messagingExtensionQuery.QueryOptions.Skip), }); } catch (Exception ex) { this.logger.LogError(ex, $"Failed to handle the Messaging Extension command {turnContext.Activity.Name}: {ex.Message}"); throw; } }
/// <inheritdoc/> protected override Task <MessagingExtensionResponse> OnTeamsMessagingExtensionConfigurationQuerySettingUrlAsync( ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { var openSettingAction = new CardAction { Type = ActionTypes.OpenUrl, Value = $"{this.appSettings.BaseUrl}/mesettings", }; // ME Result. var result = new MessagingExtensionResult { Type = "config", SuggestedActions = new MessagingExtensionSuggestedAction { Actions = new List <CardAction> { openSettingAction }, }, }; // ME response. var response = new MessagingExtensionResponse() { ComposeExtension = result, }; return(Task.FromResult(response)); }
/// <summary> /// Open the Messaging Extension Configuration Page /// </summary> /// <param name="turnContext">The turn context.</param> /// <param name="query">The matched url.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A Task resolving to the settings / logout page </returns> /// <remarks> /// For more information on Link Unfurling see the documentation /// https://docs.microsoft.com/en-us/microsoftteams/platform/messaging-extensions/how-to/link-unfurling?tabs=dotnet /// </remarks> protected override Task <MessagingExtensionResponse> OnTeamsMessagingExtensionConfigurationQuerySettingUrlAsync( ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { var messagingExtensionReponse = new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Type = "config", SuggestedActions = new MessagingExtensionSuggestedAction { Actions = new List <CardAction> { new CardAction { Type = ActionTypes.OpenUrl, Value = this.options.Value.SettingsPageUrl, }, }, }, }, }; return(Task.FromResult(messagingExtensionReponse)); }
public void MessagingExtensionQueryInitsWithNoArgs() { var msgExtQuery = new MessagingExtensionQuery(); Assert.NotNull(msgExtQuery); Assert.IsType <MessagingExtensionQuery>(msgExtQuery); }
/// <summary> /// Gets the search result asynchronously. /// </summary> /// <param name="query">The invoke query object</param> /// <returns>Messaging extension result.</returns> public async Task <MessagingExtensionResult> GetSearchResultAsync(MessagingExtensionQuery query) { MessagingExtensionResult composeExtensionResult = new MessagingExtensionResult { Type = "result", AttachmentLayout = "list", Attachments = new List <MessagingExtensionAttachment>(), }; IList <WikipediaResult> searchResults = new List <WikipediaResult>(); // Search Wikipedia string apiUrl = GenerateSearchApiUrl(query); WikipediaQueryResult queryResult = await this.InvokeWikipediaApiAsync(apiUrl).ConfigureAwait(false); searchResults = queryResult.Query.Results; // Grab pageIds so that we can batch query to fetch image urls of the pages IList <string> pageIds = new List <string>(); foreach (WikipediaResult searchResult in searchResults) { pageIds.Add(searchResult.Pageid); } IDictionary <string, string> imageResults = await this.GetImageUrlAsync(pageIds).ConfigureAwait(false); // Genereate results foreach (WikipediaResult searchResult in searchResults) { string imageUrl = DefaultImageUrl; // Always set a default image url in case of failure, or image doesn't exist if (imageResults.ContainsKey(searchResult.Pageid)) { imageUrl = imageResults[searchResult.Pageid]; } ThumbnailCard previewCard = new ThumbnailCard { Title = HttpUtility.HtmlEncode(searchResult.Title), Text = searchResult.Snippet, }; previewCard.Images = new CardImage[] { new CardImage(imageUrl, searchResult.Title) }; // Generate cards with links in the titles - preview cards don't have links ThumbnailCard card = new ThumbnailCard { Title = "<a href='" + HttpUtility.HtmlAttributeEncode("https://en.wikipedia.org/wiki/" + Uri.EscapeDataString(searchResult.Title)) + "' target='_blank'>" + HttpUtility.HtmlEncode(searchResult.Title) + "</a>", Text = searchResult.Snippet, Images = previewCard.Images, }; composeExtensionResult.Attachments.Add(card.ToAttachment().ToMessagingExtensionAttachment(previewCard.ToAttachment())); } return(composeExtensionResult); }
/// <summary> /// Generates the search API URL. /// </summary> /// <param name="query">The query.</param> /// <returns>Search API url.</returns> private static string GenerateSearchApiUrl(MessagingExtensionQuery query) { return(string.Format( WikiSearchUrlFormat, Uri.EscapeDataString(query.Parameters[0].Value.ToString()), query.QueryOptions.Count, query.QueryOptions.Skip)); }
public async Task <WikiResult> SearchWiki(string queryParameter, MessagingExtensionQuery composeExtensionQuery) { string searchApiUrl = SearchApiUrlFormat.Replace("[keyword]", queryParameter); searchApiUrl = searchApiUrl.Replace("[limit]", composeExtensionQuery.QueryOptions.Count + ""); searchApiUrl = searchApiUrl.Replace("[offset]", composeExtensionQuery.QueryOptions.Skip + ""); Uri apiUrl = new Uri(searchApiUrl); return(await ProcessRequest <WikiResult>(apiUrl)); }
// return the value of the specified query parameter public string GetQueryParameterByName(MessagingExtensionQuery query, string name) { foreach (var param in query.Parameters) { if (param.Name == name) { return(param.Value.ToString()); } } return(""); }
/// <summary> /// Handle when the user is searching in the messaging extension query. /// </summary> /// <param name="turnContext">The turn context.</param> /// <param name="query">The messaging extension query.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A Task that resolves to the list of cards that matched the query.</returns> /// <remarks> /// This application only supports direct links to reddit as the query string, in many applications /// this should be used to search for matching items. /// /// For more information on search based messaging extensions see the documentation /// https://docs.microsoft.com/en-us/microsoftteams/platform/messaging-extensions/how-to/search-commands/respond-to-search?tabs=dotnet . /// </remarks> protected override Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync( ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { query = query ?? throw new ArgumentNullException(nameof(query)); turnContext = turnContext ?? throw new ArgumentNullException(nameof(turnContext)); this.RecordEvent(nameof(this.OnTeamsMessagingExtensionQueryAsync), turnContext); var queryString = query.Parameters.FirstOrDefault()?.Value as string ?? string.Empty; return(this.SearchRedditPostsAsync(queryString)); }
/// <summary> /// Invoked when the user opens the messaging extension or searching any content in it. /// </summary> /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param> /// <param name="query">Contains messaging extension query keywords.</param> /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param> /// <returns>Messaging extension response object to fill compose extension section.</returns> /// <remarks> /// https://docs.microsoft.com/en-us/dotnet/api/microsoft.bot.builder.teams.teamsactivityhandler.onteamsmessagingextensionqueryasync?view=botbuilder-dotnet-stable. /// </remarks> protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync( ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { IInvokeActivity turnContextActivity = turnContext?.Activity; try { if (!await this.CheckTeamsValidaionAsync(turnContext)) { return(new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Text = this.localizer.GetString("InvalidTeamText"), Type = "message", }, }); } MessagingExtensionQuery messageExtensionQuery = JsonConvert.DeserializeObject <MessagingExtensionQuery>(turnContextActivity.Value.ToString()); string searchQuery = SearchHelper.GetSearchQueryString(messageExtensionQuery); turnContextActivity.TryGetChannelData <TeamsChannelData>(out var teamsChannelData); var cycleStatus = await this.rewardCycleStorageProvider.GetActiveRewardCycleAsync(teamsChannelData.Channel.Id); if (cycleStatus != null) { return(new MessagingExtensionResponse { ComposeExtension = await SearchHelper.GetSearchResultAsync(this.appBaseUrl, searchQuery, cycleStatus.CycleId, teamsChannelData.Channel.Id, messageExtensionQuery.QueryOptions.Count, messageExtensionQuery.QueryOptions.Skip, this.nominateDetailSearchService, this.localizer), }); } return(new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Text = this.localizer.GetString("CycleValidationMessage"), Type = "message", }, }); } catch (Exception ex) { this.logger.LogError(ex, $"Failed to handle the messaging extension command {turnContextActivity.Name}: {ex.Message}", SeverityLevel.Error); throw; } }
// Get the value of the searchText parameter in the ME query private string GetSearchQueryString(MessagingExtensionQuery query) { string messageExtensionInputText = string.Empty; foreach (var parameter in query.Parameters) { if (parameter.Name.Equals(SearchTextParameterName, StringComparison.OrdinalIgnoreCase)) { messageExtensionInputText = parameter.Value.ToString(); break; } } return(messageExtensionInputText); }
private static string GetQueryParameterByName(MessagingExtensionQuery query, string name) { if (query?.Parameters == null || query.Parameters.Count == 0) { return(string.Empty); } var parameter = query.Parameters[0]; if (!string.Equals(parameter.Name, name, StringComparison.OrdinalIgnoreCase)) { return(string.Empty); } return(parameter.Value != null?parameter.Value.ToString() : string.Empty); }
/// <summary> /// Invoked when the user opens the messaging extension or searching any content in it. /// </summary> /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param> /// <param name="query">Contains messaging extension query keywords.</param> /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param> /// <returns>Messaging extension response object to fill compose extension section.</returns> /// <remarks> /// https://docs.microsoft.com/en-us/dotnet/api/microsoft.bot.builder.teams.teamsactivityhandler.onteamsmessagingextensionqueryasync?view=botbuilder-dotnet-stable. /// </remarks> protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync( ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { IInvokeActivity turnContextActivity = turnContext?.Activity; try { MessagingExtensionQuery messageExtensionQuery = JsonConvert.DeserializeObject <MessagingExtensionQuery>(turnContextActivity.Value.ToString()); string searchQuery = SearchHelper.GetSearchQueryString(messageExtensionQuery); string onCallSMEUsers = string.Empty; turnContextActivity.TryGetChannelData <TeamsChannelData>(out var teamsChannelData); if (messageExtensionQuery.CommandId == Constants.ActiveCommandId || messageExtensionQuery.CommandId == Constants.ClosedCommandId) { onCallSMEUsers = await CardHelper.GetOnCallSMEuserListAsync(turnContext, this.onCallSupportDetailSearchService, this.teamId, this.logger); return(new MessagingExtensionResponse { ComposeExtension = await SearchHelper.GetSearchResultAsync(searchQuery, messageExtensionQuery.CommandId, messageExtensionQuery.QueryOptions.Count, messageExtensionQuery.QueryOptions.Skip, this.ticketSearchService, this.localizer, turnContext.Activity.From.AadObjectId, onCallSMEUsers), }); } if (turnContext != null && teamsChannelData.Team != null && teamsChannelData.Team.Id == this.teamId && (messageExtensionQuery.CommandId == Constants.UrgentCommandId || messageExtensionQuery.CommandId == Constants.AssignedCommandId || messageExtensionQuery.CommandId == Constants.UnassignedCommandId)) { return(new MessagingExtensionResponse { ComposeExtension = await SearchHelper.GetSearchResultAsync(searchQuery, messageExtensionQuery.CommandId, messageExtensionQuery.QueryOptions.Count, messageExtensionQuery.QueryOptions.Skip, this.ticketSearchService, this.localizer), }); } return(new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Text = this.localizer.GetString("InvalidTeamText"), Type = "message", }, }); } catch (Exception ex) { this.logger.LogError(ex, $"Failed to handle the messaging extension command {turnContextActivity.Name}: {ex.Message}", SeverityLevel.Error); throw; } }
/// <summary> /// Handle when the user is searching in the messaging extension query. /// Apps should handle user queries and return appropriate results. /// </summary> /// <param name="turnContext">The turn context.</param> /// <param name="query">The messaging extension query.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A Task that resolves to the list of cards that matched the query.</returns> protected override Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync( ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { var attachment = new HeroCard("Query not implemented", "App should handle query approperiately."); var attachments = new MessagingExtensionAttachment(HeroCard.ContentType, null /*url*/, attachment); var response = new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult( AttachmentLayoutTypes.List, "result" /*type*/, new[] { attachments }), }; return(Task.FromResult(response)); }
public async Task ComposeExtension_GetComposeExtensionDataAsync() { Activity sampleActivity = JsonConvert.DeserializeObject <Activity>(File.ReadAllText(@"Jsons\SampleActivityComposeExtension.json")); await TestHelpers.RunTestPipelineWithActivityAsync( sampleActivity, (teamsContext) => { MessagingExtensionQuery query = teamsContext.GetMessagingExtensionQueryData(); Assert.AreEqual("testQuery", query.CommandId); Assert.IsTrue(query.Parameters != null && query.Parameters.Count == 1); Assert.AreEqual("selectedQueryJson", query.Parameters[0].Name); Assert.AreEqual("Value", query.Parameters[0].Value.ToString()); return(Task.CompletedTask); }).ConfigureAwait(false); }
public void MessagingExtensionQueryInits() { var commandId = "commandId123"; var parameters = new List <MessagingExtensionParameter>() { new MessagingExtensionParameter("pandaCount", 5) }; var queryOptions = new MessagingExtensionQueryOptions(0, 1); var state = "secureAuthStateValue123"; var msgExtQuery = new MessagingExtensionQuery(commandId, parameters, queryOptions, state); Assert.NotNull(msgExtQuery); Assert.IsType <MessagingExtensionQuery>(msgExtQuery); Assert.Equal(commandId, msgExtQuery.CommandId); Assert.Equal(parameters, msgExtQuery.Parameters); Assert.Equal(queryOptions, msgExtQuery.QueryOptions); Assert.Equal(state, msgExtQuery.State); }
/// <summary> /// Invoked when the user opens the messaging extension or searching any content in it. /// </summary> /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param> /// <param name="query">Contains messaging extension query keywords.</param> /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param> /// <returns>Messaging extension response object to fill compose extension section.</returns> /// <remarks> /// https://docs.microsoft.com/en-us/dotnet/api/microsoft.bot.builder.teams.teamsactivityhandler.onteamsmessagingextensionqueryasync?view=botbuilder-dotnet-stable. /// </remarks> protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync( ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { turnContext = turnContext ?? throw new ArgumentNullException(nameof(turnContext)); this.RecordEvent(nameof(this.OnTeamsMessagingExtensionQueryAsync), turnContext); var activity = turnContext.Activity; try { var messagingExtensionQuery = JsonConvert.DeserializeObject <MessagingExtensionQuery>(activity.Value.ToString()); var searchQuery = this.messagingExtensionHelper.GetSearchQueryString(messagingExtensionQuery); if (!string.IsNullOrEmpty(searchQuery)) { switch (messagingExtensionQuery.CommandId) { case Constants.YourResponseCommandId: // Tracking the user search keywords from the messaging extension. this.RecordEvent(YourResponsesSearchEventName, turnContext); break; case Constants.CompanyResponseCommandId: // Tracking the company search keywords from the messaging extension. this.RecordEvent(CompanyResponsesSearchEventName, turnContext); break; } } return(new MessagingExtensionResponse { ComposeExtension = await this.messagingExtensionHelper.GetSearchResultAsync(searchQuery, messagingExtensionQuery.CommandId, messagingExtensionQuery.QueryOptions.Count, messagingExtensionQuery.QueryOptions.Skip, activity.From.AadObjectId, localizer : this.localizer), }); } catch (Exception ex) { this.logger.LogError(ex, $"Failed to handle the messaging extension command {activity.Name}: {ex.Message}", SeverityLevel.Error); throw; } }
public async Task OnTurnAsync(ITurnContext turnCtx, CancellationToken cancellationToken) { try { if (turnCtx.Activity != null && turnCtx.Activity.Type != null && turnCtx.Activity.Type == ActivityTypes.Invoke) { ITeamsContext teamsContext = turnCtx.TurnState.Get <ITeamsContext>(); MessagingExtensionQuery meQuery = null; if (teamsContext.IsRequestMessagingExtensionQuery()) { meQuery = teamsContext.GetMessagingExtensionQueryData(); } InvokeResponse ir = new InvokeResponse { Body = new MessagingExtensionResponse { ComposeExtension = await searchHandler.GetSearchResultAsync(meQuery.Parameters[0].Value.ToString()) }, Status = 200, }; await turnCtx.SendActivityAsync( new Activity { Value = ir, Type = ActivityTypesEx.InvokeResponse, }).ConfigureAwait(false); } else { await turnCtx.SendActivityAsync(string.Format("Sorry! As of now I'm only support an invoke command, but you're trying to execute {0}", (turnCtx.Activity != null && turnCtx.Activity.Type != null) ? turnCtx.Activity.Type.ToString() : "empty activity")); } } catch (Exception ex) { await turnCtx.SendActivityAsync($"Oppps, seems like an error: {ex.InnerException}. Try again or contact your IT admin"); } }
/// <summary> /// Invoked when the user opens the Messaging Extension or searching any content in it. /// </summary> /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param> /// <param name="query">Contains Messaging Extension query keywords.</param> /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param> /// <returns>Messaging extension response object to fill compose extension section.</returns> /// <remarks> /// https://docs.microsoft.com/en-us/dotnet/api/microsoft.bot.builder.teams.teamsactivityhandler.onteamsmessagingextensionqueryasync?view=botbuilder-dotnet-stable. /// </remarks> protected override Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync( ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { turnContext = turnContext ?? throw new ArgumentNullException(nameof(turnContext)); var activity = turnContext.Activity; WikipediaComposeExtension wikipediaComposeExtension = new WikipediaComposeExtension(this._userState.CreateProperty <UserData>(nameof(UserData))); if (activity.Name == "composeExtension/selectItem") { var selectedItemResponse = wikipediaComposeExtension.HandleComposeExtensionSelectedItem(turnContext, query); this._userState.SaveChangesAsync(turnContext, false, cancellationToken); return(selectedItemResponse); } else { var result = wikipediaComposeExtension.GetComposeExtensionResponseAsync(turnContext, query); this._userState.SaveChangesAsync(turnContext, false, cancellationToken); return(result); } }
/// <summary> /// Get the value of the searchText parameter in the Messaging Extension query. /// </summary> /// <param name="query">Contains Messaging Extension query keywords.</param> /// <returns>A value of the searchText parameter.</returns> public string GetSearchResult(MessagingExtensionQuery query) { return query?.Parameters.FirstOrDefault(parameter => parameter.Name.Equals(SearchTextParameterName, StringComparison.OrdinalIgnoreCase))?.Value?.ToString(); }
/// <summary> /// Handle message extension query received by the bot. /// </summary> /// <param name="turnContext">turn context.</param> /// <param name="query">query.</param> /// <param name="cancellationToken">cancellation token.</param> /// <returns>MessagingExtensionResponse.</returns> protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { try { var messageExtensionQuery = JsonConvert.DeserializeObject <MessagingExtensionQuery>(turnContext.Activity.Value.ToString()); var searchQuery = this.GetSearchQueryString(messageExtensionQuery); this.telemetryClient.TrackTrace($"searchQuery : {searchQuery} commandId : {messageExtensionQuery.CommandId}"); turnContext.Activity.TryGetChannelData <TeamsChannelData>(out var teamsChannelData); if (!string.IsNullOrEmpty(teamsChannelData.Team?.Id)) { return(new MessagingExtensionResponse { ComposeExtension = await this.GetSearchResultAsync(searchQuery, messageExtensionQuery.CommandId, teamsChannelData.Team.Id), }); } } catch (Exception ex) { this.telemetryClient.TrackException(ex); } return(new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult() { Type = "message", Text = Strings.NoEntriesFound, }, }); }
protected override Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { Record.Add(MethodBase.GetCurrentMethod().Name); return(Task.FromResult(new MessagingExtensionResponse())); }
protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { var text = query?.Parameters?[0]?.Value as string ?? string.Empty; var packages = await FindPackages(text); var attachments = packages.Select(package => { var previewCard = new ThumbnailCard { Title = package.Name, Tap = new CardAction { Type = "invoke", Value = package }, }; var attachment = new MessagingExtensionAttachment { ContentType = HeroCard.ContentType, Content = new HeroCard { Title = package.Name }, Preview = previewCard.ToAttachment() }; return(attachment); }).ToList(); return(new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Type = "result", AttachmentLayout = "list", Attachments = attachments } }); }
/// <summary> /// Get the value of the searchText parameter in the messaging extension query. /// </summary> /// <param name="query">Contains messaging extension query keywords.</param> /// <returns>A value of the searchText parameter.</returns> public static string GetSearchQueryString(MessagingExtensionQuery query) { var messageExtensionInputText = query?.Parameters.FirstOrDefault(parameter => parameter.Name.Equals(SearchTextParameterName, StringComparison.OrdinalIgnoreCase)); return(messageExtensionInputText?.Value?.ToString()); }
protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { var text = query?.Parameters?[0]?.Value as string ?? string.Empty; var patients = await FindPatient(text); var attachments = patients.Select(patient => { var previewCard = new ThumbnailCard { Title = patient.Item2, Subtitle = "Gender : " + patient.Item4, Text = "Contact Number : " + patient.Item5, Tap = new CardAction { Type = "invoke", Value = patient } }; if (!string.IsNullOrEmpty(patient.Item6)) { previewCard.Images = new List <CardImage>() { new CardImage(patient.Item6, "Profile Pic") }; } var attachment = new MessagingExtensionAttachment { ContentType = HeroCard.ContentType, Content = new HeroCard { Title = patient.Item1 }, Preview = previewCard.ToAttachment() }; return(attachment); }).ToList(); return(new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Type = "result", AttachmentLayout = "list", Attachments = attachments } }); }
/// <summary> /// When OnTurn method receives a compose extension query invoke activity on bot turn, it calls this method. /// </summary> /// <param name="turnContext">Provides context for a turn of a bot.</param> /// <param name="query">Messaging extension query request value payload.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> /// <returns>A task that represents messaging extension response.</returns> protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { try { var messageExtensionQuery = JsonConvert.DeserializeObject <MessagingExtensionQuery>(turnContext.Activity.Value.ToString()); // Execute code when parameter name is initial run. if (messageExtensionQuery.Parameters.First().Name == MessagingExtensionInitialParameterName) { this.logger.LogInformation("Executing initial run parameter from messaging extension."); // Get access token for user.if already authenticated, we will get token. // If user is not signed in, send sign in link in messaging extension. var tokenResponse = await(turnContext.Adapter as IUserTokenProvider).GetUserTokenAsync(turnContext, this.botSettings.OAuthConnectionName, messageExtensionQuery.State, cancellationToken).ConfigureAwait(false); if (tokenResponse == null) { var signInLink = await(turnContext.Adapter as IUserTokenProvider).GetOauthSignInLinkAsync(turnContext, this.botSettings.OAuthConnectionName, cancellationToken).ConfigureAwait(false); return(new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Type = MessagingExtensionAuthType, SuggestedActions = new MessagingExtensionSuggestedAction { Actions = new List <CardAction> { new CardAction { Type = ActionTypes.OpenUrl, Value = signInLink, Title = Strings.SignInCardText, }, }, }, }, }); } } return(await this.HandleMessagingExtensionSearchQueryAsync(turnContext).ConfigureAwait(false)); } catch (Exception ex) { this.logger.LogError(ex, "Error in handling invoke action from messaging extension."); return(null); } }
protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionConfigurationQuerySettingUrlAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { // The user has requested the Messaging Extension Configuration page. var escapedSettings = string.Empty; var userConfigSettings = await _userConfigProperty.GetAsync(turnContext, () => string.Empty); if (!string.IsNullOrEmpty(userConfigSettings)) { escapedSettings = Uri.EscapeDataString(userConfigSettings); } return(new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Type = "config", SuggestedActions = new MessagingExtensionSuggestedAction { Actions = new List <CardAction> { new CardAction { Type = ActionTypes.OpenUrl, Value = $"{_siteUrl}/searchSettings.html?settings={escapedSettings}", }, }, }, }, }); }
protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery action, CancellationToken cancellationToken) { var text = action?.Parameters?[0]?.Name as string ?? string.Empty; var attachments = new List <MessagingExtensionAttachment>(); var userConfigSettings = await _userConfigProperty.GetAsync(turnContext, () => string.Empty); if (userConfigSettings.ToUpper().Contains("EMAIL")) { // When the Bot Service Auth flow completes, the action.State will contain a magic code used for verification. var state = action.State; // Check the state value var tokenResponse = await GetTokenResponse(turnContext, state, cancellationToken); if (tokenResponse == null || string.IsNullOrEmpty(tokenResponse.Token)) { // There is no token, so the user has not signed in yet. // Retrieve the OAuth Sign in Link to use in the MessagingExtensionResult Suggested Actions var signInLink = await GetSignInLinkAsync(turnContext, cancellationToken).ConfigureAwait(false); return(new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Type = "auth", SuggestedActions = new MessagingExtensionSuggestedAction { Actions = new List <CardAction> { new CardAction { Type = ActionTypes.OpenUrl, Value = signInLink, Title = "Bot Service OAuth", }, }, }, }, }); } var client = new SimpleGraphClient(tokenResponse.Token); var messages = await client.SearchMailInboxAsync(text); // Here we construct a ThumbnailCard for every attachment, and provide a HeroCard which will be // displayed if the selects that item. attachments = messages.Select(msg => new MessagingExtensionAttachment { ContentType = HeroCard.ContentType, Content = new HeroCard { Title = msg.From.EmailAddress.Address, Subtitle = msg.Subject, Text = msg.Body.Content, }, Preview = new ThumbnailCard { Title = msg.From.EmailAddress.Address, Text = $"{msg.Subject}<br />{msg.BodyPreview}", Images = new List <CardImage>() { new CardImage("https://raw.githubusercontent.com/microsoft/botbuilder-samples/master/docs/media/OutlookLogo.jpg", "Outlook Logo"), }, }.ToAttachment() } ).ToList(); } else { var packages = await FindPackages(text); // We take every row of the results and wrap them in cards wrapped in in MessagingExtensionAttachment objects. // The Preview is optional, if it includes a Tap, that will trigger the OnTeamsMessagingExtensionSelectItemAsync event back on this bot. attachments = packages.Select(package => { var previewCard = new ThumbnailCard { Title = package.Item1, Tap = new CardAction { Type = "invoke", Value = package } }; if (!string.IsNullOrEmpty(package.Item5)) { previewCard.Images = new List <CardImage>() { new CardImage(package.Item5, "Icon") }; } var attachment = new MessagingExtensionAttachment { ContentType = HeroCard.ContentType, Content = new HeroCard { Title = package.Item1 }, Preview = previewCard.ToAttachment() }; return(attachment); }).ToList(); } // The list of MessagingExtensionAttachments must we wrapped in a MessagingExtensionResult wrapped in a MessagingExtensionResponse. return(new MessagingExtensionResponse { ComposeExtension = new MessagingExtensionResult { Type = "result", AttachmentLayout = "list", Attachments = attachments } }); }
protected override async Task <MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { if (query.CommandId == ManifestConstants.ComposeExtensions.ProjectQuery.Id) { return(await this.projectMessagingExtension.HandleMessagingExtensionQueryAsync(turnContext, query)); } else { return(new MessagingExtensionResponse()); } }
/// <summary> /// Invoked when a messaging extension configuration query setting url activity is received from the connector. /// </summary> /// <param name="turnContext">A strongly-typed context object for this turn.</param> /// <param name="query">The Messaging extension query.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>The Messaging Extension Response for the query.</returns> protected virtual Task <MessagingExtensionResponse> OnTeamsMessagingExtensionConfigurationQuerySettingUrlAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken) { throw new InvokeResponseException(HttpStatusCode.NotImplemented); }