/// <summary>
        /// Send the nomination reminder notification to specified team.
        /// </summary>
        /// <param name="rewardCycleEntity">Reward cycle model object.</param>
        /// <returns>A task that sends notification card in channel.</returns>
        private async Task SendCardToTeamAsync(RewardCycleEntity rewardCycleEntity)
        {
            rewardCycleEntity = rewardCycleEntity ?? throw new ArgumentNullException(nameof(rewardCycleEntity));

            var awardsList = await this.awardsStorageProvider.GetAwardsAsync(rewardCycleEntity.TeamId);

            var valuesFromTaskModule = new TaskModuleResponseDetails()
            {
                RewardCycleStartDate = rewardCycleEntity.RewardCycleStartDate,
                RewardCycleEndDate   = rewardCycleEntity.RewardCycleEndDate,
                RewardCycleId        = rewardCycleEntity.CycleId,
            };

            var teamDetails = await this.teamStorageProvider.GetTeamDetailAsync(rewardCycleEntity.TeamId);

            string serviceUrl = teamDetails.ServiceUrl;

            MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
            string teamGeneralChannelId = rewardCycleEntity.TeamId;

            this.logger.LogInformation($"sending notification to channel id - {teamGeneralChannelId}");

            await retryPolicy.ExecuteAsync(async() =>
            {
                try
                {
                    var conversationParameters = new ConversationParameters()
                    {
                        ChannelData = new TeamsChannelData()
                        {
                            Channel = new ChannelInfo()
                            {
                                Id = rewardCycleEntity.TeamId
                            }
                        },
                        Activity = (Activity)MessageFactory.Carousel(NominateCarouselCard.GetAwardNominationCards(this.options.Value.AppBaseUri, awardsList, this.localizer, valuesFromTaskModule)),
                    };

                    Activity mentionActivity = MessageFactory.Text(this.localizer.GetString("NominationReminderNotificationText"));

                    await((BotFrameworkAdapter)this.adapter).CreateConversationAsync(
                        Constants.TeamsBotFrameworkChannelId,
                        serviceUrl,
                        this.microsoftAppCredentials,
                        conversationParameters,
                        async(conversationTurnContext, conversationCancellationToken) =>
                    {
                        await conversationTurnContext.SendActivityAsync(mentionActivity, conversationCancellationToken);
                    },
                        default);
                }
                catch (Exception ex)
                {
                    this.logger.LogError(ex, "Error while sending mention card notification to channel.");
                    throw;
                }
            });
        }
        /// <summary>
        /// This method will construct admin card with corresponding details.
        /// </summary>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="adminDetails">Admin details to show in card.</param>
        /// <returns>User welcome card.</returns>
        public static Attachment GetAdminCard(IStringLocalizer <Strings> localizer, TaskModuleResponseDetails adminDetails)
        {
            AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(Constants.AdaptiveCardVersion))
            {
                Body = new List <AdaptiveElement>
                {
                    new AdaptiveTextBlock
                    {
                        Text   = localizer.GetString("AdminHeaderText"),
                        Weight = AdaptiveTextWeight.Bolder,
                        Size   = AdaptiveTextSize.Large,
                    },
                    new AdaptiveTextBlock
                    {
                        Text    = localizer.GetString("AdminSubheaderText"),
                        Spacing = AdaptiveSpacing.None,
                    },
                    new AdaptiveTextBlock
                    {
                        Text    = localizer.GetString("AdminName", adminDetails?.AdminName, adminDetails.AdminPrincipalName),
                        Wrap    = true,
                        Spacing = AdaptiveSpacing.Default,
                    },
                    new AdaptiveTextBlock
                    {
                        Text      = localizer.GetString("NoteForTeamText", adminDetails.NoteForTeam),
                        Wrap      = true,
                        Spacing   = AdaptiveSpacing.Default,
                        IsVisible = !string.IsNullOrEmpty(adminDetails.NoteForTeam),
                    },
                },
                Actions = new List <AdaptiveAction>
                {
                    new AdaptiveOpenUrlAction
                    {
                        Title = localizer.GetString("ManageRewardTitle"),
                        Url   = new System.Uri($"{GoToLink}threadId={adminDetails.TeamId}&ctx=channel"),
                    },
                },
            };

            return(new Attachment
            {
                ContentType = AdaptiveCard.ContentType,
                Content = card,
            });
        }
        /// <summary>
        /// This method will construct admin card with corresponding details.
        /// </summary>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="adminDetails">Admin details to show in card.</param>
        /// <returns>User welcome card.</returns>
        public static Attachment GetAdminCard(IStringLocalizer <Strings> localizer, TaskModuleResponseDetails adminDetails)
        {
            adminDetails = adminDetails ?? throw new ArgumentNullException(nameof(adminDetails));

            AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(Constants.AdaptiveCardVersion))
            {
                Body = new List <AdaptiveElement>
                {
                    new AdaptiveTextBlock
                    {
                        Text   = localizer.GetString("AdminHeaderText"),
                        Weight = AdaptiveTextWeight.Bolder,
                        Size   = AdaptiveTextSize.Large,
                    },
                    new AdaptiveTextBlock
                    {
                        Text    = localizer.GetString("AdminSubheaderText", adminDetails.AdminName, adminDetails.AdminUserPrincipalName),
                        Spacing = AdaptiveSpacing.None,
                    },
                    new AdaptiveTextBlock
                    {
                        Text      = localizer.GetString("NoteForTeamText", adminDetails.NoteForTeam),
                        Wrap      = true,
                        Spacing   = AdaptiveSpacing.Default,
                        IsVisible = !string.IsNullOrEmpty(adminDetails.NoteForTeam),
                    },
                    new AdaptiveTextBlock
                    {
                        Text    = localizer.GetString("AdminTabNavigationText", adminDetails.NoteForTeam),
                        Wrap    = true,
                        Spacing = AdaptiveSpacing.Large,
                        Size    = AdaptiveTextSize.Medium,
                        Weight  = AdaptiveTextWeight.Bolder,
                    },
                },
            };

            return(new Attachment
            {
                ContentType = AdaptiveCard.ContentType,
                Content = card,
            });
        }
        /// <summary>
        /// This method will construct admin card with corresponding details.
        /// </summary>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="adminDetails">Admin details to show in card.</param>
        /// <param name="manifestId">Unique id of manifest.</param>
        /// <returns>User welcome card.</returns>
        public static Attachment GetAdminCard(IStringLocalizer <Strings> localizer, TaskModuleResponseDetails adminDetails, string manifestId)
        {
            string context = HttpUtility.UrlEncode(JsonConvert.SerializeObject(new { channelId = adminDetails?.TeamId }));

            AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(Constants.AdaptiveCardVersion))
            {
                Body = new List <AdaptiveElement>
                {
                    new AdaptiveTextBlock
                    {
                        Text   = localizer.GetString("AdminHeaderText"),
                        Weight = AdaptiveTextWeight.Bolder,
                        Size   = AdaptiveTextSize.Large,
                    },
                    new AdaptiveTextBlock
                    {
                        Text    = localizer.GetString("AdminSubheaderText", adminDetails?.AdminName, adminDetails.AdminPrincipalName),
                        Spacing = AdaptiveSpacing.None,
                    },
                    new AdaptiveTextBlock
                    {
                        Text      = localizer.GetString("NoteForTeamText", adminDetails.NoteForTeam),
                        Wrap      = true,
                        Spacing   = AdaptiveSpacing.Default,
                        IsVisible = !string.IsNullOrEmpty(adminDetails.NoteForTeam),
                    },
                },
                Actions = new List <AdaptiveAction>
                {
                    new AdaptiveOpenUrlAction
                    {
                        Title = localizer.GetString("ManageRewardTitle"),
                        Url   = new System.Uri(string.Format(CultureInfo.InvariantCulture, Constants.TabDeepLink, manifestId, context)),
                    },
                },
            };

            return(new Attachment
            {
                ContentType = AdaptiveCard.ContentType,
                Content = card,
            });
        }
        /// <summary>
        /// Render the set of attachments that comprise carousel.
        /// </summary>
        /// <param name="applicationBasePath">Application base URL.</param>
        /// <param name="awards">award details.</param>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="details">Details to show in card.</param>
        /// <returns>The cards that comprise nominations.</returns>
        public static IEnumerable <Attachment> GetAwardsCard(string applicationBasePath, IEnumerable <AwardEntity> awards, IStringLocalizer <Strings> localizer, TaskModuleResponseDetails details)
        {
            var attachments    = new List <Attachment>();
            var startCycleDate = "{{DATE(" + details?.RewardCycleStartDate.ToString(Constants.Rfc3339DateTimeFormat, CultureInfo.InvariantCulture) + ", SHORT)}}";
            var endCycleDate   = "{{DATE(" + details?.RewardCycleEndDate.ToString(Constants.Rfc3339DateTimeFormat, CultureInfo.InvariantCulture) + ", SHORT)}}";

            foreach (var award in awards)
            {
                AdaptiveCard carouselCard = new AdaptiveCard(new AdaptiveSchemaVersion(Constants.AdaptiveCardVersion))
                {
                    Body = new List <AdaptiveElement>
                    {
                        new AdaptiveTextBlock
                        {
                            Text   = localizer.GetString("RewardTitle"),
                            Weight = AdaptiveTextWeight.Bolder,
                            Size   = AdaptiveTextSize.Large,
                        },
                        new AdaptiveImage
                        {
                            Url         = string.IsNullOrEmpty(award.AwardLink) ? new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/Content/DefaultAwardImage.png", applicationBasePath?.Trim('/'))) : new Uri(award.AwardLink),
                            PixelWidth  = PixelWidth,
                            PixelHeight = PixelHeight,
                            Size        = AdaptiveImageSize.Auto,
                            Style       = AdaptiveImageStyle.Default,
                        },
                        new AdaptiveTextBlock
                        {
                            Text    = $"**{award.AwardName.Trim()}**",
                            Size    = AdaptiveTextSize.Large,
                            Weight  = AdaptiveTextWeight.Bolder,
                            Spacing = AdaptiveSpacing.Small,
                            Wrap    = true,
                        },
                        new AdaptiveTextBlock
                        {
                            Text    = localizer.GetString("RewardCycleHeader", startCycleDate, endCycleDate),
                            Size    = AdaptiveTextSize.Small,
                            Spacing = AdaptiveSpacing.Small,
                            Wrap    = true,
                        },
                        new AdaptiveTextBlock
                        {
                            Text    = award.AwardDescription,
                            Size    = AdaptiveTextSize.Small,
                            Spacing = AdaptiveSpacing.Small,
                            Wrap    = true,
                        },
                    },
                    Actions = new List <AdaptiveAction>
                    {
                        new AdaptiveSubmitAction
                        {
                            Title = localizer.GetString("NominateButtonText"),
                            Data  = new AdaptiveCardAction
                            {
                                MsteamsCardAction = new CardAction
                                {
                                    Type = Constants.FetchActionType,
                                },
                                Command       = Constants.NominateAction,
                                AwardId       = award.AwardId,
                                RewardCycleId = details.RewardCycleId,
                            },
                        },
                    },
                };

                attachments.Add(new Attachment
                {
                    ContentType = AdaptiveCard.ContentType,
                    Content     = carouselCard,
                });
            }

            return(attachments);
        }
        /// <summary>
        /// Render the set of attachments that comprise carousel.
        /// </summary>
        /// <param name="awards">award details.</param>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="details">Details to show in card.</param>
        /// <returns>The cards that comprise nominations.</returns>
        public static IEnumerable <Attachment> GetAwardsCard(IEnumerable <AwardEntity> awards, IStringLocalizer <Strings> localizer, TaskModuleResponseDetails details)
        {
            var attachments    = new List <Attachment>();
            var startCycleDate = "{{DATE(" + details?.RewardCycleStartDate.ToString(Constants.Rfc3339DateTimeFormat, CultureInfo.InvariantCulture) + ", SHORT)}}";
            var endCycleDate   = "{{DATE(" + details?.RewardCycleEndDate.ToString(Constants.Rfc3339DateTimeFormat, CultureInfo.InvariantCulture) + ", SHORT)}}";

            foreach (var award in awards)
            {
                AdaptiveCard carouselCard = new AdaptiveCard(new AdaptiveSchemaVersion(Constants.AdaptiveCardVersion))
                {
                    Body = new List <AdaptiveElement>
                    {
                        new AdaptiveTextBlock
                        {
                            Text   = localizer.GetString("RewardTitle"),
                            Weight = AdaptiveTextWeight.Bolder,
                            Size   = AdaptiveTextSize.Large,
                        },
                        new AdaptiveImage
                        {
                            Url = string.IsNullOrEmpty(award.AwardLink) ? default : new Uri(award.AwardLink),
                                  PixelWidth  = PixelWidth,
                                  PixelHeight = PixelHeight,
                                  Size        = AdaptiveImageSize.Auto,
                                  Style       = AdaptiveImageStyle.Default,
                        },
Example #7
0
 /// <summary>
 /// This method will construct endorse card with corresponding details.
 /// </summary>
 /// <param name="localizer">The current cultures' string localizer.</param>
 /// <param name="nominatedDetails">Nominated details to show in card.</param>
 /// <returns>Endorse card with nominated details.</returns>
 public static Attachment GetEndorseCard(IStringLocalizer <Strings> localizer, TaskModuleResponseDetails nominatedDetails)
 {
     AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(Constants.AdaptiveCardVersion))
     {
         Body = new List <AdaptiveElement>
         {
             new AdaptiveColumnSet
             {
                 Columns = new List <AdaptiveColumn>
                 {
                     new AdaptiveColumn
                     {
                         Width = "50",
                         Items = new List <AdaptiveElement>
                         {
                             new AdaptiveTextBlock
                             {
                                 Text = nominatedDetails?.AwardName,
                                 Wrap = true,
                                 HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                                 Weight = AdaptiveTextWeight.Bolder,
                                 Size   = AdaptiveTextSize.Large,
                             },
                         },
                     },
                     new AdaptiveColumn
                     {
                         Width = "100",
                         Items = new List <AdaptiveElement>
                         {
                             new AdaptiveImage
                             {
                                 Url = string.IsNullOrEmpty(nominatedDetails.AwardLink) ? default : new Uri(nominatedDetails.AwardLink),
                                       HorizontalAlignment = AdaptiveHorizontalAlignment.Right,
                                       PixelHeight         = PixelHeight,
                                       PixelWidth          = PixelWidth,
                             },
                         },
                     },
                 },
             },
        /// <summary>
        /// This method will construct endorse card with corresponding details.
        /// </summary>
        /// <param name="applicationBasePath">Application base URL.</param>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="nominatedDetails">Nominated details to show in card.</param>
        /// <returns>Endorse card with nominated details.</returns>
        public static Attachment GetEndorseCard(string applicationBasePath, IStringLocalizer <Strings> localizer, TaskModuleResponseDetails nominatedDetails)
        {
            AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(Constants.AdaptiveCardVersion))
            {
                Body = new List <AdaptiveElement>
                {
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveTextBlock
                                    {
                                        Text = nominatedDetails?.AwardName,
                                        Wrap = true,
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                                        Weight = AdaptiveTextWeight.Bolder,
                                        Size   = AdaptiveTextSize.Large,
                                    },
                                },
                            },
                            new AdaptiveColumn
                            {
                                Width = AdaptiveColumnWidth.Auto,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveImage
                                    {
                                        Url = string.IsNullOrEmpty(nominatedDetails.AwardLink) ? new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/Content/DefaultAwardImage.png", applicationBasePath?.Trim('/'))) : new Uri(nominatedDetails.AwardLink),
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Right,
                                        PixelHeight         = PixelHeight,
                                        PixelWidth          = PixelWidth,
                                    },
                                },
                            },
                        },
                    },
                    new AdaptiveTextBlock
                    {
                        Text = nominatedDetails.NominatedToName,
                        Wrap = true,
                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                        Weight  = AdaptiveTextWeight.Bolder,
                        Spacing = AdaptiveSpacing.Large,
                    },
                    new AdaptiveTextBlock
                    {
                        Text = localizer.GetString("NominatedByText", nominatedDetails.NominatedByName),
                        Wrap = true,
                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                        Spacing             = AdaptiveSpacing.Default,
                    },
                    new AdaptiveTextBlock
                    {
                        Text = nominatedDetails.ReasonForNomination,
                        Wrap = true,
                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                        Spacing             = AdaptiveSpacing.Default,
                    },
                },
                Actions = new List <AdaptiveAction>
                {
                    new AdaptiveSubmitAction
                    {
                        Title = localizer.GetString("EndorseButtonText"),
                        Data  = new AdaptiveCardAction
                        {
                            MsteamsCardAction = new CardAction
                            {
                                Type = Constants.FetchActionType,
                            },
                            Command = Constants.EndorseAction,
                            NominatedToPrincipalName = nominatedDetails.NominatedToPrincipalName,
                            AwardName           = nominatedDetails.AwardName,
                            NominatedToName     = nominatedDetails.NominatedToName,
                            NominatedToObjectId = nominatedDetails.NominatedToObjectId,
                            AwardId             = nominatedDetails.AwardId,
                            RewardCycleId       = nominatedDetails.RewardCycleId,
                        },
                    },
                },
            };

            return(new Attachment
            {
                ContentType = AdaptiveCard.ContentType,
                Content = card,
            });
        }
        /// <summary>
        /// This method will construct endorse card with corresponding details.
        /// </summary>
        /// <param name="applicationBasePath">Application base URL.</param>
        /// <param name="localizer">The current cultures' string localizer.</param>
        /// <param name="nominatedDetails">Nominated details to show in card.</param>
        /// <returns>Endorse card with nominated details.</returns>
        public static Attachment GetEndorseCard(string applicationBasePath, IStringLocalizer <Strings> localizer, TaskModuleResponseDetails nominatedDetails)
        {
            nominatedDetails = nominatedDetails ?? throw new ArgumentNullException(nameof(nominatedDetails));

            AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(Constants.AdaptiveCardVersion))
            {
                Body = new List <AdaptiveElement>
                {
                    new AdaptiveColumnSet
                    {
                        Columns = new List <AdaptiveColumn>
                        {
                            new AdaptiveColumn
                            {
                                Width = AdaptiveColumnWidth.Stretch,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveTextBlock
                                    {
                                        Text = nominatedDetails.AwardName,
                                        Wrap = true,
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                                        Weight = AdaptiveTextWeight.Bolder,
                                        Size   = AdaptiveTextSize.Large,
                                    },
                                },
                            },
                            new AdaptiveColumn
                            {
                                Width = AdaptiveColumnWidth.Auto,
                                Items = new List <AdaptiveElement>
                                {
                                    new AdaptiveImage
                                    {
                                        Url = string.IsNullOrEmpty(nominatedDetails.AwardLink) ? new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/Content/DefaultAwardImage.png", applicationBasePath)) : new Uri(nominatedDetails.AwardLink),
                                        HorizontalAlignment = AdaptiveHorizontalAlignment.Right,
                                        PixelHeight         = AwardImagePixelHeight,
                                        PixelWidth          = AwardImagePixelWidth,
                                    },
                                },
                            },
                        },
                    },
                    new AdaptiveTextBlock
                    {
                        Text = string.Join(", ", JsonConvert.DeserializeObject <List <string> >(nominatedDetails.GroupName)),
                        Wrap = true,
                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                        Weight  = AdaptiveTextWeight.Bolder,
                        Spacing = AdaptiveSpacing.Large,
                    },
                    new AdaptiveTextBlock
                    {
                        Text = localizer.GetString("NominatedByText", nominatedDetails.NominatedByName),
                        Wrap = true,
                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                        Spacing             = AdaptiveSpacing.Default,
                    },
                    new AdaptiveTextBlock
                    {
                        Text = nominatedDetails.ReasonForNomination,
                        Wrap = true,
                        HorizontalAlignment = AdaptiveHorizontalAlignment.Left,
                        Spacing             = AdaptiveSpacing.Default,
                    },
                },
            };

            return(new Attachment
            {
                ContentType = AdaptiveCard.ContentType,
                Content = card,
            });
        }
        /// <summary>
        /// Send the given attachment to the specified team.
        /// </summary>
        /// <param name="rewardCycleEntity">Reward cycle model object.</param>
        /// <returns>A task that sends notification card in channel.</returns>
        private async Task SendCardToTeamAsync(RewardCycleEntity rewardCycleEntity)
        {
            try
            {
                var awardsList = await this.awardsStorageProvider.GetAwardsAsync(rewardCycleEntity.TeamId);

                var valuesfromTaskModule = new TaskModuleResponseDetails()
                {
                    RewardCycleStartDate = rewardCycleEntity.RewardCycleStartDate,
                    RewardCycleEndDate   = rewardCycleEntity.RewardCycleEndDate,
                    RewardCycleId        = rewardCycleEntity.CycleId,
                };

                var teamDetails = await this.teamStorageProvider.GetTeamDetailAsync(rewardCycleEntity.TeamId);

                string serviceUrl = teamDetails.ServiceUrl;

                MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
                string teamsChannelId = rewardCycleEntity.TeamId;

                var conversationReference = new ConversationReference()
                {
                    ChannelId = Channel,
                    Bot       = new ChannelAccount()
                    {
                        Id = this.microsoftAppCredentials.MicrosoftAppId
                    },
                    ServiceUrl   = serviceUrl,
                    Conversation = new ConversationAccount()
                    {
                        ConversationType = ChannelConversationType, IsGroup = true, Id = teamsChannelId, TenantId = teamsChannelId
                    },
                };

                this.logger.LogInformation($"sending notification to channelId- {teamsChannelId}");

                await retryPolicy.ExecuteAsync(async() =>
                {
                    try
                    {
                        var conversationParameters = new ConversationParameters()
                        {
                            ChannelData = new TeamsChannelData()
                            {
                                Team = new TeamInfo()
                                {
                                    Id = rewardCycleEntity.TeamId
                                }, Channel = new ChannelInfo()
                                {
                                    Id = rewardCycleEntity.TeamId
                                }
                            },
                            Activity = (Activity)MessageFactory.Carousel(NominateCarouselCard.GetAwardsCard(this.options.Value.AppBaseUri, awardsList, this.localizer, valuesfromTaskModule)),
                            Bot      = new ChannelAccount()
                            {
                                Id = this.microsoftAppCredentials.MicrosoftAppId
                            },
                            IsGroup  = true,
                            TenantId = this.options.Value.TenantId,
                        };

                        await((BotFrameworkAdapter)this.adapter).CreateConversationAsync(
                            Channel,
                            serviceUrl,
                            this.microsoftAppCredentials,
                            conversationParameters,
                            async(conversationTurnContext, conversationCancellationToken) =>
                        {
                            Activity mentionActivity = MessageFactory.Text(this.localizer.GetString("NominationReminderNotificationText"));
                            await((BotFrameworkAdapter)this.adapter).ContinueConversationAsync(
                                this.microsoftAppCredentials.MicrosoftAppId,
                                conversationTurnContext.Activity.GetConversationReference(),
                                async(continueConversationTurnContext, continueConversationCancellationToken) =>
                            {
                                mentionActivity.ApplyConversationReference(conversationTurnContext.Activity.GetConversationReference());
                                await continueConversationTurnContext.SendActivityAsync(mentionActivity, continueConversationCancellationToken);
                            }, conversationCancellationToken);
                        },
                            default);
                    }
                    catch (Exception ex)
                    {
                        this.logger.LogError(ex, "Error while performing retry logic to send notification to channel.");
                        throw;
                    }
                });
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, "Error while sending notification to channel from background service.");
            }
        }