/// <summary> /// Initializes a new instance of the <see cref="PublishFunction"/> class. /// </summary> /// <param name="qnaServiceProviders">Language specific Question and answer maker service providers.</param> /// <param name="configurationProvider">Configuration service provider.</param> /// <param name="searchServiceDataProvider">Search service data provider.</param> /// <param name="knowledgeBaseSearchService">Knowledgebase search service.</param> public PublishFunction(IEnumerable <IQnaServiceProvider> qnaServiceProviders, IConfigurationDataProvider configurationProvider, ISearchServiceDataProvider searchServiceDataProvider, IKnowledgeBaseSearchService knowledgeBaseSearchService) { this.qnaServiceProviders = qnaServiceProviders; this.configurationProvider = configurationProvider; this.searchServiceDataProvider = searchServiceDataProvider; this.knowledgeBaseSearchService = knowledgeBaseSearchService; }
/// <summary> /// Get the results from Azure search service and populate the result (card + preview). /// </summary> /// <param name="languageCode">Current expert team's applicable language code.</param> /// <param name="query">Query which the user had typed in message extension search.</param> /// <param name="commandId">Command id to determine which tab in message extension has been invoked.</param> /// <param name="count">Count for pagination.</param> /// <param name="skip">Skip for pagination.</param> /// <param name="localTimestamp">Local timestamp of the user activity.</param> /// <param name="searchService">Search service.</param> /// <param name="knowledgeBaseSearchService">Knowledgebase search service.</param> /// <param name="activityStorageProvider">Activity storage provider.</param> /// <param name="appBaseUri">Application base uri.</param> /// <returns><see cref="Task"/> Returns MessagingExtensionResult which will be used for providing the card.</returns> public static async Task <MessagingExtensionResult> GetSearchResultAsync( string languageCode, string query, string commandId, int?count, int?skip, DateTimeOffset?localTimestamp, ISearchService searchService, IKnowledgeBaseSearchService knowledgeBaseSearchService, IActivityStorageProvider activityStorageProvider, string appBaseUri) { MessagingExtensionResult composeExtensionResult = new MessagingExtensionResult { Type = "result", AttachmentLayout = AttachmentLayoutTypes.List, Attachments = new List <MessagingExtensionAttachment>(), }; IList <TicketEntity> searchServiceResults = new List <TicketEntity>(); // commandId should be equal to Id mentioned in Manifest file under composeExtensions section. switch (commandId) { case RecentCommandId: searchServiceResults = await searchService.SearchTicketsAsync(TicketSearchScope.RecentTickets, languageCode, query, count, skip).ConfigureAwait(false); composeExtensionResult = GetMessagingExtensionResult(commandId, localTimestamp, searchServiceResults, appBaseUri); break; case OpenCommandId: searchServiceResults = await searchService.SearchTicketsAsync(TicketSearchScope.UnAnsweredTickets, languageCode, query, count, skip).ConfigureAwait(false); composeExtensionResult = GetMessagingExtensionResult(commandId, localTimestamp, searchServiceResults, appBaseUri); break; case AssignedCommandId: searchServiceResults = await searchService.SearchTicketsAsync(TicketSearchScope.AnsweredTickets, languageCode, query, count, skip).ConfigureAwait(false); composeExtensionResult = GetMessagingExtensionResult(commandId, localTimestamp, searchServiceResults, appBaseUri); break; case KnowledgebaseQuestionCommandId: var azureSearchEntities = await knowledgeBaseSearchService.GetAzureSearchEntitiesAsync(query).ConfigureAwait(false); if (azureSearchEntities.Any()) { var activitiesData = await activityStorageProvider.GetActivityEntitiesAsync().ConfigureAwait(false); composeExtensionResult.Attachments = MessagingExtensionQnaCard.GetAllKbQuestionsCard(azureSearchEntities, activitiesData); } break; } return(composeExtensionResult); }
/// <summary> /// Initializes a new instance of the <see cref="MessagingExtensionActivity"/> class. /// </summary> /// <param name="configurationProvider">Configuration Provider.</param> /// <param name="activityStorageProvider">Activity storage provider.</param> /// <param name="qnaServiceProvider">Question and answer maker service provider.</param> /// <param name="searchService">SearchService dependency injection.</param> /// <param name="botAdapter">Bot adapter dependency injection.</param> /// <param name="memoryCache">IMemoryCache dependency injection.</param> /// <param name="knowledgeBaseSearchService">KnowledgeBaseSearchService dependency injection.</param> /// <param name="optionsAccessor">A set of key/value application configuration properties for FaqPlusPlus bot.</param> /// <param name="logger">Instance to send logs to the Application Insights service.</param> /// <param name="ticketsProvider">Instance of Ticket provider helps in fetching and storing information in storage table.</param> /// <param name="notificationService">Notifies in expert's Team chat.</param> public MessagingExtensionActivity( Common.Providers.IConfigurationDataProvider configurationProvider, IQnaServiceProvider qnaServiceProvider, IActivityStorageProvider activityStorageProvider, ISearchService searchService, BotFrameworkAdapter botAdapter, IMemoryCache memoryCache, IKnowledgeBaseSearchService knowledgeBaseSearchService, IOptionsMonitor <BotSettings> optionsAccessor, ILogger <MessagingExtensionActivity> logger, ITicketsProvider ticketsProvider, INotificationService notificationService) { this.configurationProvider = configurationProvider ?? throw new ArgumentNullException(nameof(configurationProvider)); this.qnaServiceProvider = qnaServiceProvider ?? throw new ArgumentNullException(nameof(qnaServiceProvider)); this.activityStorageProvider = activityStorageProvider ?? throw new ArgumentNullException(nameof(activityStorageProvider)); this.searchService = searchService ?? throw new ArgumentNullException(nameof(searchService)); this.botAdapter = botAdapter ?? throw new ArgumentNullException(nameof(botAdapter)); this.accessCache = memoryCache ?? throw new ArgumentNullException(nameof(memoryCache)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.knowledgeBaseSearchService = knowledgeBaseSearchService ?? throw new ArgumentNullException(nameof(knowledgeBaseSearchService)); this.ticketsProvider = ticketsProvider ?? throw new ArgumentNullException(nameof(ticketsProvider)); this.notificationService = notificationService ?? throw new ArgumentNullException(nameof(notificationService)); if (optionsAccessor == null) { throw new ArgumentNullException(nameof(optionsAccessor)); } this.options = optionsAccessor.CurrentValue; this.appId = this.options.ExpertAppId; this.appBaseUri = this.options.AppBaseUri; this.accessCacheExpiryInDays = this.options.AccessCacheExpiryInDays; if (this.accessCacheExpiryInDays <= 0) { this.accessCacheExpiryInDays = DefaultAccessCacheExpiryInDays; this.logger.LogInformation($"Configuration option is not present or out of range for AccessCacheExpiryInDays and the default value is set to: {this.accessCacheExpiryInDays}", SeverityLevel.Information); } }