├── .deployment ├── .github └── policies │ └── resourceManagement.yml ├── .gitignore ├── .travis.yml ├── Build └── UserExclusion.xml ├── CompanyCommunicator_Context.tm7 ├── Deployment ├── AadAppManifest.json ├── AadOptionalClaims.json ├── AadOptionalClaims_Reset.json ├── DOD │ └── azuredeploy.json ├── GCC │ ├── botazuredeploy.json │ └── otherresourcesazuredeploy.json ├── GCCH │ └── azuredeploy.json ├── applicationinsights-migration.ps1 ├── azuredeploy.json ├── azuredeploywithcert.json ├── deploy.ps1 ├── dotnet6-migration.ps1 └── parameters.json ├── LICENSE ├── Manifest ├── color.png ├── manifest_authors.json ├── manifest_users.json └── outline.png ├── README.md ├── SECURITY.md ├── Source ├── .dockerignore ├── CompanyCommunicator.Common │ ├── Adapter │ │ ├── CCBotAdapter.cs │ │ ├── CCBotAdapterBase.cs │ │ ├── CCBotFrameworkHttpAdapter.cs │ │ └── ICCBotFrameworkHttpAdapter.cs │ ├── Clients │ │ ├── IStorageClientFactory.cs │ │ └── StorageClientFactory.cs │ ├── Configuration │ │ ├── CommericalConfiguration.cs │ │ ├── ConfigurationFactory.cs │ │ ├── DODConfiguration.cs │ │ ├── GCCHConfiguration.cs │ │ ├── IAppConfiguration.cs │ │ └── TeamsEnvironment.cs │ ├── Constants.cs │ ├── Extensions │ │ ├── EnumerableExtensions.cs │ │ ├── NotificationDataExtensions.cs │ │ ├── SendQueueMessageContentExtensions.cs │ │ ├── ServiceCollectionExtension.cs │ │ ├── StringExtensions.cs │ │ └── UserExtensions.cs │ ├── Microsoft.Teams.Apps.CompanyCommunicator.Common.csproj │ ├── Policies │ │ └── PollyPolicy.cs │ ├── Repositories │ │ ├── AppConfig │ │ │ ├── AppConfigEntity.cs │ │ │ ├── AppConfigRepository.cs │ │ │ ├── AppConfigTableName.cs │ │ │ └── IAppConfigRepository.cs │ │ ├── BaseRepository.cs │ │ ├── CleanUpHistory │ │ │ ├── CleanUpHistoryEntity.cs │ │ │ ├── CleanUpHistoryRepository.cs │ │ │ ├── CleanUpHistoryTableName.cs │ │ │ ├── CleanUpStatus.cs │ │ │ ├── DeleteMessage.cs │ │ │ └── ICleanUpHistoryRepository.cs │ │ ├── ExportData │ │ │ ├── ExportDataEntity.cs │ │ │ ├── ExportDataRepository.cs │ │ │ ├── ExportDataTableName.cs │ │ │ ├── ExportStatus.cs │ │ │ └── IExportDataRepository.cs │ │ ├── IRepository.cs │ │ ├── NotificationData │ │ │ ├── GlobalSendingNotificationDataEntity.cs │ │ │ ├── GlobalSendingNotificationDataRepository.cs │ │ │ ├── IGlobalSendingNotificationDataRepository.cs │ │ │ ├── INotificationDataRepository.cs │ │ │ ├── ISendingNotificationDataRepository.cs │ │ │ ├── NotificationDataEntity.cs │ │ │ ├── NotificationDataRepository.cs │ │ │ ├── NotificationDataTableNames.cs │ │ │ ├── NotificationStatus.cs │ │ │ ├── SendingNotificationDataEntity.cs │ │ │ └── SendingNotificationDataRepository.cs │ │ ├── RepositoryOptions.cs │ │ ├── SentNotificationData │ │ │ ├── ISentNotificationDataRepository.cs │ │ │ ├── SentNotificationDataEntity.cs │ │ │ ├── SentNotificationDataRepository.cs │ │ │ └── SentNotificationDataTableNames.cs │ │ ├── TableRowKeyGenerator.cs │ │ ├── TeamData │ │ │ ├── ITeamDataRepository.cs │ │ │ ├── TeamDataEntity.cs │ │ │ ├── TeamDataRepository.cs │ │ │ └── TeamDataTableNames.cs │ │ └── UserData │ │ │ ├── IUserDataRepository.cs │ │ │ ├── UserDataEntity.cs │ │ │ ├── UserDataRepository.cs │ │ │ ├── UserDataTableNames.cs │ │ │ └── UsersSyncEntity.cs │ ├── Resources │ │ ├── LocaleOptions.cs │ │ ├── Strings.Designer.cs │ │ ├── Strings.ar-SA.resx │ │ ├── Strings.de-DE.resx │ │ ├── Strings.es-ES.resx │ │ ├── Strings.fr-FR.resx │ │ ├── Strings.he-IL.resx │ │ ├── Strings.ja-JP.resx │ │ ├── Strings.ko-KR.resx │ │ ├── Strings.pl-PL.Designer.cs │ │ ├── Strings.pl-PL.resx │ │ ├── Strings.pt-BR.resx │ │ ├── Strings.qps-ploc.resx │ │ ├── Strings.qps-ploca.resx │ │ ├── Strings.qps-plocm.resx │ │ ├── Strings.resx │ │ ├── Strings.ru-RU.resx │ │ ├── Strings.zh-CN.resx │ │ └── Strings.zh-TW.resx │ ├── Secrets │ │ ├── Cache.cs │ │ ├── CachedResponse.cs │ │ ├── CertificateProvider.cs │ │ ├── ICertificateProvider.cs │ │ ├── KeyVaultProxy.cs │ │ └── SecretsRegistry.cs │ ├── Services │ │ ├── AdaptiveCard │ │ │ ├── AdaptiveCardCreator.cs │ │ │ └── AdaptiveImageWithLongUrl.cs │ │ ├── App │ │ │ ├── AppSettingsService.cs │ │ │ └── IAppSettingsService.cs │ │ ├── Blob │ │ │ ├── BlobStorageProvider.cs │ │ │ └── IBlobStorageProvider.cs │ │ ├── CommonBot │ │ │ ├── AuthorAppCredentials.cs │ │ │ ├── BotOptions.cs │ │ │ ├── ConfigurationCredentialProvider.cs │ │ │ └── UserAppCredentials.cs │ │ ├── MessageQueues │ │ │ ├── BaseQueue.cs │ │ │ ├── DataQueue │ │ │ │ ├── DataQueue.cs │ │ │ │ ├── DataQueueMessageContent.cs │ │ │ │ └── IDataQueue.cs │ │ │ ├── ExportQueue │ │ │ │ ├── ExportQueue.cs │ │ │ │ ├── ExportQueueMessageContent.cs │ │ │ │ └── IExportQueue.cs │ │ │ ├── IBaseQueue.cs │ │ │ ├── PrepareToSendQueue │ │ │ │ ├── IPrepareToSendQueue.cs │ │ │ │ ├── PrepareToSendQueue.cs │ │ │ │ └── PrepareToSendQueueMessageContent.cs │ │ │ └── SendQueue │ │ │ │ ├── ISendQueue.cs │ │ │ │ ├── RecipientData.cs │ │ │ │ ├── RecipientDataType.cs │ │ │ │ ├── SendQueue.cs │ │ │ │ └── SendQueueMessageContent.cs │ │ ├── MicrosoftGraph │ │ │ ├── Authentication │ │ │ │ └── MsalAuthenticationProvider.cs │ │ │ ├── Factory │ │ │ │ ├── GraphServiceFactory.cs │ │ │ │ └── IGraphServiceFactory.cs │ │ │ ├── GraphConstants.cs │ │ │ ├── GraphPermissionType.cs │ │ │ ├── GroupMembers │ │ │ │ ├── GroupMembersService.cs │ │ │ │ └── IGroupMembersService.cs │ │ │ ├── Groups │ │ │ │ ├── GroupExtensions.cs │ │ │ │ ├── GroupsService.cs │ │ │ │ └── IGroupsService.cs │ │ │ ├── TeamWork │ │ │ │ ├── AppCatalogService.cs │ │ │ │ ├── AppManagerService.cs │ │ │ │ ├── ChatsService.cs │ │ │ │ ├── IAppCatalogService.cs │ │ │ │ ├── IAppManagerService.cs │ │ │ │ └── IChatsService.cs │ │ │ ├── UserType.cs │ │ │ └── Users │ │ │ │ ├── IUsersService.cs │ │ │ │ └── UsersService.cs │ │ ├── Recipients │ │ │ ├── IRecipientsService.cs │ │ │ ├── RecipientsInfo.cs │ │ │ └── RecipientsService.cs │ │ ├── Teams │ │ │ ├── Conversations │ │ │ │ ├── ConversationService.cs │ │ │ │ ├── CreateConversationResponse.cs │ │ │ │ ├── IConversationService.cs │ │ │ │ └── Result.cs │ │ │ ├── Messages │ │ │ │ ├── IMessageService.cs │ │ │ │ ├── MessageService.cs │ │ │ │ ├── SendMessageResponse.cs │ │ │ │ └── SendMessageResult.cs │ │ │ └── TeamMembers │ │ │ │ ├── ITeamMembersService.cs │ │ │ │ └── TeamMembersService.cs │ │ └── User │ │ │ ├── IUserDataService.cs │ │ │ ├── IUserTypeService.cs │ │ │ ├── UserDataService.cs │ │ │ └── UserTypeService.cs │ └── Utilities │ │ └── PartitionKeyUtility.cs ├── CompanyCommunicator.Data.Func │ ├── CleanUpFileOptions.cs │ ├── CompanyCommunicatorCleanUpFunction.cs │ ├── CompanyCommunicatorDataCleanUpFunction.cs │ ├── CompanyCommunicatorDataFunction.cs │ ├── DataQueueMessageOptions.cs │ ├── Dockerfile │ ├── Microsoft.Teams.Apps.CompanyCommunicator.Data.Func.csproj │ ├── Services │ │ ├── DataCleanUpServices │ │ │ ├── IPartitionKeyHandler.cs │ │ │ └── PartitionKeyHandlerService.cs │ │ ├── FileCardServices │ │ │ ├── FileCardService.cs │ │ │ └── IFileCardService.cs │ │ └── NotificationDataServices │ │ │ ├── AggregateSentNotificationDataService.cs │ │ │ ├── AggregatedSentNotificationDataResults.cs │ │ │ ├── OrchestrationStatus.cs │ │ │ ├── OrchestrationStatusResponse.cs │ │ │ ├── UpdateNotificationDataEntity.cs │ │ │ └── UpdateNotificationDataService.cs │ ├── Startup.cs │ └── host.json ├── CompanyCommunicator.Prep.Func │ ├── Dockerfile │ ├── Export │ │ ├── Activities │ │ │ ├── GetMetadataActivity.cs │ │ │ ├── HandleExportFailureActivity.cs │ │ │ ├── SendFileCardActivity.cs │ │ │ ├── UpdateExportDataActivity.cs │ │ │ └── UploadActivity.cs │ │ ├── ExportFunction.cs │ │ ├── Mappers │ │ │ ├── MetadataMap.cs │ │ │ ├── TeamDataMap.cs │ │ │ └── UserDataMap.cs │ │ ├── Model │ │ │ ├── Error.cs │ │ │ ├── ExportDataRequirement.cs │ │ │ ├── ExportMessageQueueContent.cs │ │ │ ├── Metadata.cs │ │ │ ├── RootErrorMessage.cs │ │ │ ├── TeamData.cs │ │ │ └── UserData.cs │ │ ├── Orchestrator │ │ │ └── ExportOrchestration.cs │ │ └── Streams │ │ │ ├── DataStreamFacade.cs │ │ │ └── IDataStreamFacade.cs │ ├── Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.csproj │ ├── PreparingToSend │ │ ├── Activities │ │ │ ├── DataAggregationTriggerActivity.cs │ │ │ ├── HandleFailureActivity.cs │ │ │ ├── RecipientsActivity.cs │ │ │ ├── SendBatchMessagesActivity.cs │ │ │ ├── StoreMessageActivity.cs │ │ │ ├── SyncAllUsersActivity.cs │ │ │ ├── SyncGroupMembersActivity.cs │ │ │ ├── SyncTeamMembersActivity.cs │ │ │ ├── SyncTeamsActivity.cs │ │ │ ├── TeamsConversationActivity.cs │ │ │ └── UpdateNotificationStatusActivity.cs │ │ ├── DataQueueMessageOptions.cs │ │ ├── Extensions │ │ │ └── UserDataEntityExtensions.cs │ │ ├── FunctionNames.cs │ │ ├── FunctionSettings.cs │ │ ├── Orchestrators │ │ │ ├── PrepareToSendOrchestrator.cs │ │ │ ├── SendQueueOrchestrator.cs │ │ │ ├── SyncRecipientsOrchestrator.cs │ │ │ └── TeamsConversationOrchestrator.cs │ │ ├── PrepareToSendFunction.cs │ │ └── TeamsConversationOptions.cs │ ├── Startup.cs │ └── host.json ├── CompanyCommunicator.Send.Func │ ├── Dockerfile │ ├── Microsoft.Teams.Apps.CompanyCommunicator.Send.Func.csproj │ ├── ScheduleSendFunction.cs │ ├── SendFunction.cs │ ├── SendFunctionOptions.cs │ ├── Services │ │ ├── INotificationService.cs │ │ └── NotificationService.cs │ ├── Startup.cs │ └── host.json ├── CompanyCommunicator │ ├── Authentication │ │ ├── AuthenticationOptions.cs │ │ ├── AuthenticationServiceCollectionExtensions.cs │ │ ├── GraphTokenProvider.cs │ │ ├── MSGraphScopeHandler.cs │ │ ├── MSGraphScopeRequirement.cs │ │ ├── MustBeValidDeleteUpnHandler.cs │ │ ├── MustBeValidDeleteUpnRequirement.cs │ │ ├── MustBeValidUpnHandler.cs │ │ ├── MustBeValidUpnRequirement.cs │ │ └── PolicyNames.cs │ ├── Bot │ │ ├── AuthorTeamsActivityHandler.cs │ │ ├── BotFilterMiddlewareOptions.cs │ │ ├── CompanyCommunicatorBotAdapter.cs │ │ ├── CompanyCommunicatorBotFilterMiddleware.cs │ │ ├── TeamsDataCapture.cs │ │ ├── TeamsFileUpload.cs │ │ └── UserTeamsActivityHandler.cs │ ├── ClientApp │ │ ├── .eslintrc.json │ │ ├── .gitignore │ │ ├── README.md │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── image │ │ │ │ └── imagePlaceholder.png │ │ │ ├── index.html │ │ │ ├── locales │ │ │ │ ├── ar-SA │ │ │ │ │ └── translation.json │ │ │ │ ├── de-DE │ │ │ │ │ └── translation.json │ │ │ │ ├── en-US │ │ │ │ │ └── translation.json │ │ │ │ ├── es-ES │ │ │ │ │ └── translation.json │ │ │ │ ├── fr-FR │ │ │ │ │ └── translation.json │ │ │ │ ├── he-IL │ │ │ │ │ └── translation.json │ │ │ │ ├── ja-JP │ │ │ │ │ └── translation.json │ │ │ │ ├── ko-KR │ │ │ │ │ └── translation.json │ │ │ │ ├── pl-PL │ │ │ │ │ └── translation.json │ │ │ │ ├── pt-BR │ │ │ │ │ └── translation.json │ │ │ │ ├── qps-ploc │ │ │ │ │ └── translation.json │ │ │ │ ├── qps-ploca │ │ │ │ │ └── translation.json │ │ │ │ ├── qps-plocm │ │ │ │ │ └── translation.json │ │ │ │ ├── ru-RU │ │ │ │ │ └── translation.json │ │ │ │ ├── zh-CN │ │ │ │ │ └── translation.json │ │ │ │ └── zh-TW │ │ │ │ │ └── translation.json │ │ │ └── manifest.json │ │ ├── src │ │ │ ├── App.scss │ │ │ ├── App.test.tsx │ │ │ ├── App.tsx │ │ │ ├── actions.ts │ │ │ ├── apis │ │ │ │ ├── apiDecorator.ts │ │ │ │ └── messageListApi.ts │ │ │ ├── assets │ │ │ │ └── Images │ │ │ │ │ ├── FeedbackIcon.svg │ │ │ │ │ ├── HelpIcon.svg │ │ │ │ │ ├── InfoIcon.svg │ │ │ │ │ └── mslogo.png │ │ │ ├── components │ │ │ │ ├── AdaptiveCard │ │ │ │ │ └── adaptiveCard.ts │ │ │ │ ├── DeleteMessages │ │ │ │ │ ├── deleteConfirmationTask.tsx │ │ │ │ │ ├── deleteMessage.scss │ │ │ │ │ ├── deleteMessages.tsx │ │ │ │ │ └── deleteMessagesDetail.tsx │ │ │ │ ├── DraftMessages │ │ │ │ │ ├── draftMessageDetail.tsx │ │ │ │ │ └── draftMessages.tsx │ │ │ │ ├── ErrorPage │ │ │ │ │ ├── errorPage.scss │ │ │ │ │ └── errorPage.tsx │ │ │ │ ├── Home │ │ │ │ │ └── homePage.tsx │ │ │ │ ├── NewMessage │ │ │ │ │ ├── newMessage.scss │ │ │ │ │ └── newMessage.tsx │ │ │ │ ├── PreviewMessageConfirmation │ │ │ │ │ └── previewMessageConfirmation.tsx │ │ │ │ ├── ScheduledMessages │ │ │ │ │ ├── scheduledMessageDetail.tsx │ │ │ │ │ └── scheduledMessages.tsx │ │ │ │ ├── SendConfirmationTask │ │ │ │ │ └── sendConfirmationTask.tsx │ │ │ │ ├── SentMessages │ │ │ │ │ ├── sentMessageDetail.tsx │ │ │ │ │ └── sentMessages.tsx │ │ │ │ ├── Shared │ │ │ │ │ ├── header.tsx │ │ │ │ │ └── main.scss │ │ │ │ ├── SignInPage │ │ │ │ │ ├── signInPage.scss │ │ │ │ │ ├── signInPage.tsx │ │ │ │ │ ├── signInSimpleEnd.tsx │ │ │ │ │ └── signInSimpleStart.tsx │ │ │ │ ├── ViewStatusTask │ │ │ │ │ └── viewStatusTask.tsx │ │ │ │ └── config.tsx │ │ │ ├── configVariables.ts │ │ │ ├── i18n.ts │ │ │ ├── index.tsx │ │ │ ├── logo.svg │ │ │ ├── messagesSlice.ts │ │ │ ├── models │ │ │ │ └── deleteMessages.ts │ │ │ ├── react-app-env.d.ts │ │ │ ├── routes.ts │ │ │ ├── store.ts │ │ │ └── useInterval.tsx │ │ └── tsconfig.json │ ├── Connected Services │ │ └── Application Insights │ │ │ └── ConnectedService.json │ ├── Controllers │ │ ├── AuthenticationMetadataController.cs │ │ ├── BotController.cs │ │ ├── DataQueueMessageOptions.cs │ │ ├── DeleteMessagesController.cs │ │ ├── DraftNotificationsController.cs │ │ ├── ExportController.cs │ │ ├── GroupDataController.cs │ │ ├── HealthController.cs │ │ ├── Options │ │ │ └── UserAppOptions.cs │ │ ├── SentNotificationsController.cs │ │ └── TeamDataController.cs │ ├── Dockerfile │ ├── DraftNotificationPreview │ │ ├── DraftNotificationPreviewService.cs │ │ └── IDraftNotificationPreviewService.cs │ ├── Localization │ │ ├── LocalizationServiceCollectionExtensions.cs │ │ └── RequestCultureProvider.cs │ ├── Microsoft.Teams.Apps.CompanyCommunicator.csproj │ ├── Models │ │ ├── BaseNotification.cs │ │ ├── DeleteHistoricalMessages.cs │ │ ├── DraftNotification.cs │ │ ├── DraftNotificationPreviewRequest.cs │ │ ├── DraftNotificationSummary.cs │ │ ├── DraftNotificationSummaryForConsent.cs │ │ ├── ExportRequest.cs │ │ ├── GroupData.cs │ │ ├── SentNotification.cs │ │ ├── SentNotificationSummary.cs │ │ └── TeamData.cs │ ├── Pages │ │ ├── Error.cshtml │ │ ├── Error.cshtml.cs │ │ └── _ViewImports.cshtml │ ├── Program.cs │ ├── Repositories │ │ └── Extensions │ │ │ ├── NotificationRepositoryExtensions.cs │ │ │ └── TeamDataRepositoryExtensions.cs │ ├── Startup.cs │ └── appsettings.json ├── Microsoft.Teams.Apps.CompanyCommunicator.sln ├── Test │ ├── CompanyCommunicator.Common.Test │ │ ├── Extensions │ │ │ ├── EnumerableExtensionsTest.cs │ │ │ └── StringExtensionsTest.cs │ │ ├── Microsoft.Teams.App.CompanyCommunicator.Common.Test.csproj │ │ ├── Repositories │ │ │ └── NotificationData │ │ │ │ └── NotificationDataRepositoryTests.cs │ │ ├── Services │ │ │ ├── MicrosoftGraph │ │ │ │ ├── UserTypeServiceTest.cs │ │ │ │ └── UsersServiceTests.cs │ │ │ ├── Mock │ │ │ │ ├── MockAuthenticationHelper.cs │ │ │ │ └── MockHttpProvider.cs │ │ │ └── Recipients │ │ │ │ └── RecipientsServiceTest.cs │ │ ├── Utilities │ │ │ └── PartitionKeyUtilityTest.cs │ │ └── stylecop.json │ ├── CompanyCommunicator.Prep.Func.Test │ │ ├── Export │ │ │ ├── Activities │ │ │ │ ├── GetMetadataActivityTest.cs │ │ │ │ ├── HandleExportFailureActivityTest.cs │ │ │ │ ├── SendFileCardActivityTest.cs │ │ │ │ ├── UpdateExportDataActivityTest.cs │ │ │ │ └── UploadActivityTest.cs │ │ │ ├── ExportFunctionTest.cs │ │ │ └── Streams │ │ │ │ └── DataStreamFacadeTest.cs │ │ ├── Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Test.csproj │ │ └── PreparingToSend │ │ │ ├── Activities │ │ │ ├── DataAggregationTriggerActivityTest.cs │ │ │ ├── HandleFailureActivityTest.cs │ │ │ ├── RecipientsActivityTest.cs │ │ │ ├── SendBatchMessagesActivityTest.cs │ │ │ ├── StoreMessageActivityTest.cs │ │ │ ├── SyncAllUsersActivityTest.cs │ │ │ ├── SyncGroupMembersActivityTest.cs │ │ │ ├── SyncTeamMembersActivityTest.cs │ │ │ ├── SyncTeamsActivityTest.cs │ │ │ ├── TeamsConversationActivityTest.cs │ │ │ └── UpdateNotificationStatusActivityTest.cs │ │ │ ├── Orchestrators │ │ │ ├── PrepareToSendOrchestratorTest.cs │ │ │ ├── SendQueueOrchestratorTest.cs │ │ │ ├── SyncRecipientsOrchestratorTest.cs │ │ │ └── TeamsConversationOrchestratorTest.cs │ │ │ └── PrepareToSendFunctionTest.cs │ ├── CompanyCommunicator.Send.Func.Test │ │ ├── Microsoft.Teams.Apps.CompanyCommunicator.Send.Func.Test.csproj │ │ ├── SendFunctionTest.cs │ │ └── Services │ │ │ └── NotificationServiceTest.cs │ └── CompanyCommunicator.Test │ │ ├── Controllers │ │ ├── AuthenticationMetadataControllerTest.cs │ │ ├── DraftNotificationsControllerTest.cs │ │ ├── ExportControllerTest.cs │ │ ├── GroupDataControllerTest.cs │ │ ├── HealthControllerTest.cs │ │ ├── SentNotificationsControllerTest.cs │ │ └── TeamDataControllerTest.cs │ │ ├── Microsoft.Teams.Apps.CompanyCommunicator.Test.csproj │ │ └── stylecop.json ├── nuget.config └── stylecop.json ├── Support ├── Check-AppRegistrations.ps1 ├── Check-GraphApp.ps1 ├── Start-ChatWithSpecifiedUser.ps1 └── readme.md ├── Wiki ├── Authorization-issue-fix.md ├── Cost-estimate.md ├── Custom-domain-option.md ├── Data-stores.md ├── Deployment-guide-certificate.md ├── Deployment-guide-dod.md ├── Deployment-guide-gcch.md ├── Deployment-guide-powershell.md ├── Deployment-guide.md ├── FAQ.md ├── Home.md ├── Known-limitations.md ├── Localization.md ├── Migration-guide.md ├── Release-notes.md ├── Scale-app.md ├── Solution-overview.md ├── Support-policy.md ├── Taking-it-further.md ├── Telemetry.md ├── Troubleshooting-powershell-script.md ├── Troubleshooting.md ├── User-manual.md ├── images │ ├── ARM-Deployment-Timeout.png │ ├── CompanyCommunicatorCompose.png │ ├── admin_consent.png │ ├── admin_consent_error.png │ ├── admin_consent_url.png │ ├── appinsights-migration-execution.png │ ├── appservice-dotnet-version.png │ ├── appservice_sync_deployment_error.png │ ├── appservice_sync_error_fix.png │ ├── architecture_overview_v1.png │ ├── architecture_overview_v2.png │ ├── architecture_overview_v4.png │ ├── authorization_fail.png │ ├── azure-config-app-step3.png │ ├── azure_cli.png │ ├── azurefunctions_runtime_version.png │ ├── botchanneldod_1.png │ ├── botchannelgovernment_1.png │ ├── botchannelgovernment_2.png │ ├── botchannelgovernment_3.png │ ├── check_modules.png │ ├── company-communicator-compose.png │ ├── create-certificate.png │ ├── create-log-analytics.png │ ├── delete_application_uri.png │ ├── deploybutton.png │ ├── deployment_success.png │ ├── disable_routing_rule.png │ ├── dotnet_upgrade_execution.png │ ├── draft-message.png │ ├── export-cert.png │ ├── file-explorer.png │ ├── frontdoor_designer.png │ ├── go_back_main_window.png │ ├── graph_permissions_access.png │ ├── import-app-service-cert-finished.png │ ├── import-key-vault-cert.png │ ├── log-analytics-overview-page.png │ ├── log_folder.png │ ├── login_screen_first.png │ ├── login_screen_second.png │ ├── manifest_folder.png │ ├── migrate-appinsights.png │ ├── migrated-appinsights-overview.png │ ├── multitenant_app_creation.png │ ├── multitenant_app_overview_1.png │ ├── multitenant_app_overview_2.png │ ├── multitenant_app_permissions_1.png │ ├── multitenant_app_permissions_2.png │ ├── multitenant_app_secret.png │ ├── param_file.png │ ├── postdeployment_output.png │ ├── powershell_deployment_error.png │ ├── remove_permission.png │ ├── resource_availability.png │ ├── send-options.png │ ├── sent-messages.png │ ├── set_application_uri.png │ ├── single_tenant_app_creation.png │ ├── single_tenant_app_overview.png │ ├── single_tenant_app_secret.png │ ├── support-banner.png │ ├── sync_changes.png │ ├── tab_name_change_cc.png │ ├── troubleshooting_appservicesyncerror_1.png │ ├── troubleshooting_appservicesyncerror_2.png │ ├── troubleshooting_appservicesyncerror_3.png │ ├── troubleshooting_deltalinkerror.png │ ├── troubleshooting_permissionerror.png │ ├── troubleshooting_roleassignmenterror.png │ ├── troubleshooting_sourcecontrols.png │ ├── troubleshooting_teamsnamesemptyerror.png │ ├── update_ad_app.png │ ├── update_author_list.png │ ├── update_banner_title_logo.png │ ├── upload_certificate.png │ ├── version_app.png │ └── warning_message.png ├── v2-migration-guide.md ├── v3-migration-guide.md ├── v4-migration-guide.md └── v5-migration-guide.md ├── azure-pipelines.yml ├── deploy.app.cmd ├── deploy.cmd ├── deploy.function.cmd └── global.json /.deployment: -------------------------------------------------------------------------------- 1 | [config] 2 | command = deploy.cmd 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | dist: bionic 3 | sudo: false 4 | env: 5 | global: 6 | - ORG="OfficeDev" 7 | - REPO_SOURCE="microsoft-teams-company-communicator-app" 8 | - REPO_DEST="${REPO_SOURCE}.wiki" 9 | - GH_REPO_DEST="github.com/${ORG}/${REPO_DEST}.git" 10 | - GH_REPO_CONSOLIDATE="github.com/${ORG}/${REPO_SOURCE}.git" 11 | install: skip 12 | stages: 13 | - name: WikiUpdate 14 | jobs: 15 | include: 16 | - stage: WikiUpdate 17 | if: (branch = main) AND (type = push) 18 | script: 19 | - rm -rf ${REPO_SOURCE} 20 | - rm -rf ${REPO_DEST} 21 | # Clone repositories 22 | - git clone https://${GH_REPO_DEST} 23 | - git clone https://${GH_REPO_CONSOLIDATE} 24 | # Update wiki repository with wiki folder contents 25 | - yes | cp -rf ${REPO_SOURCE}/Wiki/* ${REPO_DEST}/ 26 | - cd ${REPO_DEST} 27 | # Terminate Travis CI build when no changes detected 28 | - | 29 | if git diff-index --quiet HEAD && [ ! -n "$(git status -s)" ]; then 30 | set +e 31 | pkill -9 -P $$ &> /dev/null || true 32 | exit 0 33 | else 34 | git config user.email ${EMAIL} 35 | git config user.name ${USER} 36 | git status 37 | git add . 38 | git commit -m "${REPO_SOURCE} Wiki Update | Travis CI build number $TRAVIS_BUILD_NUMBER" 39 | git remote add origin-wiki "https://${USER}:${GITHUB_TOKEN}@${GH_REPO_DEST}" 40 | git push origin-wiki main 41 | fi -------------------------------------------------------------------------------- /Build/UserExclusion.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | NODE_MODULES|BUILD 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Deployment/AadAppManifest.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "resourceAppId": "00000003-0000-0000-c000-000000000000", 4 | "resourceAccess": [ 5 | { 6 | "id": "bc024368-1153-4739-b217-4326f2e966d0", 7 | "type": "Scope" 8 | }, 9 | { 10 | "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", 11 | "type": "Scope" 12 | }, 13 | { 14 | "id": "88e58d74-d3df-44f3-ad47-e89edf4472e4", 15 | "type": "Scope" 16 | }, 17 | { 18 | "id": "98830695-27a2-44f7-8c18-0c3ebc9698f6", 19 | "type": "Role" 20 | }, 21 | { 22 | "id": "df021288-bdef-4463-88db-98f22de89214", 23 | "type": "Role" 24 | }, 25 | { 26 | "id": "74ef0291-ca83-4d02-8c7e-d2391e6a444f", 27 | "type": "Role" 28 | } 29 | ] 30 | } 31 | ] 32 | -------------------------------------------------------------------------------- /Deployment/AadOptionalClaims.json: -------------------------------------------------------------------------------- 1 | { 2 | "idToken": [], 3 | "accessToken": [ 4 | { 5 | "name": "upn", 6 | "source": null, 7 | "essential": false, 8 | "additionalProperties": [] 9 | } 10 | ], 11 | "saml2Token": [] 12 | } -------------------------------------------------------------------------------- /Deployment/AadOptionalClaims_Reset.json: -------------------------------------------------------------------------------- 1 | { 2 | "idToken": [], 3 | "accessToken": [], 4 | "saml2Token": [] 5 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /Manifest/color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Manifest/color.png -------------------------------------------------------------------------------- /Manifest/manifest_authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.5/MicrosoftTeams.schema.json", 3 | "manifestVersion": "1.5", 4 | "version": "5.5.2", 5 | "id": "1c07cd26-a088-4db8-8928-ace382fa219f", 6 | "packageName": "com.microsoft.teams.companycommunicator.authors", 7 | "developer": { 8 | "name": "<>", 9 | "websiteUrl": "<>", 10 | "privacyUrl": "<>", 11 | "termsOfUseUrl": "<>" 12 | }, 13 | "icons": { 14 | "color": "color.png", 15 | "outline": "outline.png" 16 | }, 17 | "name": { 18 | "short": "Company Communicator (Authors)", 19 | "full": "Company Communicator (Authors)" 20 | }, 21 | "description": { 22 | "short": "Broadcast messages to multiple teams and people in one go", 23 | "full": "Broadcasts messages to multiple teams and individuals through channel posts and chat messages" 24 | }, 25 | "accentColor": "#64A2CC", 26 | "configurableTabs": [{ 27 | "configurationUrl": "https://<>/configtab", 28 | "canUpdateConfiguration": true, 29 | "scopes": [ 30 | "team" 31 | ] 32 | }], 33 | "bots": [{ 34 | "botId": "<>", 35 | "scopes": [ 36 | "team" 37 | ], 38 | "supportsFiles": true, 39 | "isNotificationOnly": true 40 | }], 41 | "permissions": [ 42 | "identity", 43 | "messageTeamMembers" 44 | ], 45 | "validDomains": [ 46 | "<>" 47 | ], 48 | "webApplicationInfo": { 49 | "id": "<>", 50 | "resource": "api://<>" 51 | } 52 | } -------------------------------------------------------------------------------- /Manifest/manifest_users.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.5/MicrosoftTeams.schema.json", 3 | "manifestVersion": "1.5", 4 | "version": "5.5.2", 5 | "id": "148a66bb-e83d-425a-927d-09f4299a9274", 6 | "packageName": "com.microsoft.teams.companycommunicator", 7 | "developer": { 8 | "name": "<>", 9 | "websiteUrl": "<>", 10 | "privacyUrl": "<>", 11 | "termsOfUseUrl": "<>" 12 | }, 13 | "icons": { 14 | "color": "color.png", 15 | "outline": "outline.png" 16 | }, 17 | "name": { 18 | "short": "Company Communicator", 19 | "full": "Company Communicator" 20 | }, 21 | "description": { 22 | "short": "Broadcast messages to multiple teams and people in one go", 23 | "full": "Broadcasts messages to multiple teams and individuals through channel posts and chat messages" 24 | }, 25 | "accentColor": "#64A2CC", 26 | "bots": [{ 27 | "botId": "<>", 28 | "scopes": [ 29 | "personal", 30 | "team" 31 | ], 32 | "supportsFiles": false, 33 | "isNotificationOnly": true 34 | }], 35 | "permissions": [ 36 | "identity", 37 | "messageTeamMembers" 38 | ], 39 | "validDomains": [ 40 | "<>" 41 | ] 42 | } -------------------------------------------------------------------------------- /Manifest/outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Manifest/outline.png -------------------------------------------------------------------------------- /Source/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/build 21 | **/npm-debug.log 22 | **/obj 23 | **/secrets.dev.yaml 24 | **/values.dev.yaml 25 | 26 | # NuGet Packages 27 | *.nupkg 28 | # The packages folder can be ignored because of Package Restore 29 | **/packages/* 30 | # except build/, which is used as an MSBuild target. 31 | !**/packages/build/ 32 | # Uncomment if necessary however generally it will be regenerated when needed 33 | #!**/packages/repositories.config 34 | # NuGet v3's project.json files produces more ignoreable files 35 | *.nuget.props 36 | *.nuget.targets -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Clients/IStorageClientFactory.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Clients 7 | { 8 | using global::Azure.Storage.Blobs; 9 | 10 | /// 11 | /// Storage client factory. 12 | /// 13 | public interface IStorageClientFactory 14 | { 15 | /// 16 | /// Create the blob container client instance. 17 | /// 18 | /// BlobContainerClient instance. 19 | BlobContainerClient CreateBlobContainerClient(); 20 | 21 | /// 22 | /// Create the blob container client instance. 23 | /// 24 | /// Blob container name. 25 | /// BlobContainerClient instance. 26 | BlobContainerClient CreateBlobContainerClient(string blobContainerName); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Configuration/CommericalConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Configuration 2 | { 3 | /// 4 | /// App configuration for commercial environment. 5 | /// 6 | public class CommericalConfiguration : IAppConfiguration 7 | { 8 | private readonly string tenantId; 9 | 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | /// Tenant id. 14 | public CommericalConfiguration(string tenantId) 15 | { 16 | this.tenantId = tenantId ?? throw new System.ArgumentNullException(nameof(tenantId)); 17 | } 18 | 19 | /// 20 | public string AzureAd_Instance => "https://login.microsoftonline.com"; 21 | 22 | /// 23 | public string AzureAd_ValidIssuers => "https://login.microsoftonline.com/TENANT_ID/v2.0,https://sts.windows.net/TENANT_ID/"; 24 | 25 | /// 26 | public string AuthorityUri => $"https://login.microsoftonline.com/{this.tenantId}"; 27 | 28 | /// 29 | public string GraphBaseUrl => "https://graph.microsoft.com/v1.0"; 30 | 31 | /// 32 | public string GraphDefaultScope => "https://graph.microsoft.com/.default"; 33 | 34 | /// 35 | public string GraphUserReadScope => "https://graph.microsoft.com/User.Read openid profile"; 36 | 37 | /// 38 | public string TeamsLicenseId => "57ff2da0-773e-42df-b2af-ffb7a2317929"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Configuration/ConfigurationFactory.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Configuration 2 | { 3 | /// 4 | /// Configuration factory returns relevant configuration for a given environment. 5 | /// 6 | public class ConfigurationFactory 7 | { 8 | private readonly string tenantId; 9 | 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | /// Tenant id. 14 | public ConfigurationFactory(string tenantId) 15 | { 16 | this.tenantId = tenantId ?? throw new System.ArgumentNullException(nameof(tenantId)); 17 | } 18 | 19 | /// 20 | /// Configuration factory returns relevant configuration for a given environment. 21 | /// 22 | /// Teams environment. 23 | /// App configurstion. 24 | public IAppConfiguration GetAppConfiguration(TeamsEnvironment env) 25 | { 26 | switch (env) 27 | { 28 | case TeamsEnvironment.Commercial: 29 | case TeamsEnvironment.GCC: 30 | return new CommericalConfiguration(this.tenantId); 31 | case TeamsEnvironment.GCCH: 32 | return new GCCHConfiguration(this.tenantId); 33 | case TeamsEnvironment.DOD: 34 | return new DODConfiguration(this.tenantId); 35 | default: 36 | return new CommericalConfiguration(this.tenantId); 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Configuration/DODConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Configuration 2 | { 3 | /// 4 | /// App configuration for DOD environment. 5 | /// 6 | internal class DODConfiguration : IAppConfiguration 7 | { 8 | private readonly string tenantId; 9 | 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | /// TenantId. 14 | public DODConfiguration(string tenantId) 15 | { 16 | this.tenantId = tenantId ?? throw new System.ArgumentNullException(nameof(tenantId)); 17 | } 18 | 19 | /// 20 | public string AzureAd_Instance => "https://login.microsoftonline.us/"; 21 | 22 | /// 23 | public string AzureAd_ValidIssuers => $"https://login.microsoftonline.us/{this.tenantId}/v2.0,https://sts.windows.net/{this.tenantId}/"; 24 | 25 | /// 26 | public string AuthorityUri => $"https://login.microsoftonline.us/{this.tenantId}"; 27 | 28 | /// 29 | public string GraphBaseUrl => "https://dod-graph.microsoft.us/v1.0"; 30 | 31 | /// 32 | public string GraphDefaultScope => "https://dod-graph.microsoft.us/.default"; 33 | 34 | /// 35 | public string GraphUserReadScope => "https://dod-graph.microsoft.us/User.Read openid profile"; 36 | 37 | /// 38 | public string TeamsLicenseId => "fd500458-c24c-478e-856c-a6067a8376cd"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Configuration/GCCHConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Configuration 2 | { 3 | /// 4 | /// App configuration for GCCH environment. 5 | /// 6 | internal class GCCHConfiguration : IAppConfiguration 7 | { 8 | private readonly string tenantId; 9 | 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | /// TenantId. 14 | public GCCHConfiguration(string tenantId) 15 | { 16 | this.tenantId = tenantId ?? throw new System.ArgumentNullException(nameof(tenantId)); 17 | } 18 | 19 | /// 20 | public string AzureAd_Instance => "https://login.microsoftonline.us/"; 21 | 22 | /// 23 | public string AzureAd_ValidIssuers => $"https://login.microsoftonline.us/{this.tenantId}/v2.0,https://sts.windows.net/{this.tenantId}/"; 24 | 25 | /// 26 | public string AuthorityUri => $"https://login.microsoftonline.us/{this.tenantId}"; 27 | 28 | /// 29 | public string GraphBaseUrl => "https://graph.microsoft.us/v1.0"; 30 | 31 | /// 32 | public string GraphDefaultScope => "https://graph.microsoft.us/.default"; 33 | 34 | /// 35 | public string GraphUserReadScope => "https://graph.microsoft.us/User.Read openid profile"; 36 | 37 | /// 38 | public string TeamsLicenseId => "9953b155-8aef-4c56-92f3-72b0487fce41"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Configuration/IAppConfiguration.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Configuration 7 | { 8 | /// 9 | /// App configuration interface. 10 | /// 11 | public interface IAppConfiguration 12 | { 13 | public string AzureAd_Instance { get; } 14 | 15 | public string AzureAd_ValidIssuers { get; } 16 | 17 | public string AuthorityUri { get; } 18 | 19 | public string GraphBaseUrl { get; } 20 | 21 | public string GraphDefaultScope { get; } 22 | 23 | public string GraphUserReadScope { get; } 24 | 25 | public string TeamsLicenseId { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Configuration/TeamsEnvironment.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common 2 | { 3 | /// 4 | /// Teams environment. 5 | /// 6 | public enum TeamsEnvironment 7 | { 8 | /// 9 | /// Commmercial environment. 10 | /// 11 | Commercial, 12 | 13 | /// 14 | /// GCC - https://learn.microsoft.com/en-us/office365/servicedescriptions/office-365-platform-service-description/office-365-us-government/gcc 15 | /// 16 | GCC, 17 | 18 | /// 19 | /// GCCH - https://learn.microsoft.com/en-us/office365/servicedescriptions/office-365-platform-service-description/office-365-us-government/gcc-high-and-dod 20 | /// 21 | GCCH, 22 | 23 | /// 24 | /// DOD - https://learn.microsoft.com/en-us/office365/servicedescriptions/office-365-platform-service-description/office-365-us-government/gcc-high-and-dod 25 | /// 26 | DOD 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Policies/PollyPolicy.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Policies 7 | { 8 | using System; 9 | using System.Net; 10 | using Microsoft.Graph; 11 | using Polly; 12 | using Polly.Contrib.WaitAndRetry; 13 | using Polly.Retry; 14 | 15 | /// 16 | /// Polly policies. 17 | /// 18 | public class PollyPolicy 19 | { 20 | /// 21 | /// Get the graph retry policy. 22 | /// 23 | /// the number of max attempts. 24 | /// A retry policy that can be applied to async delegates. 25 | public static AsyncRetryPolicy GetGraphRetryPolicy(int maxAttempts) 26 | { 27 | var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: maxAttempts); 28 | 29 | // Only Handling 502 Bad Gateway Exception 30 | // Other exception such as 429, 503, 504 is handled by default by Graph SDK. 31 | return Policy 32 | .Handle(e => 33 | e.StatusCode == HttpStatusCode.BadGateway) 34 | .WaitAndRetryAsync(delay); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/AppConfig/AppConfigEntity.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories 7 | { 8 | using Microsoft.Azure.Cosmos.Table; 9 | 10 | /// 11 | /// App configuration entity. 12 | /// 13 | public class AppConfigEntity : TableEntity 14 | { 15 | /// 16 | /// Gets or sets the entity value. 17 | /// 18 | public string Value { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/AppConfig/AppConfigRepository.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories 7 | { 8 | using Microsoft.Extensions.Logging; 9 | using Microsoft.Extensions.Options; 10 | using Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories; 11 | 12 | /// 13 | /// App configuration repository. 14 | /// 15 | public class AppConfigRepository : BaseRepository, IAppConfigRepository 16 | { 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | /// The logging service. 21 | /// Options used to create the repository. 22 | public AppConfigRepository( 23 | ILogger logger, 24 | IOptions repositoryOptions) 25 | : base( 26 | logger, 27 | storageAccountConnectionString: repositoryOptions.Value.StorageAccountConnectionString, 28 | tableName: AppConfigTableName.TableName, 29 | defaultPartitionKey: AppConfigTableName.SettingsPartition, 30 | ensureTableExists: repositoryOptions.Value.EnsureTableExists) 31 | { 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/AppConfig/AppConfigTableName.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories 7 | { 8 | /// 9 | /// App config table information. 10 | /// 11 | public class AppConfigTableName 12 | { 13 | /// 14 | /// Table name for app config.. 15 | /// 16 | public static readonly string TableName = "AppConfig"; 17 | 18 | /// 19 | /// App settings partition. 20 | /// 21 | public static readonly string SettingsPartition = "Settings"; 22 | 23 | /// 24 | /// Service url row key. 25 | /// 26 | public static readonly string ServiceUrlRowKey = "ServiceUrl"; 27 | 28 | /// 29 | /// User app id row key. 30 | /// 31 | public static readonly string UserAppIdRowKey = "UserAppId"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/AppConfig/IAppConfigRepository.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories 7 | { 8 | /// 9 | /// Interface for App configuration repository. 10 | /// 11 | public interface IAppConfigRepository : IRepository 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/CleanUpHistory/CleanUpHistoryEntity.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.CleanUpHistory 7 | { 8 | using Microsoft.Azure.Cosmos.Table; 9 | 10 | /// 11 | /// Clean Up History entity class. 12 | /// This entity holds all of the information about Deletion of records. 13 | /// 14 | public class CleanUpHistoryEntity : TableEntity 15 | { 16 | /// 17 | /// Gets or sets the selected date range for the delete data. 18 | /// 19 | public string SelectedDateRange { get; set; } 20 | 21 | /// 22 | /// Gets or sets the number of records deleted. 23 | /// 24 | public int RecordsDeleted { get; set; } 25 | 26 | /// 27 | /// Gets or sets the Deleted By field. 28 | /// 29 | public string DeletedBy { get; set; } 30 | 31 | /// 32 | /// Gets or sets the status of the deletion. 33 | /// 34 | public string Status { get; set; } 35 | 36 | /// 37 | /// Gets or sets the Start Date field. 38 | /// 39 | public string StartDate { get; set; } 40 | 41 | /// 42 | /// Gets or sets the End Date field. 43 | /// 44 | public string EndDate { get; set; } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/CleanUpHistory/CleanUpHistoryTableName.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.CleanUpHistory 7 | { 8 | /// 9 | /// CleanUpHistory table names. 10 | /// 11 | public class CleanUpHistoryTableName 12 | { 13 | /// 14 | /// Table name for the delete message history table. 15 | /// 16 | public static readonly string TableName = "CleanUpHistory"; 17 | 18 | /// 19 | /// Default partition - should not be used. 20 | /// 21 | public static readonly string DefaultPartition = "Default"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/CleanUpHistory/CleanUpStatus.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.CleanUpHistory 7 | { 8 | /// 9 | /// Cleanup telemetry status. 10 | /// 11 | public enum CleanUpStatus 12 | { 13 | /// 14 | /// This represents the cleanup is in progress. 15 | /// 16 | InProgress, 17 | 18 | /// 19 | /// This represents the cleanup is completed. 20 | /// 21 | Completed, 22 | 23 | /// 24 | /// This represents the cleanup is failed. 25 | /// 26 | Failed, 27 | } 28 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/CleanUpHistory/DeleteMessage.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Models 7 | { 8 | /// 9 | /// Delete message model class. 10 | /// 11 | public class DeleteMessage 12 | { 13 | /// 14 | /// Gets or sets the table row key id. 15 | /// 16 | public string RowKeyId { get; set; } 17 | 18 | /// 19 | /// Gets or sets the selected date range for the delete data. 20 | /// 21 | public string SelectedDateRange { get; set; } 22 | 23 | /// 24 | /// Gets or sets the Deleted By field. 25 | /// 26 | public string DeletedBy { get; set; } 27 | 28 | /// 29 | /// Gets or sets the Start Date field. 30 | /// 31 | public string StartDate { get; set; } 32 | 33 | /// 34 | /// Gets or sets the End Date field. 35 | /// 36 | public string EndDate { get; set; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/CleanUpHistory/ICleanUpHistoryRepository.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.CleanUpHistory 7 | { 8 | using System.Collections.Generic; 9 | using System.Threading.Tasks; 10 | 11 | /// 12 | /// interface for export data Repository. 13 | /// 14 | public interface ICleanUpHistoryRepository : IRepository 15 | { 16 | /// 17 | /// Gets or sets table row key generator. 18 | /// 19 | public TableRowKeyGenerator TableRowKeyGenerator { get; set; } 20 | 21 | /// 22 | /// This method ensures the CleanUpHistory table is created in the storage. 23 | /// This method should be called before kicking off an Azure function that uses the CleanUpHistory table. 24 | /// Otherwise the app will crash. 25 | /// By design, Azure functions (in this app) do not create a table if it's absent. 26 | /// 27 | /// A representing the result of the asynchronous operation. 28 | public Task EnsureCleanUpHistoryTableExistsAsync(); 29 | 30 | /// 31 | /// Get all CleanUp History entities from the table storage. 32 | /// 33 | /// All entities of Cleanup History. 34 | public Task> GetAllCleanUpHistoryAsync(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/ExportData/ExportDataEntity.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.ExportData 7 | { 8 | using System; 9 | using Microsoft.Azure.Cosmos.Table; 10 | 11 | /// 12 | /// Export notification entity class. 13 | /// This entity holds all of the information about export. 14 | /// 15 | public class ExportDataEntity : TableEntity 16 | { 17 | /// 18 | /// Gets or sets the file name for the export data. 19 | /// 20 | public string FileName { get; set; } 21 | 22 | /// 23 | /// Gets or sets the response id of the File Consent Card. 24 | /// 25 | public string FileConsentId { get; set; } 26 | 27 | /// 28 | /// Gets or sets the DateTime of exporting the notification. 29 | /// 30 | public DateTime? SentDate { get; set; } 31 | 32 | /// 33 | /// Gets or sets the status of the export. 34 | /// 35 | public string Status { get; set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/ExportData/ExportDataTableName.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.ExportData 7 | { 8 | /// 9 | /// Export data table names. 10 | /// 11 | public class ExportDataTableName 12 | { 13 | /// 14 | /// Table name for the send batches data table. 15 | /// 16 | public static readonly string TableName = "ExportData"; 17 | 18 | /// 19 | /// Default partition - should not be used. 20 | /// 21 | public static readonly string DefaultPartition = "Default"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/ExportData/ExportStatus.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.ExportData 7 | { 8 | /// 9 | /// Export telemetry status. 10 | /// 11 | public enum ExportStatus 12 | { 13 | /// 14 | /// This represents the export is scheduled. 15 | /// 16 | New, 17 | 18 | /// 19 | /// This represents the export is in progress. 20 | /// 21 | InProgress, 22 | 23 | /// 24 | /// This reprsents the export is completed. 25 | /// 26 | Completed, 27 | 28 | /// 29 | /// This represents the export is failed. 30 | /// 31 | Failed, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/ExportData/IExportDataRepository.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.ExportData 7 | { 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// interface for export data Repository. 12 | /// 13 | public interface IExportDataRepository : IRepository 14 | { 15 | /// 16 | /// This method ensures the ExportData table is created in the storage. 17 | /// This method should be called before kicking off an Azure function that uses the ExportData table. 18 | /// Otherwise the app will crash. 19 | /// By design, Azure functions (in this app) do not create a table if it's absent. 20 | /// 21 | /// A representing the result of the asynchronous operation. 22 | public Task EnsureExportDataTableExistsAsync(); 23 | } 24 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/NotificationData/GlobalSendingNotificationDataEntity.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.NotificationData 7 | { 8 | using System; 9 | using Microsoft.Azure.Cosmos.Table; 10 | 11 | /// 12 | /// Entity that holds metadata for all sending operations. 13 | /// This data is shared by all sending functions for all notifications. 14 | /// 15 | public class GlobalSendingNotificationDataEntity : TableEntity 16 | { 17 | /// 18 | /// Gets or sets a DateTime that sending of a notification can be retried/resumed. 19 | /// This is used to trigger a delay for all notifications if the bot is 20 | /// currently in a long term throttled state. 21 | /// After this given time, the sending function will attempt sending again to see 22 | /// if the bot is still in a throttled state. 23 | /// 24 | public DateTime? SendRetryDelayTime { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/NotificationData/IGlobalSendingNotificationDataRepository.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.NotificationData 7 | { 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// interface for Global Sending Notification Data Repository. 12 | /// 13 | public interface IGlobalSendingNotificationDataRepository : IRepository 14 | { 15 | /// 16 | /// Gets the entity that holds meta-data for all sending operations. 17 | /// 18 | /// The Global Sending Notification Data Entity. 19 | public Task GetGlobalSendingNotificationDataEntityAsync(); 20 | 21 | /// 22 | /// Insert or merges the entity that holds meta-data for all sending operations. Partition Key and Row Key do not need to be 23 | /// set on the incoming entity. 24 | /// 25 | /// Entity that holds meta-data for all sending operations. Partition Key and 26 | /// Row Key do not need to be set. 27 | /// The Task. 28 | public Task SetGlobalSendingNotificationDataEntityAsync(GlobalSendingNotificationDataEntity globalSendingNotificationDataEntity); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/NotificationData/ISendingNotificationDataRepository.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.NotificationData 7 | { 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// interface for Sending Notification Data Repository. 12 | /// 13 | public interface ISendingNotificationDataRepository : IRepository 14 | { 15 | /// 16 | /// Get Adaptive Card from external storage. 17 | /// 18 | /// Blob name. 19 | /// AC in json format. 20 | public Task GetAdaptiveCardAsync(string blobName); 21 | 22 | /// 23 | /// Save Adaptive Card to external storage. 24 | /// 25 | /// Blob name. 26 | /// Adaptive card in json format. 27 | /// A representing the result of the asynchronous operation. 28 | public Task SaveAdaptiveCardAsync(string blobName, string adaptiveCard); 29 | 30 | /// 31 | /// Get image from external storage. 32 | /// 33 | /// Blob name. 34 | /// Image in base64 format. 35 | public Task GetImageAsync(string blobName); 36 | } 37 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/NotificationData/NotificationDataTableNames.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.NotificationData 7 | { 8 | /// 9 | /// Notification data table names. 10 | /// 11 | public static class NotificationDataTableNames 12 | { 13 | /// 14 | /// Table name for the notification data table. 15 | /// 16 | public static readonly string TableName = "NotificationData"; 17 | 18 | /// 19 | /// Draft notifications partition key name. 20 | /// 21 | public static readonly string DraftNotificationsPartition = "DraftNotifications"; 22 | 23 | /// 24 | /// Sending notifications partition key name. 25 | /// 26 | public static readonly string SendingNotificationsPartition = "SendingNotifications"; 27 | 28 | /// 29 | /// Global sending notification data partition key name. 30 | /// 31 | public static readonly string GlobalSendingNotificationDataPartition = "GlobalSendingNotificationData"; 32 | 33 | /// 34 | /// Sent notifications partition key name. 35 | /// 36 | public static readonly string SentNotificationsPartition = "SentNotifications"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/NotificationData/NotificationStatus.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.NotificationData 7 | { 8 | /// 9 | /// Notification status. 10 | /// 11 | public enum NotificationStatus 12 | { 13 | /// 14 | /// Status is Unknown. 15 | /// 16 | Unknown, 17 | 18 | /// 19 | /// Message is queued to be processed. 20 | /// All new messages sent are created with this status. 21 | /// 22 | Queued, 23 | 24 | /// 25 | /// Syncing recipients. 26 | /// 27 | SyncingRecipients, 28 | 29 | /// 30 | /// Installing user app for recipients. 31 | /// 32 | InstallingApp, 33 | 34 | /// 35 | /// In process of sending the message. 36 | /// 37 | Sending, 38 | 39 | /// 40 | /// Message is sent to recipients. This is an end state. 41 | /// 42 | Sent, 43 | 44 | /// 45 | /// Failed to send the message. This is an end state. 46 | /// 47 | Failed, 48 | 49 | /// 50 | /// In process of canceling the message. 51 | /// 52 | Canceling, 53 | 54 | /// 55 | /// Canceled the message. This is an end state. 56 | /// 57 | Canceled, 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/NotificationData/SendingNotificationDataEntity.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.NotificationData 7 | { 8 | using Microsoft.Azure.Cosmos.Table; 9 | 10 | /// 11 | /// Sending notification entity class. 12 | /// This entity holds the information about the content for a notification 13 | /// that is either currently being sent or was previously sent. 14 | /// 15 | public class SendingNotificationDataEntity : TableEntity 16 | { 17 | /// 18 | /// Gets or sets the notification id. 19 | /// 20 | public string NotificationId { get; set; } 21 | 22 | /// 23 | /// Gets or sets the content of the notification in serialized JSON form. 24 | /// 25 | public string Content { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/RepositoryOptions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories 7 | { 8 | /// 9 | /// Options used for creating repositories. 10 | /// 11 | public class RepositoryOptions 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | public RepositoryOptions() 17 | { 18 | // Default this option to true as ensuring the table exists is technically 19 | // more robust. 20 | this.EnsureTableExists = true; 21 | } 22 | 23 | /// 24 | /// Gets or sets the storage account connection string. 25 | /// 26 | public string StorageAccountConnectionString { get; set; } 27 | 28 | /// 29 | /// Gets or sets a value indicating whether the table should be created 30 | /// if it does not already exist. 31 | /// 32 | public bool EnsureTableExists { get; set; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/SentNotificationData/SentNotificationDataTableNames.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.SentNotificationData 7 | { 8 | /// 9 | /// Sent notification data table names. 10 | /// 11 | public static class SentNotificationDataTableNames 12 | { 13 | /// 14 | /// Table name for the sent notification data table. 15 | /// 16 | public static readonly string TableName = "SentNotificationData"; 17 | 18 | /// 19 | /// Default partition - should not be used. 20 | /// 21 | public static readonly string DefaultPartition = "Default"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/TableRowKeyGenerator.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories 7 | { 8 | using System; 9 | 10 | /// 11 | /// This class generates rowKeys based off timestamps so that the order of the table is correct. 12 | /// 13 | public class TableRowKeyGenerator 14 | { 15 | /// 16 | /// Generates a new row key based off of the current timestamp such that the keys are ordered most recent => oldest. 17 | /// 18 | /// A new row key. 19 | public string CreateNewKeyOrderingMostRecentToOldest() 20 | { 21 | var invertedTicksString = string.Format("{0:D19}", DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks); 22 | 23 | return invertedTicksString; 24 | } 25 | 26 | /// 27 | /// Generates a new row key based off of the current timestamp such that the keys are ordered oldest => most recent. 28 | /// 29 | /// A new row key. 30 | public virtual string CreateNewKeyOrderingOldestToMostRecent() 31 | { 32 | var ticksString = string.Format("{0:D19}", DateTime.UtcNow.Ticks); 33 | 34 | return ticksString; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/TeamData/ITeamDataRepository.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.TeamData 6 | { 7 | using System.Collections.Generic; 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// Interface for Team Data Repository. 12 | /// 13 | public interface ITeamDataRepository : IRepository 14 | { 15 | /// 16 | /// Gets team data entities by ID values. 17 | /// 18 | /// Team IDs. 19 | /// Team data entities. 20 | public Task> GetTeamDataEntitiesByIdsAsync(IEnumerable teamIds); 21 | 22 | /// 23 | /// Get team names by Ids. 24 | /// 25 | /// Team ids. 26 | /// Names of the teams matching incoming ids. 27 | public Task> GetTeamNamesByIdsAsync(IEnumerable ids); 28 | 29 | /// 30 | /// Get all team data entities, and sort the result alphabetically by name. 31 | /// 32 | /// The team data entities sorted alphabetically by name. 33 | public Task> GetAllSortedAlphabeticallyByNameAsync(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/TeamData/TeamDataEntity.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.TeamData 7 | { 8 | using Microsoft.Azure.Cosmos.Table; 9 | 10 | /// 11 | /// Teams data entity class. 12 | /// This entity holds the information about a team. 13 | /// 14 | public class TeamDataEntity : TableEntity 15 | { 16 | /// 17 | /// Gets or sets the team id. 18 | /// 19 | public string TeamId { get; set; } 20 | 21 | /// 22 | /// Gets or sets the name of the team. 23 | /// 24 | public string Name { get; set; } 25 | 26 | /// 27 | /// Gets or sets the service url for the team. 28 | /// 29 | public string ServiceUrl { get; set; } 30 | 31 | /// 32 | /// Gets or sets tenant id for the team. 33 | /// 34 | public string TenantId { get; set; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/TeamData/TeamDataTableNames.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.TeamData 7 | { 8 | /// 9 | /// Team data table names. 10 | /// 11 | public static class TeamDataTableNames 12 | { 13 | /// 14 | /// Table name for the team data table. 15 | /// 16 | public static readonly string TableName = "TeamData"; 17 | 18 | /// 19 | /// Team data partition key name. 20 | /// 21 | public static readonly string TeamDataPartition = "TeamData"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/UserData/IUserDataRepository.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.UserData 7 | { 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// Interface for User Data Repository. 12 | /// 13 | public interface IUserDataRepository : IRepository 14 | { 15 | /// 16 | /// Get delta link. 17 | /// 18 | /// Delta link. 19 | public Task GetDeltaLinkAsync(); 20 | 21 | /// 22 | /// Sets delta link. 23 | /// 24 | /// delta link. 25 | /// A representing the asynchronous operation. 26 | public Task SetDeltaLinkAsync(string deltaLink); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/UserData/UserDataTableNames.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.UserData 7 | { 8 | /// 9 | /// User data table names. 10 | /// 11 | public static class UserDataTableNames 12 | { 13 | /// 14 | /// Table name for the user data table. 15 | /// 16 | public static readonly string TableName = "UserData"; 17 | 18 | /// 19 | /// Users data partition key name. 20 | /// 21 | public static readonly string UserDataPartition = "UserData"; 22 | 23 | /// 24 | /// Users sync data partition. 25 | /// 26 | public static readonly string UsersSyncDataPartition = "UsersSyncData"; 27 | 28 | /// 29 | /// All users delta link row key. 30 | /// 31 | public static readonly string AllUsersDeltaLinkRowKey = "AllUsersDeltaLink"; 32 | 33 | /// 34 | /// Authors data partition key name. 35 | /// 36 | public static readonly string AuthorDataPartition = "AuthorData"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Repositories/UserData/UsersSyncEntity.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories 7 | { 8 | using Microsoft.Azure.Cosmos.Table; 9 | 10 | /// 11 | /// Users sync information. 12 | /// 13 | public class UsersSyncEntity : TableEntity 14 | { 15 | /// 16 | /// Gets or sets the entity value. 17 | /// 18 | public string Value { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Resources/LocaleOptions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Resources 7 | { 8 | /// 9 | /// Options used for setting locale. 10 | /// 11 | public class LocaleOptions 12 | { 13 | /// 14 | /// Gets or sets the default culture. 15 | /// 16 | public string DefaultCulture { get; set; } 17 | 18 | /// 19 | /// Gets or sets the supported cultures. 20 | /// 21 | public string SupportedCultures { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Secrets/ICertificateProvider.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Secrets 7 | { 8 | using System.Security.Cryptography.X509Certificates; 9 | using System.Threading.Tasks; 10 | 11 | /// 12 | /// This instance is used to retrieve certificates. 13 | /// 14 | public interface ICertificateProvider 15 | { 16 | /// 17 | /// Gets the certificate for the given app id. 18 | /// 19 | /// The Azure active directory Identifier. 20 | /// Certificate. 21 | Task GetCertificateAsync(string appId); 22 | 23 | /// 24 | /// Checks if authentication is to be done using certificate. 25 | /// 26 | /// Boolean indicating if authentication type is certificate. 27 | bool IsCertificateAuthenticationEnabled(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Secrets/SecretsRegistry.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Secrets 7 | { 8 | using System; 9 | using global::Azure.Core; 10 | using global::Azure.Identity; 11 | using global::Azure.Security.KeyVault.Certificates; 12 | using Microsoft.Extensions.DependencyInjection; 13 | 14 | /// 15 | /// Register secrets dependencies. 16 | /// 17 | public static class SecretsRegistry 18 | { 19 | /// 20 | /// Service Collection extension. 21 | /// 22 | /// Injects secrets provider. 23 | /// 24 | /// Service collection. 25 | /// Key vault url. 26 | /// the service collection. 27 | public static IServiceCollection AddSecretsProvider(this IServiceCollection services, string keyVaultUrl) 28 | { 29 | if (string.IsNullOrEmpty(keyVaultUrl)) 30 | { 31 | throw new ArgumentNullException("KeyVault Url is null or empty."); 32 | } 33 | 34 | var options = new CertificateClientOptions(); 35 | options.AddPolicy(new KeyVaultProxy(), HttpPipelinePosition.PerCall); 36 | services.AddSingleton(new CertificateClient(new Uri(keyVaultUrl), new DefaultAzureCredential(), options)); 37 | services.AddSingleton(); 38 | 39 | return services; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/AdaptiveCard/AdaptiveImageWithLongUrl.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.AdaptiveCard 7 | { 8 | using AdaptiveCards; 9 | using Newtonsoft.Json; 10 | 11 | /// 12 | /// Workaround for long data uri https://github.com/microsoft/AdaptiveCards/issues/2716. 13 | /// 14 | public class AdaptiveImageWithLongUrl : AdaptiveImage 15 | { 16 | /// 17 | /// Gets or sets Data URI for Image. 18 | /// 19 | [JsonProperty(PropertyName = "url", Required = Required.Always)] 20 | public string LongUrl { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/CommonBot/AuthorAppCredentials.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.CommonBot 7 | { 8 | using System; 9 | using System.Threading.Tasks; 10 | using Microsoft.Bot.Connector.Authentication; 11 | using Microsoft.Extensions.Options; 12 | 13 | /// 14 | /// An author Microsoft app credentials object. 15 | /// 16 | public class AuthorAppCredentials : MicrosoftAppCredentials 17 | { 18 | private readonly bool useCertificate; 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | /// The bot options. 24 | public AuthorAppCredentials(IOptions botOptions) 25 | : base( 26 | appId: botOptions.Value.AuthorAppId, 27 | password: botOptions.Value.AuthorAppPassword) 28 | { 29 | botOptions = botOptions ?? throw new ArgumentNullException(nameof(botOptions)); 30 | this.useCertificate = botOptions.Value.UseCertificate; 31 | } 32 | 33 | /// 34 | /// Checks if authentication is to be done using certificate. 35 | /// 36 | /// Boolean indicating if authentication type is certifcate. 37 | public bool IsCertificateAuthenticationEnabled() 38 | { 39 | return this.useCertificate; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/CommonBot/UserAppCredentials.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.CommonBot 7 | { 8 | using System; 9 | using Microsoft.Bot.Connector.Authentication; 10 | using Microsoft.Extensions.Options; 11 | 12 | /// 13 | /// A user Microsoft app credentials object. 14 | /// 15 | public class UserAppCredentials : MicrosoftAppCredentials 16 | { 17 | private readonly bool useCertificate; 18 | 19 | /// 20 | /// Initializes a new instance of the class. 21 | /// 22 | /// The bot options. 23 | public UserAppCredentials(IOptions botOptions) 24 | : base( 25 | appId: botOptions.Value.UserAppId, 26 | password: botOptions.Value.UserAppPassword) 27 | { 28 | botOptions = botOptions ?? throw new ArgumentNullException(nameof(botOptions)); 29 | this.useCertificate = botOptions.Value.UseCertificate; 30 | } 31 | 32 | /// 33 | /// Checks if authentication is to be done using certificate. 34 | /// 35 | /// Boolean indicating if authentication type is certifcate. 36 | public bool IsCertificateAuthenticationEnabled() 37 | { 38 | return this.useCertificate; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/DataQueue/DataQueueMessageContent.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.DataQueue 7 | { 8 | /// 9 | /// Azure service bus data queue message content class. 10 | /// 11 | public class DataQueueMessageContent 12 | { 13 | /// 14 | /// Gets or sets the notification id value. 15 | /// 16 | public string NotificationId { get; set; } 17 | 18 | /// 19 | /// Gets or sets a value indicating whether the data function should force the 20 | /// corresponding notification to be marked as complete. 21 | /// 22 | public bool ForceMessageComplete { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/DataQueue/IDataQueue.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.DataQueue 7 | { 8 | using System; 9 | using System.Threading.Tasks; 10 | 11 | /// 12 | /// interface for DataQueue. 13 | /// 14 | public interface IDataQueue : IBaseQueue 15 | { 16 | /// 17 | /// Sends message to data queue to trigger Data function. 18 | /// 19 | /// the notification id. 20 | /// time to delay the message. 21 | /// A representing the result of the asynchronous operation. 22 | Task SendMessageAsync(string notificationId, TimeSpan messageDelay); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/ExportQueue/ExportQueue.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.ExportQueue 7 | { 8 | using global::Azure.Messaging.ServiceBus; 9 | 10 | /// 11 | /// The message queue service connected to the "company-communicator-export" queue in Azure service bus. 12 | /// 13 | public class ExportQueue : BaseQueue, IExportQueue 14 | { 15 | /// 16 | /// Queue name of the export queue. 17 | /// 18 | public const string QueueName = "company-communicator-export"; 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | /// The service bus client. 24 | public ExportQueue(ServiceBusClient serviceBusClient) 25 | : base( 26 | serviceBusClient: serviceBusClient, 27 | queueName: ExportQueue.QueueName) 28 | { 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/ExportQueue/ExportQueueMessageContent.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.ExportQueue 7 | { 8 | /// 9 | /// Azure service bus export queue message content class. 10 | /// 11 | public class ExportQueueMessageContent 12 | { 13 | /// 14 | /// Gets or sets the user id value. 15 | /// 16 | public string UserId { get; set; } 17 | 18 | /// 19 | /// Gets or sets the notification id value. 20 | /// 21 | public string NotificationId { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/ExportQueue/IExportQueue.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.ExportQueue 7 | { 8 | /// 9 | /// interface for Export Queue. 10 | /// 11 | public interface IExportQueue : IBaseQueue 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/PrepareToSendQueue/IPrepareToSendQueue.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.PrepareToSendQueue 7 | { 8 | /// 9 | /// interface for Prepare to send Queue. 10 | /// 11 | public interface IPrepareToSendQueue : IBaseQueue 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/PrepareToSendQueue/PrepareToSendQueue.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.PrepareToSendQueue 7 | { 8 | using global::Azure.Messaging.ServiceBus; 9 | 10 | /// 11 | /// The message queue service connected to the "company-communicator-prep" queue in Azure service bus. 12 | /// 13 | public class PrepareToSendQueue : BaseQueue, IPrepareToSendQueue 14 | { 15 | /// 16 | /// Queue name of the prepare to send queue. 17 | /// 18 | public const string QueueName = "company-communicator-prep"; 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | /// The service bus client. 24 | public PrepareToSendQueue(ServiceBusClient serviceBusClient) 25 | : base( 26 | serviceBusClient: serviceBusClient, 27 | queueName: PrepareToSendQueue.QueueName) 28 | { 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/PrepareToSendQueue/PrepareToSendQueueMessageContent.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.PrepareToSendQueue 7 | { 8 | /// 9 | /// Azure service bus prepare to send queue message content class. 10 | /// 11 | public class PrepareToSendQueueMessageContent 12 | { 13 | /// 14 | /// Gets or sets the notification id value. 15 | /// 16 | public string NotificationId { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/SendQueue/ISendQueue.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.SendQueue 7 | { 8 | /// 9 | /// interface for Send Queue. 10 | /// 11 | public interface ISendQueue : IBaseQueue 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/SendQueue/RecipientDataType.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.SendQueue 7 | { 8 | /// 9 | /// Type used for indicating to the sending Azure Function what type of recipient to which 10 | /// the notification is to be delivered. 11 | /// 12 | public enum RecipientDataType 13 | { 14 | /// 15 | /// Indicates the notification is to be sent to a user. 16 | /// 17 | User, 18 | 19 | /// 20 | /// Indicates the notification is to be sent to a team. 21 | /// 22 | Team, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/SendQueue/SendQueue.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.SendQueue 7 | { 8 | using global::Azure.Messaging.ServiceBus; 9 | 10 | /// 11 | /// The message queue service connected to the "company-communicator-send" queue in Azure service bus. 12 | /// 13 | public class SendQueue : BaseQueue, ISendQueue 14 | { 15 | /// 16 | /// Queue name of the send queue. 17 | /// 18 | public const string QueueName = "company-communicator-send"; 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | /// The service bus client. 24 | public SendQueue(ServiceBusClient serviceBusClient) 25 | : base( 26 | serviceBusClient: serviceBusClient, 27 | queueName: SendQueue.QueueName) 28 | { 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MessageQueues/SendQueue/SendQueueMessageContent.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MessageQueues.SendQueue 7 | { 8 | /// 9 | /// Azure service bus send queue message content class. 10 | /// 11 | public class SendQueueMessageContent 12 | { 13 | /// 14 | /// Gets or sets the notification id value. 15 | /// 16 | public string NotificationId { get; set; } 17 | 18 | /// 19 | /// Gets or sets the information about the recipient. This 20 | /// holds enough information for the Azure Function to send this 21 | /// recipient a notification. 22 | /// 23 | public RecipientData RecipientData { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MicrosoftGraph/GraphConstants.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MicrosoftGraph 7 | { 8 | /// 9 | /// Microsoft Graph Constants. 10 | /// 11 | public class GraphConstants 12 | { 13 | /// 14 | /// Max page size. 15 | /// 16 | public const int MaxPageSize = 999; 17 | 18 | /// 19 | /// Max retry for Graph API calls. 20 | /// Note: Max value allowed is 10. 21 | /// 22 | public const int MaxRetry = 5; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MicrosoftGraph/GraphPermissionType.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MicrosoftGraph 7 | { 8 | /// 9 | /// Graph Permission Type. 10 | /// 11 | public enum GraphPermissionType 12 | { 13 | /// 14 | /// This represents application permission of Microsoft Graph. 15 | /// 16 | Application, 17 | 18 | /// 19 | /// This represents delgeate permission of Microsoft Graph. 20 | /// 21 | Delegate, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MicrosoftGraph/Groups/GroupExtensions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MicrosoftGraph 7 | { 8 | using System; 9 | using Microsoft.Graph; 10 | 11 | /// 12 | /// Group Extension. 13 | /// 14 | public static class GroupExtensions 15 | { 16 | /// 17 | /// Check if the group's visibility set to hidden membership. 18 | /// 19 | /// Group. 20 | /// Indicating if the visibility is hidden membership. 21 | public static bool IsHiddenMembership(this Group group) 22 | { 23 | var visibility = group.Visibility; 24 | if (string.IsNullOrWhiteSpace(visibility)) 25 | { 26 | return false; 27 | } 28 | 29 | return visibility.Equals(Common.Constants.HiddenMembership, StringComparison.CurrentCultureIgnoreCase); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MicrosoftGraph/Groups/IGroupsService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MicrosoftGraph 7 | { 8 | using System.Collections.Generic; 9 | using System.Threading.Tasks; 10 | using Microsoft.Graph; 11 | 12 | /// 13 | /// Interface for Groups Service. 14 | /// 15 | public interface IGroupsService 16 | { 17 | /// 18 | /// get the group by ids. 19 | /// 20 | /// list of group ids. 21 | /// list of groups. 22 | IAsyncEnumerable GetByIdsAsync(IEnumerable groupIds); 23 | 24 | /// 25 | /// check if list has hidden membership group. 26 | /// 27 | /// list of group ids. 28 | /// boolean. 29 | Task ContainsHiddenMembershipAsync(IEnumerable groupIds); 30 | 31 | /// 32 | /// Search groups based on query. 33 | /// 34 | /// query param. 35 | /// list of group. 36 | Task> SearchAsync(string query); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MicrosoftGraph/TeamWork/IAppCatalogService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MicrosoftGraph 7 | { 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// Read information about the apps published in the Teams app store and organization's app catalog. 12 | /// 13 | public interface IAppCatalogService 14 | { 15 | /// 16 | /// Gets teamsAppId from externalId of an app in a tenant's app catalog. 17 | /// 18 | /// ExternalId is provided in the app manifest and its unique for all the apps in a tenant's app catalog. 19 | /// 20 | /// Teams app's external id. 21 | /// teamsAppId. 22 | public Task GetTeamsAppIdAsync(string externalId); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MicrosoftGraph/TeamWork/IChatsService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MicrosoftGraph 7 | { 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// Chats Service. 12 | /// 13 | public interface IChatsService 14 | { 15 | /// 16 | /// Get chatThread Id for the user. 17 | /// 18 | /// User Id. 19 | /// Teams App Id. 20 | /// ChatThread Id. 21 | public Task GetChatThreadIdAsync(string userId, string appId); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/MicrosoftGraph/UserType.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.MicrosoftGraph 7 | { 8 | /// 9 | /// This represents the User Type property of User entity in Microsoft Graph. 10 | /// Ref : https://docs.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0. 11 | /// The values should be kept exactly the same to the values of userType property. 12 | /// 13 | public class UserType 14 | { 15 | /// 16 | /// This represents Member value of userType property of User entity in Microsoft Graph. 17 | /// 18 | public const string Member = "Member"; 19 | 20 | /// 21 | /// This represents Guest value of userType property of User entity in Microsoft Graph. 22 | /// 23 | public const string Guest = "Guest"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/Recipients/IRecipientsService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.Recipients 7 | { 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.SentNotificationData; 13 | 14 | /// 15 | /// Recipient service. 16 | /// 17 | public interface IRecipientsService 18 | { 19 | /// 20 | /// Batch the list of recipients. 21 | /// 22 | /// list of recipients. 23 | /// recipients information. 24 | Task BatchRecipients(IEnumerable recipients); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/Teams/Conversations/CreateConversationResponse.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.Teams 7 | { 8 | /// 9 | /// The class for the create conversation response. 10 | /// 11 | public class CreateConversationResponse 12 | { 13 | /// 14 | /// Gets or sets the status code. 15 | /// 16 | public int StatusCode { get; set; } 17 | 18 | /// 19 | /// Gets or sets the result type. 20 | /// 21 | public Result Result { get; set; } 22 | 23 | /// 24 | /// Gets or sets the conversation ID. 25 | /// 26 | public string ConversationId { get; set; } 27 | 28 | /// 29 | /// Gets or sets the error message when trying to create the conversation. 30 | /// 31 | public string ErrorMessage { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/Teams/Conversations/Result.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.Teams 7 | { 8 | /// 9 | /// An enum indicating the different create user conversation result types. 10 | /// 11 | public enum Result 12 | { 13 | /// 14 | /// Type indicating creating the conversation succeeded. 15 | /// 16 | Succeeded, 17 | 18 | /// 19 | /// Type indicating creating the conversation was throttled. 20 | /// 21 | Throttled, 22 | 23 | /// 24 | /// Type indicating creating the conversation failed. 25 | /// 26 | Failed, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/Teams/Messages/IMessageService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.Teams 7 | { 8 | using System.Threading.Tasks; 9 | using Microsoft.Bot.Schema; 10 | using Microsoft.Extensions.Logging; 11 | 12 | /// 13 | /// Teams message service. 14 | /// 15 | public interface IMessageService 16 | { 17 | /// 18 | /// Send message to a conversation. 19 | /// 20 | /// Message. 21 | /// Conversation Id. 22 | /// The service URL to use for sending the notification. 23 | /// Max attempts to send the message. 24 | /// Logger. 25 | /// Send message response. 26 | public Task SendMessageAsync( 27 | IMessageActivity message, 28 | string conversationId, 29 | string serviceUrl, 30 | int maxAttempts, 31 | ILogger logger); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/Teams/Messages/SendMessageResponse.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.Teams 7 | { 8 | /// 9 | /// Send message response object. 10 | /// 11 | public class SendMessageResponse 12 | { 13 | /// 14 | /// Gets or sets the status code. 15 | /// 16 | public int StatusCode { get; set; } 17 | 18 | /// 19 | /// Gets or sets the result type. 20 | /// 21 | public SendMessageResult ResultType { get; set; } 22 | 23 | /// 24 | /// Gets or sets a comma separated list representing all of the status code responses received when trying 25 | /// to send the notification to the recipient. These results can include success, failure, and throttle 26 | /// status codes. 27 | /// 28 | public string AllSendStatusCodes { get; set; } 29 | 30 | /// 31 | /// Gets or sets the number of throttle responses. 32 | /// 33 | public int TotalNumberOfSendThrottles { get; set; } 34 | 35 | /// 36 | /// Gets or sets the error message when trying to send the notification. 37 | /// 38 | public string ErrorMessage { get; set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/Teams/Messages/SendMessageResult.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.Teams 7 | { 8 | /// 9 | /// Send message result enum. 10 | /// 11 | public enum SendMessageResult 12 | { 13 | /// 14 | /// Type indicating sending the notification succeeded. 15 | /// 16 | Succeeded, 17 | 18 | /// 19 | /// Type indicating sending the notification was throttled. 20 | /// 21 | Throttled, 22 | 23 | /// 24 | /// Type indicating sending the notification failed. 25 | /// 26 | Failed, 27 | 28 | /// 29 | /// Type indicating that the recipient can't be found. 30 | /// When sending a notification to a removed recipient, the send function gets 404 error. 31 | /// The recipient should be excluded from the list. 32 | /// 33 | RecipientNotFound, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/Teams/TeamMembers/ITeamMembersService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.Teams 7 | { 8 | using System.Collections.Generic; 9 | using System.Threading.Tasks; 10 | using Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.UserData; 11 | 12 | /// 13 | /// Team Members service interface. 14 | /// 15 | public interface ITeamMembersService 16 | { 17 | /// 18 | /// Get all the members in a team using user app id. 19 | /// 20 | /// Team Id. Example: "19:44777361677b439281a0f0cd914cb149@thread.skype". 21 | /// Tenant Id. 22 | /// Service url. 23 | /// All the members in a team. 24 | public Task> GetUsersAsync(string teamId, string tenantId, string serviceUrl); 25 | 26 | /// 27 | /// Get all the members in a team using author app id. 28 | /// 29 | /// Team Id. Example: "19:44777361677b439281a0f0cd914cb149@thread.skype". 30 | /// Tenant Id. 31 | /// Service url. 32 | /// All the members in a team. 33 | public Task> GetAuthorsAsync(string teamId, string tenantId, string serviceUrl); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Common/Services/User/IUserTypeService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Common.Services.User 7 | { 8 | using System.Collections.Generic; 9 | using System.Threading.Tasks; 10 | using Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.UserData; 11 | 12 | /// 13 | /// The user type service interface. 14 | /// 15 | public interface IUserTypeService 16 | { 17 | /// 18 | /// Update user type of existing user if it is not set. 19 | /// 20 | /// User Data Entity. 21 | /// Type of the user such as Member or Guest. 22 | /// A representing the result of the asynchronous operation. 23 | public Task UpdateUserTypeForExistingUserAsync(UserDataEntity userDataEntity, string userType); 24 | 25 | /// 26 | /// Update user type of existing user list if it is not set. 27 | /// 28 | /// User Data Entity list. 29 | /// A representing the result of the asynchronous operation. 30 | public Task UpdateUserTypeForExistingUserListAsync(IEnumerable userDataEntities); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Data.Func/CleanUpFileOptions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Data.Func 7 | { 8 | /// 9 | /// Options used for holding clean up file number in days. 10 | /// 11 | public class CleanUpFileOptions 12 | { 13 | /// 14 | /// Gets or sets the clean up file number in days. 15 | /// 16 | public string CleanUpFile { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Data.Func/DataQueueMessageOptions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Data.Func 7 | { 8 | /// 9 | /// Options for data queue messages. 10 | /// 11 | public class DataQueueMessageOptions 12 | { 13 | /// 14 | /// Gets or sets the value for the delay to be applied to the 15 | /// requeued data queue trigger message if the trigger message 16 | /// is to be requeued in the first ten minutes of the notification 17 | /// being sent - this way, the initial results can be aggregated 18 | /// more often and displayed to the user faster so they are 19 | /// confident sending has started and is progressing. 20 | /// 21 | public double FirstTenMinutesRequeueMessageDelayInSeconds { get; set; } 22 | 23 | /// 24 | /// Gets or sets the value for the delay to be applied to the 25 | /// requeued data queue trigger message if the trigger message 26 | /// is to be requeued after the first ten minutes of the notification 27 | /// being sent. 28 | /// 29 | public double RequeueMessageDelayInSeconds { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Data.Func/Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 1 : Define the base image 2 | # This will setup the image that will be used for production(aliased as "base"). 3 | FROM mcr.microsoft.com/azure-functions/dotnet:3.0 AS base 4 | WORKDIR /home/site/wwwroot 5 | EXPOSE 80 6 | 7 | # Stage 2: Build and publish the code 8 | # Uses an sdk image(aliased as "build"), copies our project code into a working directory, 9 | # restores Nuget packages, builds the code and publishes it to a directory names publish. 10 | FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build 11 | WORKDIR /src 12 | COPY ["Microsoft.Teams.Apps.CompanyCommunicator.Data.Func/Microsoft.Teams.Apps.CompanyCommunicator.Data.Func.csproj", "Microsoft.Teams.Apps.CompanyCommunicator.Data.Func/"] 13 | COPY ["Microsoft.Teams.Apps.CompanyCommunicator.Common/Microsoft.Teams.Apps.CompanyCommunicator.Common.csproj", "Microsoft.Teams.Apps.CompanyCommunicator.Common/"] 14 | RUN dotnet restore "Microsoft.Teams.Apps.CompanyCommunicator.Data.Func/Microsoft.Teams.Apps.CompanyCommunicator.Data.Func.csproj" 15 | COPY . . 16 | WORKDIR "/src/Microsoft.Teams.Apps.CompanyCommunicator.Data.Func" 17 | RUN dotnet build "Microsoft.Teams.Apps.CompanyCommunicator.Data.Func.csproj" -c Release -o /app/build 18 | 19 | FROM build AS publish 20 | RUN dotnet publish "Microsoft.Teams.Apps.CompanyCommunicator.Data.Func.csproj" -c Release -o /app/publish 21 | 22 | # Stage 3: Build and publish the code 23 | # This copies the publish directory into production image's working directory. 24 | FROM base AS final 25 | WORKDIR /home/site/wwwroot 26 | COPY --from=publish /app/publish . 27 | ENV AzureWebJobsScriptRoot=/home/site/wwwroot \ 28 | AzureFunctionsJobHost__Logging__Console__IsEnabled=true -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Data.Func/Services/FileCardServices/IFileCardService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Data.Func.Services.FileCardServices 7 | { 8 | using System.Threading.Tasks; 9 | 10 | /// 11 | /// The file card service to manange the card. 12 | /// 13 | public interface IFileCardService 14 | { 15 | /// 16 | /// Delete the card and send the permission expired message. 17 | /// 18 | /// the user id. 19 | /// the file consent id. 20 | /// A representing the asynchronous operation. 21 | Task DeleteAsync(string userId, string fileConsentId); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Data.Func/Services/NotificationDataServices/OrchestrationStatus.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Data.Func.Services.NotificationDataServices 7 | { 8 | /// 9 | /// Orchestration instance status. 10 | /// 11 | public enum OrchestrationStatus 12 | { 13 | /// 14 | /// Orchestration instance is Running. 15 | /// 16 | Running, 17 | 18 | /// 19 | /// Orchestration instance is Terminated. 20 | /// 21 | Terminated, 22 | 23 | /// 24 | /// Orchestration instance is Completed. 25 | /// 26 | Completed, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Data.Func/Services/NotificationDataServices/OrchestrationStatusResponse.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Data.Func.Services.NotificationDataServices 7 | { 8 | /// 9 | /// Orchestration Status response. 10 | /// 11 | public class OrchestrationStatusResponse 12 | { 13 | /// 14 | /// Gets or sets the orchestration name. 15 | /// 16 | public string Name { get; set; } 17 | 18 | /// 19 | /// Gets or sets the Instance id of the orchestration. 20 | /// 21 | public string InstanceId { get; set; } 22 | 23 | /// 24 | /// Gets or sets the runtime status of the orchestration. 25 | /// 26 | public string RuntimeStatus { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Data.Func/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "extensions": { 4 | "serviceBus": { 5 | "messageHandlerOptions": { 6 | "maxConcurrentCalls": 1, 7 | "maxAutoRenewDuration": "00:35:00", 8 | "autoComplete": true 9 | } 10 | } 11 | }, 12 | "logging": { 13 | "applicationInsights": { 14 | "samplingSettings": { 15 | "isEnabled": false 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 1 : Define the base image 2 | # This will setup the image that will be used for production(aliased as "base"). 3 | FROM mcr.microsoft.com/azure-functions/dotnet:3.0 AS base 4 | WORKDIR /home/site/wwwroot 5 | EXPOSE 80 6 | 7 | # Stage 2: Build and publish the code 8 | # Uses an sdk image(aliased as "build"), copies our project code into a working directory, 9 | # restores Nuget packages, builds the code and publishes it to a directory names publish. 10 | FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build 11 | WORKDIR /src 12 | COPY ["Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func/Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.csproj", "Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func/"] 13 | COPY ["Microsoft.Teams.Apps.CompanyCommunicator.Common/Microsoft.Teams.Apps.CompanyCommunicator.Common.csproj", "Microsoft.Teams.Apps.CompanyCommunicator.Common/"] 14 | RUN dotnet restore "Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func/Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.csproj" 15 | COPY . . 16 | WORKDIR "/src/Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func" 17 | RUN dotnet build "Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.csproj" -c Release -o /app/build 18 | 19 | FROM build AS publish 20 | RUN dotnet publish "Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.csproj" -c Release -o /app/publish 21 | 22 | # Stage 3: Build and publish the code 23 | # This copies the publish directory into production image's working directory. 24 | FROM base AS final 25 | WORKDIR /home/site/wwwroot 26 | COPY --from=publish /app/publish . 27 | ENV AzureWebJobsScriptRoot=/home/site/wwwroot \ 28 | AzureFunctionsJobHost__Logging__Console__IsEnabled=true -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/Export/Mappers/MetadataMap.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Mappers 7 | { 8 | using System; 9 | using CsvHelper.Configuration; 10 | using Microsoft.Extensions.Localization; 11 | using Microsoft.Teams.Apps.CompanyCommunicator.Common.Resources; 12 | using Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Model; 13 | 14 | /// 15 | /// Mapper class for MetaData. 16 | /// 17 | public sealed class MetadataMap : ClassMap 18 | { 19 | private readonly IStringLocalizer localizer; 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// Localization service. 25 | public MetadataMap(IStringLocalizer localizer) 26 | { 27 | this.localizer = localizer ?? throw new ArgumentNullException(nameof(localizer)); 28 | this.Map(x => x.MessageTitle).Name(this.localizer.GetString("ColumnName_MessageTitle")); 29 | this.Map(x => x.SentTimeStamp).Name(this.localizer.GetString("ColumnName_SentTimeStamp")); 30 | this.Map(x => x.ExportTimeStamp).Name(this.localizer.GetString("ColumnName_ExportTimeStamp")); 31 | this.Map(x => x.ExportedBy).Name(this.localizer.GetString("ColumnName_ExportedBy")); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/Export/Mappers/TeamDataMap.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Mappers 7 | { 8 | using System; 9 | using CsvHelper.Configuration; 10 | using Microsoft.Extensions.Localization; 11 | using Microsoft.Teams.Apps.CompanyCommunicator.Common.Resources; 12 | using Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Model; 13 | 14 | /// 15 | /// Mapper class for TeamData. 16 | /// 17 | public sealed class TeamDataMap : ClassMap 18 | { 19 | private readonly IStringLocalizer localizer; 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// Localization service. 25 | public TeamDataMap(IStringLocalizer localizer) 26 | { 27 | this.localizer = localizer ?? throw new ArgumentNullException(nameof(localizer)); 28 | this.Map(x => x.Id).Name(this.localizer.GetString("ColumnName_TeamId")); 29 | this.Map(x => x.Name).Name(this.localizer.GetString("ColumnName_TeamName")); 30 | this.Map(x => x.DeliveryStatus).Name(this.localizer.GetString("ColumnName_DeliveryStatus")); 31 | this.Map(x => x.StatusReason).Name(this.localizer.GetString("ColumnName_StatusReason")); 32 | this.Map(x => x.Error).Name(this.localizer.GetString("ColumnName_Error")); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/Export/Model/Error.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Model 7 | { 8 | /// 9 | /// Error model class. 10 | /// 11 | public class Error 12 | { 13 | /// 14 | /// Gets or sets the code. 15 | /// 16 | public string Code { get; set; } 17 | 18 | /// 19 | /// Gets or sets the message. 20 | /// 21 | public string Message { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/Export/Model/ExportMessageQueueContent.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Model 7 | { 8 | /// 9 | /// Azure service bus export queue message content class. 10 | /// 11 | public class ExportMessageQueueContent 12 | { 13 | /// 14 | /// Gets or sets the notification id value. 15 | /// 16 | public string NotificationId { get; set; } 17 | 18 | /// 19 | /// Gets or sets the user id value. 20 | /// 21 | public string UserId { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/Export/Model/Metadata.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Model 7 | { 8 | using System; 9 | 10 | /// 11 | /// Metadata model class. 12 | /// 13 | public class Metadata 14 | { 15 | /// 16 | /// Gets or sets the message title. 17 | /// 18 | public string MessageTitle { get; set; } 19 | 20 | /// 21 | /// Gets or sets the sent timestamp. 22 | /// 23 | public DateTime? SentTimeStamp { get; set; } 24 | 25 | /// 26 | /// Gets or sets the export timestamp. 27 | /// 28 | public DateTime? ExportTimeStamp { get; set; } 29 | 30 | /// 31 | /// Gets or sets the exported by user id. 32 | /// 33 | public string ExportedBy { get; set; } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/Export/Model/RootErrorMessage.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Model 7 | { 8 | /// 9 | /// Root error message model class. 10 | /// 11 | public class RootErrorMessage 12 | { 13 | /// 14 | /// Gets or sets the error message. 15 | /// 16 | public Error Error { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/Export/Model/TeamData.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Model 7 | { 8 | /// 9 | /// the model class for team data. 10 | /// 11 | public class TeamData 12 | { 13 | /// 14 | /// Gets or sets the team id value. 15 | /// 16 | public string Id { get; set; } 17 | 18 | /// 19 | /// Gets or sets the team id value. 20 | /// 21 | public string Name { get; set; } 22 | 23 | /// 24 | /// Gets or sets the delivery status value. 25 | /// 26 | public string DeliveryStatus { get; set; } 27 | 28 | /// 29 | /// Gets or sets the status reason value. 30 | /// 31 | public string StatusReason { get; set; } 32 | 33 | /// 34 | /// Gets or sets the error message. 35 | /// 36 | public string Error { get; set; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/Export/Model/UserData.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Model 7 | { 8 | /// 9 | /// the model class for user data. 10 | /// 11 | public class UserData 12 | { 13 | /// 14 | /// Gets or sets the user id. 15 | /// 16 | public string Id { get; set; } 17 | 18 | /// 19 | /// Gets or sets the user principal name. 20 | /// 21 | public string Upn { get; set; } 22 | 23 | /// 24 | /// Gets or sets the display name. 25 | /// 26 | public string Name { get; set; } 27 | 28 | /// 29 | /// Gets or sets the user type. 30 | /// 31 | public string UserType { get; set; } 32 | 33 | /// 34 | /// Gets or sets the delivery status value. 35 | /// 36 | public string DeliveryStatus { get; set; } 37 | 38 | /// 39 | /// Gets or sets the status reason value. 40 | /// 41 | public string StatusReason { get; set; } 42 | 43 | /// 44 | /// Gets or sets the error message. 45 | /// 46 | public string Error { get; set; } 47 | } 48 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/Export/Streams/IDataStreamFacade.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Streams 7 | { 8 | using System.Collections.Generic; 9 | using Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Export.Model; 10 | 11 | /// 12 | /// Facade to get the data stream. 13 | /// 14 | public interface IDataStreamFacade 15 | { 16 | /// 17 | /// Get the user data list, which can be iterated asynchronously. 18 | /// 19 | /// the notification id. 20 | /// the notification status. 21 | /// the streams of user data. 22 | IAsyncEnumerable> GetUserDataStreamAsync(string notificationId, string notificationStatus); 23 | 24 | /// 25 | /// Get the team data list, which can be iterated asynchronously. 26 | /// 27 | /// the notification id. 28 | /// the notification status. 29 | /// the streams of team data. 30 | IAsyncEnumerable> GetTeamDataStreamAsync(string notificationId, string notificationStatus); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/PreparingToSend/DataQueueMessageOptions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.PreparingToSend 7 | { 8 | /// 9 | /// Options for data queue messages. 10 | /// 11 | public class DataQueueMessageOptions 12 | { 13 | /// 14 | /// Gets or sets the value for the delay to be applied to the data queue message. 15 | /// 16 | public int MessageDelayInSeconds { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/PreparingToSend/FunctionSettings.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.PreparingToSend 7 | { 8 | using System; 9 | using Microsoft.Azure.WebJobs.Extensions.DurableTask; 10 | 11 | /// 12 | /// Function settings. 13 | /// 14 | public class FunctionSettings 15 | { 16 | /// 17 | /// A default setting for the retry options for starting an activity / sub-orchestrator. 18 | /// 19 | public static readonly RetryOptions DefaultRetryOptions 20 | = new RetryOptions( 21 | firstRetryInterval: TimeSpan.FromSeconds(5), 22 | maxNumberOfAttempts: 3); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/PreparingToSend/TeamsConversationOptions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func 7 | { 8 | /// 9 | /// Options for Teams Conversation. 10 | /// 11 | public class TeamsConversationOptions 12 | { 13 | /// 14 | /// Gets or sets a value indicating whether user app should be proactively installed. 15 | /// 16 | public bool ProactivelyInstallUserApp { get; set; } 17 | 18 | /// 19 | /// Gets or sets maximum attempts to create conversation with teams user. 20 | /// 21 | public int MaxAttemptsToCreateConversation { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Prep.Func/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "extensions": { 4 | "serviceBus": { 5 | "messageHandlerOptions": { 6 | "maxConcurrentCalls": 1 7 | } 8 | }, 9 | "durableTask": { 10 | "hubName": "PrepareToSendFunctionTaskHub", 11 | "storageProvider": { 12 | "controlQueueVisibilityTimeout": "01:00:00", 13 | "workItemQueueVisibilityTimeout": "01:00:00" 14 | }, 15 | "extendedSessionsEnabled": true, 16 | "extendedSessionIdleTimeoutInSeconds": 60, 17 | "maxConcurrentOrchestratorFunctions": 3, 18 | "maxConcurrentActivityFunctions": 10 19 | } 20 | }, 21 | "functionTimeout": "01:00:00", 22 | "logging": { 23 | "applicationInsights": { 24 | "samplingSettings": { 25 | "isEnabled": false 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Send.Func/Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 1 : Define the base image 2 | # This will setup the image that will be used for production(aliased as "base"). 3 | FROM mcr.microsoft.com/azure-functions/dotnet:3.0 AS base 4 | WORKDIR /home/site/wwwroot 5 | EXPOSE 80 6 | 7 | # Stage 2: Build and publish the code 8 | # Uses an sdk image(aliased as "build"), copies our project code into a working directory, 9 | # restores Nuget packages, builds the code and publishes it to a directory names publish. 10 | FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build 11 | WORKDIR /src 12 | COPY ["Microsoft.Teams.Apps.CompanyCommunicator.Send.Func/Microsoft.Teams.Apps.CompanyCommunicator.Send.Func.csproj", "Microsoft.Teams.Apps.CompanyCommunicator.Send.Func/"] 13 | COPY ["Microsoft.Teams.Apps.CompanyCommunicator.Common/Microsoft.Teams.Apps.CompanyCommunicator.Common.csproj", "Microsoft.Teams.Apps.CompanyCommunicator.Common/"] 14 | RUN dotnet restore "Microsoft.Teams.Apps.CompanyCommunicator.Send.Func/Microsoft.Teams.Apps.CompanyCommunicator.Send.Func.csproj" 15 | COPY . . 16 | WORKDIR "/src/Microsoft.Teams.Apps.CompanyCommunicator.Send.Func" 17 | RUN dotnet build "Microsoft.Teams.Apps.CompanyCommunicator.Send.Func.csproj" -c Release -o /app/build 18 | 19 | FROM build AS publish 20 | RUN dotnet publish "Microsoft.Teams.Apps.CompanyCommunicator.Send.Func.csproj" -c Release -o /app/publish 21 | 22 | # Stage 3: Build and publish the code 23 | # This copies the publish directory into production image's working directory. 24 | FROM base AS final 25 | WORKDIR /home/site/wwwroot 26 | COPY --from=publish /app/publish . 27 | ENV AzureWebJobsScriptRoot=/home/site/wwwroot \ 28 | AzureFunctionsJobHost__Logging__Console__IsEnabled=true -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Send.Func/SendFunctionOptions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Send.Func 7 | { 8 | /// 9 | /// Options used to configure the Company Communicator Send Function. 10 | /// 11 | public class SendFunctionOptions 12 | { 13 | /// 14 | /// Gets or sets the max number of request attempts. 15 | /// 16 | public int MaxNumberOfAttempts { get; set; } 17 | 18 | /// 19 | /// Gets or sets the number of seconds to delay before 20 | /// retrying to send the message. 21 | /// 22 | public double SendRetryDelayNumberOfSeconds { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator.Send.Func/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0", 3 | "extensions": { 4 | "serviceBus": { 5 | "messageHandlerOptions": { 6 | "maxConcurrentCalls": 30 7 | } 8 | } 9 | }, 10 | "logging": { 11 | "applicationInsights": { 12 | "samplingSettings": { 13 | "isEnabled": false 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Authentication/MSGraphScopeRequirement.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Authentication 7 | { 8 | using Microsoft.AspNetCore.Authorization; 9 | 10 | /// 11 | /// This class is an authorization policy requirement. 12 | /// It specifies that an access token must contain group.read.all scope. 13 | /// 14 | public class MSGraphScopeRequirement : IAuthorizationRequirement 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// Microsoft Graph Scopes. 20 | public MSGraphScopeRequirement(string[] scopes) 21 | { 22 | this.Scopes = scopes; 23 | } 24 | 25 | /// 26 | /// Gets microsoft Graph Scopes. 27 | /// 28 | public string[] Scopes { get; private set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Authentication/MustBeValidDeleteUpnRequirement.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Authentication 7 | { 8 | using Microsoft.AspNetCore.Authorization; 9 | 10 | /// 11 | /// This class is an authorization policy requirement. 12 | /// It specifies that an id token must contain Upn claim. 13 | /// 14 | public class MustBeValidDeleteUpnRequirement : IAuthorizationRequirement 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Authentication/MustBeValidUpnRequirement.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Authentication 7 | { 8 | using Microsoft.AspNetCore.Authorization; 9 | 10 | /// 11 | /// This class is an authorization policy requirement. 12 | /// It specifies that an id token must contain Upn claim. 13 | /// 14 | public class MustBeValidUpnRequirement : IAuthorizationRequirement 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Authentication/PolicyNames.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Authentication 7 | { 8 | /// 9 | /// This class lists the names of the custom authorization policies in the project. 10 | /// 11 | public class PolicyNames 12 | { 13 | /// 14 | /// The name of the authorization policy, MustHaveUpnClaimPolicy. 15 | /// 16 | public const string MustBeValidUpnPolicy = "MustBeValidUpnPolicy"; 17 | 18 | /// 19 | /// The name of the authorization policy, MSGraphGroupDataPolicy. 20 | /// 21 | public const string MSGraphGroupDataPolicy = "MSGraphGroupDataPolicy"; 22 | 23 | /// 24 | /// The name of the authorization policy, MustHaveDeleteUpnClaimPolicy. 25 | /// 26 | public const string MustBeValidDeleteUpnPolicy = "MustBeValidDeleteUpnPolicy"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Bot/BotFilterMiddlewareOptions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Bot 7 | { 8 | /// 9 | /// Options used for creating the bot filter middleware. 10 | /// 11 | public class BotFilterMiddlewareOptions 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | public BotFilterMiddlewareOptions() 17 | { 18 | // Default this value to false. 19 | this.DisableTenantFilter = false; 20 | } 21 | 22 | /// 23 | /// Gets or sets a value indicating whether the tenant 24 | /// filtering for the bot should be disabled. 25 | /// 26 | public bool DisableTenantFilter { get; set; } 27 | 28 | /// 29 | /// Gets or sets the allowed tenants list. 30 | /// 31 | public string AllowedTenants { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Bot/CompanyCommunicatorBotAdapter.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Bot 7 | { 8 | using System; 9 | using Microsoft.Bot.Builder.Integration.AspNet.Core; 10 | using Microsoft.Bot.Connector.Authentication; 11 | 12 | /// 13 | /// The Company Communicator Bot Adapter. 14 | /// 15 | public class CompanyCommunicatorBotAdapter : CloudAdapter 16 | { 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | /// Teams message filter middleware instance. 21 | /// Bot framework authentication. 22 | public CompanyCommunicatorBotAdapter( 23 | CompanyCommunicatorBotFilterMiddleware companyCommunicatorBotFilterMiddleware, 24 | BotFrameworkAuthentication botFrameworkAuthentication) 25 | : base(botFrameworkAuthentication) 26 | { 27 | companyCommunicatorBotFilterMiddleware = companyCommunicatorBotFilterMiddleware ?? throw new ArgumentNullException(nameof(companyCommunicatorBotFilterMiddleware)); 28 | 29 | // Middleware 30 | this.Use(companyCommunicatorBotFilterMiddleware); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": ["plugin:react/recommended", "standard-with-typescript"], 7 | "overrides": [], 8 | "parserOptions": { 9 | "ecmaVersion": "latest", 10 | "sourceType": "module", 11 | "project": "tsconfig.json" 12 | }, 13 | "plugins": ["react"], 14 | "rules": { 15 | "@typescript-eslint/semi": ["error", "always"], 16 | "@typescript-eslint/explicit-function-return-type": ["off"], 17 | "@typescript-eslint/comma-dangle": ["off"], 18 | "@typescript-eslint/member-delimiter-style": ["off"], 19 | "@typescript-eslint/strict-boolean-expressions": ["off"], 20 | "@typescript-eslint/space-before-function-paren": ["off"], 21 | "@typescript-eslint/consistent-type-imports": ["off"] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Source/CompanyCommunicator/ClientApp/public/favicon.ico -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/public/image/imagePlaceholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Source/CompanyCommunicator/ClientApp/public/image/imagePlaceholder.png -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Company Communicator", 3 | "name": "Company Communicator application", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | import React from "react"; 5 | import ReactDOM from "react-dom"; 6 | import { App } from "./App"; 7 | 8 | it("renders without crashing", () => { 9 | const div = document.createElement("div"); 10 | ReactDOM.render(, div); 11 | ReactDOM.unmountComponentAtNode(div); 12 | }); 13 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/assets/Images/FeedbackIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/assets/Images/HelpIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ? 9 | 10 | 11 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/assets/Images/InfoIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/assets/Images/mslogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Source/CompanyCommunicator/ClientApp/src/assets/Images/mslogo.png -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/DeleteMessages/deleteMessage.scss: -------------------------------------------------------------------------------- 1 | .delete-messages { 2 | .customdaterangelabel { 3 | .fui-Label { 4 | padding-right: 0; 5 | } 6 | .fui-InfoLabel { 7 | position: relative; 8 | svg{ 9 | height: 19px; 10 | width: 19px; 11 | margin-top: 30%; 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/DraftMessages/draftMessages.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | import * as React from 'react'; 5 | import { useTranslation } from 'react-i18next'; 6 | import { Spinner } from '@fluentui/react-components'; 7 | import { GetDraftMessagesAction } from '../../actions'; 8 | import { RootState, useAppDispatch, useAppSelector } from '../../store'; 9 | import { DraftMessageDetail } from './draftMessageDetail'; 10 | 11 | export const DraftMessages = () => { 12 | const { t } = useTranslation(); 13 | const draftMessages = useAppSelector((state: RootState) => state.messages).draftMessages.payload; 14 | const loader = useAppSelector((state: RootState) => state.messages).isDraftMessagesFetchOn.payload; 15 | const dispatch = useAppDispatch(); 16 | 17 | React.useEffect(() => { 18 | if (draftMessages && draftMessages.length === 0) { 19 | GetDraftMessagesAction(dispatch); 20 | } 21 | }, [draftMessages]); 22 | 23 | return ( 24 | <> 25 | {loader && } 26 | {draftMessages && draftMessages.length === 0 && !loader &&
{t('EmptyDraftMessages')}
} 27 | {draftMessages && draftMessages.length > 0 && !loader && } 28 | 29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/ErrorPage/errorPage.scss: -------------------------------------------------------------------------------- 1 | .error-message { 2 | text-align: center; 3 | width: 80%; 4 | height: 10rem; 5 | position: absolute; 6 | top: 0; 7 | bottom: 0; 8 | left: 0; 9 | right: 0; 10 | margin: auto; 11 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/ErrorPage/errorPage.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | import './errorPage.scss'; 5 | import React from 'react'; 6 | import { useTranslation } from 'react-i18next'; 7 | import { useParams } from 'react-router-dom'; 8 | import { Text } from '@fluentui/react-components'; 9 | 10 | const ErrorPage = () => { 11 | const { t } = useTranslation(); 12 | const { id } = useParams() as any; 13 | 14 | function parseErrorMessage (): string { 15 | if (id) { 16 | if (id === '401') { 17 | return t('UnauthorizedErrorMessage'); 18 | } else if (id === '403') { 19 | return t('ForbiddenErrorMessage'); 20 | } 21 | } 22 | return t('GeneralErrorMessage'); 23 | } 24 | 25 | return ( 26 | 27 | {parseErrorMessage()} 28 | 29 | ); 30 | }; 31 | 32 | export default ErrorPage; 33 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/NewMessage/newMessage.scss: -------------------------------------------------------------------------------- 1 | .new-messages { 2 | div[class~='schedulesend-datetime'] { 3 | display: flex; 4 | justify-content: space-between; 5 | align-items: center; 6 | column-gap: 6px; 7 | width: 100%; 8 | margin-left: 36px; 9 | 10 | div[class~='schedule-datepicker'] { 11 | height: 40px; 12 | width: 45%; 13 | display: inline-block; 14 | } 15 | div[class~='schedule-datepicker']:focus { 16 | outline: 2px solid #414156; 17 | } 18 | 19 | div[class~='schedule-timepicker'] { 20 | width: 45%; 21 | display: inline-block; 22 | margin-left: 7px; 23 | margin-right: 36px; 24 | 25 | div[class~='ms-ComboBox'] { 26 | height: 32px; 27 | margin-bottom: 8px; 28 | } 29 | div[class~='ms-ComboBox-callout'] { 30 | height: 150px; 31 | } 32 | } 33 | } 34 | div[class~='validationText'] { 35 | margin-left: 36px; 36 | display: flex; 37 | color: red; 38 | } 39 | 40 | .flex-container { 41 | display: flex; 42 | flex-direction: row; 43 | } 44 | @media screen and (max-width: 767px) { 45 | div[class~='schedulesend-datetime'] { 46 | align-items: start; 47 | div[class~='schedule-timepicker'] { 48 | margin-left: 0px; 49 | width: 65%; 50 | } 51 | div[class~='schedule-datepicker'] { 52 | width: 65%; 53 | div[class~='ms-TextField-wrapper']{ 54 | height: 40px; 55 | } 56 | } 57 | } 58 | .flex-container { 59 | flex-direction: column; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/PreviewMessageConfirmation/previewMessageConfirmation.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { useTranslation } from 'react-i18next'; 3 | 4 | import { Body1Strong } from '@fluentui/react-components'; 5 | 6 | export const PreviewMessageConfirmation = () => { 7 | const { t } = useTranslation(); 8 | return ( 9 |
10 | {t('previewMessageConfirmation') ?? ''} 11 |
12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/ScheduledMessages/scheduledMessages.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | import * as React from 'react'; 5 | import { useTranslation } from 'react-i18next'; 6 | import { Spinner } from '@fluentui/react-components'; 7 | import { GetScheduledMessagesAction } from '../../actions'; 8 | import { RootState, useAppDispatch, useAppSelector } from '../../store'; 9 | import { ScheduledMessageDetail } from './scheduledMessageDetail'; 10 | import * as CustomHooks from '../../useInterval'; 11 | 12 | export const ScheduledMessages = () => { 13 | const { t } = useTranslation(); 14 | const scheduledMessages = useAppSelector((state: RootState) => state.messages).scheduledMessages.payload; 15 | const loader = useAppSelector((state: RootState) => state.messages).isScheduledMessagesFetchOn.payload; 16 | const dispatch = useAppDispatch(); 17 | const delay = 60000; 18 | 19 | React.useEffect(() => { 20 | if (scheduledMessages && scheduledMessages.length === 0) { 21 | GetScheduledMessagesAction(dispatch); 22 | } 23 | }, [scheduledMessages]); 24 | 25 | CustomHooks.useInterval(() => { 26 | GetScheduledMessagesAction(dispatch); 27 | }, delay); 28 | return ( 29 | <> 30 | {loader && } 31 | {scheduledMessages && scheduledMessages.length === 0 && !loader &&
{t('EmptyScheduledMessages')}
} 32 | {scheduledMessages && scheduledMessages.length > 0 && !loader && 33 | } 34 | 35 | ); 36 | }; 37 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/SentMessages/sentMessages.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | import * as React from 'react'; 5 | import { useTranslation } from 'react-i18next'; 6 | import { Spinner } from '@fluentui/react-components'; 7 | import { GetSentMessagesAction, GetSentMessagesSilentAction } from '../../actions'; 8 | import { RootState, useAppDispatch, useAppSelector } from '../../store'; 9 | import { SentMessageDetail } from './sentMessageDetail'; 10 | import * as CustomHooks from '../../useInterval'; 11 | 12 | export const SentMessages = () => { 13 | const { t } = useTranslation(); 14 | const sentMessages = useAppSelector((state: RootState) => state.messages).sentMessages.payload; 15 | const loader = useAppSelector((state: RootState) => state.messages).isSentMessagesFetchOn.payload; 16 | const dispatch = useAppDispatch(); 17 | const delay = 60000; 18 | 19 | React.useEffect(() => { 20 | if (sentMessages && sentMessages.length === 0) { 21 | GetSentMessagesAction(dispatch); 22 | } 23 | }, [sentMessages]); 24 | 25 | CustomHooks.useInterval(() => { 26 | GetSentMessagesSilentAction(dispatch); 27 | }, delay); 28 | 29 | return ( 30 | <> 31 | {loader && } 32 | {sentMessages && sentMessages.length === 0 && !loader &&
{t('EmptySentMessages')}
} 33 | {sentMessages && sentMessages.length > 0 && !loader && } 34 | 35 | ); 36 | }; 37 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/SignInPage/signInPage.scss: -------------------------------------------------------------------------------- 1 | .sign-in-content-container { 2 | text-align: center; 3 | width: 80%; 4 | height: 10rem; 5 | position: absolute; 6 | top:0; 7 | bottom: 0; 8 | left: 0; 9 | right: 0; 10 | margin: auto; 11 | } 12 | 13 | .space { 14 | margin: 0.5rem; 15 | } 16 | 17 | .sign-in-button { 18 | line-height: normal 19 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/SignInPage/signInPage.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | import './signInPage.scss'; 5 | import React from 'react'; 6 | import { useTranslation } from 'react-i18next'; 7 | import { Button, Text } from '@fluentui/react-components'; 8 | import { authentication } from '@microsoft/teams-js'; 9 | import i18n from '../../i18n'; 10 | import { ROUTE_PARTS } from '../../routes'; 11 | 12 | const SignInPage = () => { 13 | const { t } = useTranslation(); 14 | const errorMessage = t('SignInPromptMessage'); 15 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error 16 | // @ts-ignore 17 | const lang: string = i18n.language; 18 | 19 | function onSignIn() { 20 | authentication 21 | .authenticate({ url: window.location.origin + '/signin-simple-start', isExternal: true }) 22 | .then(() => { 23 | console.log('Login succeeded!'); 24 | window.location.href = '/messages'; 25 | }) 26 | .catch((error) => { 27 | // eslint-disable-next-line @typescript-eslint/restrict-plus-operands 28 | console.log('Login failed: ' + error); 29 | window.location.href = `/${ROUTE_PARTS.ERROR_PAGE}?locale=${lang}`; 30 | }); 31 | } 32 | 33 | return ( 34 |
35 | 36 | {errorMessage} 37 | 38 |
39 | 42 |
43 | ); 44 | }; 45 | 46 | export default SignInPage; 47 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/SignInPage/signInSimpleEnd.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | import React, { useEffect } from 'react'; 5 | import { app, authentication } from '@microsoft/teams-js'; 6 | 7 | const SignInSimpleEnd: React.FunctionComponent = () => { 8 | // Parse hash parameters into key-value pairs 9 | function getHashParameters() { 10 | const hashParams: any = {}; 11 | try { 12 | window.location.hash 13 | .substr(1) 14 | .split('&') 15 | .forEach(function (item) { 16 | const s = item.split('='); 17 | const k = s[0]; 18 | const v = s[1] && decodeURIComponent(s[1]); 19 | hashParams[k] = v; 20 | }); 21 | return hashParams; 22 | } catch (error) { 23 | console.log(error); 24 | } 25 | return null; 26 | } 27 | 28 | useEffect(() => { 29 | void app.initialize().then(() => { 30 | const hashParams: any = getHashParameters(); 31 | if (hashParams.error) { 32 | // Authentication/authorization failed 33 | authentication.notifyFailure(hashParams.error); 34 | } else if (hashParams.id_token) { 35 | // Success 36 | authentication.notifySuccess(); 37 | } else { 38 | // Unexpected condition: hash does not contain error or access_token parameter 39 | authentication.notifyFailure('UnexpectedFailure'); 40 | } 41 | }); 42 | }, []); 43 | 44 | return <>; 45 | }; 46 | 47 | export default SignInSimpleEnd; 48 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/SignInPage/signInSimpleStart.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | import React, { useEffect } from 'react'; 5 | import { app } from '@microsoft/teams-js'; 6 | import { getAuthenticationConsentMetadata } from '../../apis/messageListApi'; 7 | 8 | const SignInSimpleStart: React.FunctionComponent = () => { 9 | useEffect(() => { 10 | void app.initialize().then(() => { 11 | void app.getContext().then((context) => { 12 | const windowLocationOriginDomain = window.location.origin.replace('https://', ''); 13 | const loginHint = context.user?.userPrincipalName ? context.user.userPrincipalName : ''; 14 | void getAuthenticationConsentMetadata(windowLocationOriginDomain, loginHint).then((result) => { 15 | window.location.assign(result); 16 | }); 17 | }); 18 | }); 19 | }, []); 20 | 21 | return <>; 22 | }; 23 | 24 | export default SignInSimpleStart; 25 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/components/config.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | import React from 'react'; 5 | import { app, pages } from '@microsoft/teams-js'; 6 | import { getBaseUrl } from '../configVariables'; 7 | 8 | export interface IConfigState { 9 | url: string; 10 | } 11 | 12 | class Configuration extends React.Component { 13 | constructor(props: any) { 14 | super(props); 15 | this.state = { 16 | url: getBaseUrl() + '/messages?locale={locale}', 17 | }; 18 | } 19 | 20 | public componentDidMount() { 21 | void app.initialize().then(() => { 22 | pages.config.registerOnSaveHandler((saveEvent) => { 23 | void pages.config.setConfig({ 24 | entityId: 'Company_Communicator_App', 25 | contentUrl: this.state.url, 26 | suggestedDisplayName: 'Company Communicator', 27 | }); 28 | saveEvent.notifySuccess(); 29 | }); 30 | 31 | pages.config.setValidityState(true); 32 | }); 33 | } 34 | 35 | public render(): JSX.Element { 36 | return ( 37 |
38 |

Please click Save to get started.

39 |
40 | ); 41 | } 42 | } 43 | 44 | export default Configuration; 45 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/configVariables.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | export const getBaseUrl = (): string => { 5 | return window.location.origin; 6 | }; 7 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/index.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | import React from 'react'; 5 | import ReactDOM from 'react-dom/client'; 6 | import { Provider } from 'react-redux'; 7 | import { App } from './App'; 8 | import { store } from './store'; 9 | 10 | const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); 11 | 12 | root.render( 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/models/deleteMessages.ts: -------------------------------------------------------------------------------- 1 | export interface IDeleteMessageRequest { 2 | rowKeyId?: string; 3 | selectedDateRange: string; 4 | deletedBy?: string; 5 | startDate: string; 6 | endDate: string; 7 | } 8 | 9 | export interface IDeletedMessagesHistory { 10 | selectedDateRange: string; 11 | recordsDeleted: number; 12 | deletedBy?: string; 13 | status: string; 14 | startDate: Date; 15 | endDate: Date; 16 | } 17 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | /// 5 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/routes.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | export enum ROUTE_PARTS { 5 | CONFIG_TAB = 'configtab', 6 | MESSAGES = 'messages', 7 | NEW_MESSAGE = 'newmessage', 8 | DELETE_MESSAGES = 'deletemessages', 9 | DELETE_MESSAGES_CONFIRM = 'deleteconfirmation', 10 | VIEW_STATUS = 'viewstatus', 11 | SEND_CONFIRMATION = 'sendconfirmation', 12 | ERROR_PAGE = 'errorpage', 13 | SIGN_IN = 'signin', 14 | SIGN_IN_SIMPLE_START = 'signin-simple-start', 15 | SIGN_IN_SIMPLE_END = 'signin-simple-end', 16 | PREVIEW_MESSAGE_CONFIRMATION = 'previewMessageConfirmation', 17 | } 18 | 19 | export enum ROUTE_PARAMS { 20 | ID = 'id', 21 | DELETION_TYPE = 'deletionType', 22 | DELETION_FROM_DATE = 'deletionFromDate', 23 | DELETION_TO_DATE = 'deletionToDate', 24 | } 25 | 26 | export enum ROUTE_QUERY_PARAMS { 27 | LOCALE = 'locale', 28 | } 29 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/store.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. 2 | // Licensed under the MIT License. 3 | 4 | import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; 5 | import { configureStore } from '@reduxjs/toolkit'; 6 | import messagesReducer from './messagesSlice'; 7 | 8 | export const store = configureStore({ 9 | reducer: { messages: messagesReducer }, 10 | devTools: process.env.NODE_ENV !== 'production', 11 | }); 12 | 13 | // Infer the `RootState` and `AppDispatch` types from the store itself 14 | export type RootState = ReturnType; 15 | 16 | // Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState} 17 | export type AppDispatch = typeof store.dispatch; 18 | 19 | export const useAppDispatch = () => useDispatch(); 20 | export const useAppSelector: TypedUseSelectorHook = useSelector; 21 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/src/useInterval.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export const useInterval = (callback: any, delay: any) => { 4 | const savedCallback = React.useRef(); 5 | 6 | // Remember the latest callback. 7 | React.useEffect(() => { 8 | savedCallback.current = callback; 9 | }, [callback]); 10 | 11 | // Set up the interval. 12 | React.useEffect(() => { 13 | const tick = () => { 14 | savedCallback.current(); 15 | }; 16 | 17 | if (delay !== null) { 18 | const id = setInterval(tick, delay); 19 | return () => { 20 | clearInterval(id); 21 | }; 22 | } 23 | }, [delay]); 24 | }; 25 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/ClientApp/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "noEmit": true, 16 | "jsx": "react", 17 | "noFallthroughCasesInSwitch": true 18 | }, 19 | "include": ["src"] 20 | } 21 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "9.1.611.1" 4 | } -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Controllers/DataQueueMessageOptions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Controllers 7 | { 8 | /// 9 | /// Options for data queue messages. 10 | /// 11 | public class DataQueueMessageOptions 12 | { 13 | /// 14 | /// Gets or sets the value for the delay to be applied to the data queue message 15 | /// used to force mark a notification as complete if it is not already 16 | /// complete to ensure it is not left in a "sending" state. 17 | /// 18 | public double ForceCompleteMessageDelayInSeconds { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Controllers/HealthController.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Controllers 7 | { 8 | using Microsoft.AspNetCore.Mvc; 9 | 10 | /// 11 | /// Controller for health endpoint. 12 | /// 13 | [Route("[controller]")] 14 | public class HealthController : Controller 15 | { 16 | /// 17 | /// Report health status of the application. 18 | /// 19 | /// Action. 20 | [HttpGet] 21 | public ActionResult Index() 22 | { 23 | return this.Ok(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Controllers/Options/UserAppOptions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Controllers.Options 7 | { 8 | /// 9 | /// User app options. 10 | /// 11 | public class UserAppOptions 12 | { 13 | /// 14 | /// Gets or sets a value indicating whether user app should be proactively installed. 15 | /// 16 | public bool ProactivelyInstallUserApp { get; set; } 17 | 18 | /// 19 | /// Gets or sets User app's external Id (id in the manifest). 20 | /// 21 | public string UserAppExternalId { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/DraftNotificationPreview/IDraftNotificationPreviewService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.DraftNotificationPreview 7 | { 8 | using System.Net; 9 | using System.Threading.Tasks; 10 | using Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.NotificationData; 11 | using Microsoft.Teams.Apps.CompanyCommunicator.Common.Repositories.TeamData; 12 | 13 | /// 14 | /// Interface for DraftNotificationPreviewService. 15 | /// 16 | public interface IDraftNotificationPreviewService 17 | { 18 | /// 19 | /// Send a preview of a draft notification. 20 | /// 21 | /// Draft notification entity. 22 | /// The team data entity. 23 | /// The Teams channel id. 24 | /// It returns HttpStatusCode.OK, if this method triggers the bot service to send the adaptive card successfully. 25 | /// It returns HttpStatusCode.TooManyRequests, if the bot service throttled the request to send the adaptive card. 26 | public Task SendPreview(NotificationDataEntity draftNotificationEntity, TeamDataEntity teamDataEntity, string teamsChannelId); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Models/DeleteHistoricalMessages.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Models 7 | { 8 | /// 9 | /// Delete message model class. 10 | /// 11 | public class DeleteHistoricalMessages 12 | { 13 | /// 14 | /// Gets or sets the table row key id. 15 | /// 16 | public string RowKeyId { get; set; } 17 | 18 | /// 19 | /// Gets or sets the selected date range for the delete data. 20 | /// 21 | public string SelectedDateRange { get; set; } 22 | 23 | /// 24 | /// Gets or sets the Deleted By field. 25 | /// 26 | public string DeletedBy { get; set; } 27 | 28 | /// 29 | /// Gets or sets the Start Date field. 30 | /// 31 | public string StartDate { get; set; } 32 | 33 | /// 34 | /// Gets or sets the End Date field. 35 | /// 36 | public string EndDate { get; set; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Models/DraftNotificationPreviewRequest.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Models 7 | { 8 | /// 9 | /// Draft notification preview request model class. 10 | /// 11 | public class DraftNotificationPreviewRequest 12 | { 13 | /// 14 | /// Gets or sets draft notification id. 15 | /// 16 | public string DraftNotificationId { get; set; } 17 | 18 | /// 19 | /// Gets or sets Teams team id. 20 | /// 21 | public string TeamsTeamId { get; set; } 22 | 23 | /// 24 | /// Gets or sets Teams channel id. 25 | /// 26 | public string TeamsChannelId { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Models/DraftNotificationSummary.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Models 7 | { 8 | using System; 9 | 10 | /// 11 | /// Draft Notification Summary model class. 12 | /// 13 | public class DraftNotificationSummary 14 | { 15 | /// 16 | /// Gets or sets Notification Id. 17 | /// 18 | public string Id { get; set; } 19 | 20 | /// 21 | /// Gets or sets Title value. 22 | /// 23 | public string Title { get; set; } 24 | 25 | /// 26 | /// Gets or sets ScheduledDate value. 27 | /// 28 | public DateTime? ScheduledDate { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Models/DraftNotificationSummaryForConsent.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Models 7 | { 8 | using System.Collections.Generic; 9 | 10 | /// 11 | /// Draft notification summary (for consent page) model class. 12 | /// 13 | public class DraftNotificationSummaryForConsent 14 | { 15 | /// 16 | /// Gets or sets Notification Id value. 17 | /// 18 | public string NotificationId { get; set; } 19 | 20 | /// 21 | /// Gets or sets Team Names value. 22 | /// 23 | public IEnumerable TeamNames { get; set; } 24 | 25 | /// 26 | /// Gets or sets Roster Names value. 27 | /// 28 | public IEnumerable RosterNames { get; set; } 29 | 30 | /// 31 | /// Gets or sets Group Names value. 32 | /// 33 | public IEnumerable GroupNames { get; set; } 34 | 35 | /// 36 | /// Gets or sets a value indicating whether the All Users option is selected. 37 | /// 38 | public bool AllUsers { get; set; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Models/ExportRequest.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Models 7 | { 8 | /// 9 | /// Export request model class. 10 | /// 11 | public class ExportRequest 12 | { 13 | /// 14 | /// Gets or sets the notification id. 15 | /// 16 | public string Id { get; set; } 17 | 18 | /// 19 | /// Gets or sets the Team Id. 20 | /// 21 | public string TeamId { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Models/GroupData.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Models 7 | { 8 | /// 9 | /// Group data model class. 10 | /// 11 | public class GroupData 12 | { 13 | /// 14 | /// Gets or sets group Id. 15 | /// 16 | public string Id { get; set; } 17 | 18 | /// 19 | /// Gets or sets name. 20 | /// 21 | public string Name { get; set; } 22 | 23 | /// 24 | /// Gets or sets mail. 25 | /// 26 | public string Mail { get; set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Models/TeamData.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Models 7 | { 8 | /// 9 | /// Teams data model class. 10 | /// 11 | public class TeamData 12 | { 13 | /// 14 | /// Gets or sets team Id. 15 | /// 16 | public string Id { get; set; } 17 | 18 | /// 19 | /// Gets or sets name. 20 | /// 21 | public string Name { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model ErrorModel 3 | @{ 4 | ViewData["Title"] = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | @if (Model.ShowRequestId) 11 | { 12 |

13 | Request ID: @Model.RequestId 14 |

15 | } 16 | 17 |

Development Mode

18 |

19 | Swapping to Development environment will display more detailed information about the error that occurred. 20 |

21 |

22 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 23 |

24 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Pages 7 | { 8 | using System.Diagnostics; 9 | using Microsoft.AspNetCore.Mvc; 10 | using Microsoft.AspNetCore.Mvc.RazorPages; 11 | 12 | /// 13 | /// Error model class. 14 | /// 15 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 16 | #pragma warning disable SA1649 // File name should match first type name 17 | public class ErrorModel : PageModel 18 | #pragma warning restore SA1649 // File name should match first type name 19 | { 20 | /// 21 | /// Gets or sets the request id. 22 | /// 23 | public string RequestId { get; set; } 24 | 25 | /// 26 | /// Gets a value indicating whether the request id is null or empty. 27 | /// 28 | public bool ShowRequestId => !string.IsNullOrEmpty(this.RequestId); 29 | 30 | /// 31 | /// Sets the request id. 32 | /// 33 | public void OnGet() 34 | { 35 | this.RequestId = Activity.Current?.Id ?? this.HttpContext.TraceIdentifier; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using CompanyCommunicator 2 | @namespace Microsoft.Teams.Apps.CompanyCommunicator.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /Source/CompanyCommunicator/Program.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator 7 | { 8 | using Microsoft.AspNetCore.Hosting; 9 | using Microsoft.Extensions.Hosting; 10 | 11 | /// 12 | /// Program class of the company communicator application. 13 | /// 14 | public class Program 15 | { 16 | /// 17 | /// Main function of the company communicator application. 18 | /// It builds a web host, then launches the company communicator into it. 19 | /// 20 | /// Arguments passed in to the function. 21 | public static void Main(string[] args) 22 | { 23 | CreateHostBuilder(args).Build().Run(); 24 | } 25 | 26 | /// 27 | /// Create the web host builder. 28 | /// 29 | /// Arguments passed into the main function. 30 | /// A web host builder instance. 31 | public static IHostBuilder CreateHostBuilder(string[] args) => 32 | Host.CreateDefaultBuilder(args) 33 | .ConfigureWebHostDefaults(webBuilder => 34 | { 35 | webBuilder.UseStartup(); 36 | }); 37 | } 38 | } -------------------------------------------------------------------------------- /Source/Test/CompanyCommunicator.Common.Test/Microsoft.Teams.App.CompanyCommunicator.Common.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | true 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | all 21 | runtime; build; native; contentfiles; analyzers; buildtransitive 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Source/Test/CompanyCommunicator.Common.Test/Services/Mock/MockAuthenticationHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.App.CompanyCommunicator.Common.Test.Services.Mock 7 | { 8 | using System.Net.Http; 9 | using System.Threading.Tasks; 10 | using Microsoft.Graph; 11 | 12 | /// 13 | /// Mocking Authentication Provider. 14 | /// 15 | public class MockAuthenticationHelper : IAuthenticationProvider 16 | { 17 | /// 18 | /// Mock authenticate request. 19 | /// 20 | /// Represents a HttpRequestMessage. 21 | /// asynchronous operation. 22 | public Task AuthenticateRequestAsync(HttpRequestMessage request) 23 | { 24 | return Task.CompletedTask; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Source/Test/CompanyCommunicator.Common.Test/stylecop.json: -------------------------------------------------------------------------------- 1 | { 2 | // ACTION REQUIRED: This file was automatically added to your project, but it 3 | // will not take effect until additional steps are taken to enable it. See the 4 | // following page for additional information: 5 | // 6 | // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/main/documentation/EnableConfiguration.md 7 | 8 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/main/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", 9 | "settings": { 10 | "documentationRules": { 11 | "companyName": "Microsoft", 12 | "copyrightText": "Copyright (c) {companyName} Corporation.\nLicensed under the MIT License." 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Source/Test/CompanyCommunicator.Prep.Func.Test/Microsoft.Teams.Apps.CompanyCommunicator.Prep.Func.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | true 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Source/Test/CompanyCommunicator.Send.Func.Test/Microsoft.Teams.Apps.CompanyCommunicator.Send.Func.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | true 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | all 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Source/Test/CompanyCommunicator.Test/Controllers/HealthControllerTest.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. 3 | // Licensed under the MIT License. 4 | // 5 | 6 | namespace Microsoft.Teams.Apps.CompanyCommunicator.Test.Controllers 7 | { 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Teams.Apps.CompanyCommunicator.Controllers; 10 | using Xunit; 11 | 12 | /// 13 | /// HealthController test class. 14 | /// 15 | public class HealthControllerTest 16 | { 17 | /// 18 | /// Test method to verify status code 200 for IndexAction. 19 | /// 20 | [Fact] 21 | public void Call_IndexAction_ReturnsStausCodeOk() 22 | { 23 | // Arrage 24 | var controller = this.GetHealthControllerInstance(); 25 | var statusCodeOk = 200; 26 | 27 | // Act 28 | var result = controller.Index(); 29 | var statusCode = ((StatusCodeResult)result).StatusCode; 30 | 31 | // Assert 32 | Assert.Equal(statusCode, statusCodeOk); 33 | } 34 | 35 | private HealthController GetHealthControllerInstance() 36 | { 37 | return new HealthController(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Source/Test/CompanyCommunicator.Test/Microsoft.Teams.Apps.CompanyCommunicator.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | true 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | all 22 | runtime; build; native; contentfiles; analyzers; buildtransitive 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Source/Test/CompanyCommunicator.Test/stylecop.json: -------------------------------------------------------------------------------- 1 | { 2 | // ACTION REQUIRED: This file was automatically added to your project, but it 3 | // will not take effect until additional steps are taken to enable it. See the 4 | // following page for additional information: 5 | // 6 | // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/main/documentation/EnableConfiguration.md 7 | 8 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/main/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", 9 | "settings": { 10 | "documentationRules": { 11 | "companyName": "Microsoft", 12 | "copyrightText": "Copyright (c) {companyName} Corporation.\nLicensed under the MIT License." 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Source/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Source/stylecop.json: -------------------------------------------------------------------------------- 1 | { 2 | // ACTION REQUIRED: This file was automatically added to your project, but it 3 | // will not take effect until additional steps are taken to enable it. See the 4 | // following page for additional information: 5 | // 6 | // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/main/documentation/EnableConfiguration.md 7 | 8 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/main/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", 9 | "settings": { 10 | "documentationRules": { 11 | "companyName": "Microsoft", 12 | "copyrightText": "Copyright (c) {companyName} Corporation.\nLicensed under the MIT License." 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Support/readme.md: -------------------------------------------------------------------------------- 1 | ## Why 2 | This folder is created to aid in the troubleshooting when deploying this application into your tenant/environment. 3 | 4 | # **Start-ChatWithUser.ps1** 5 | This script is designed for the purpose of testing the chat functionality of the bot within the Teams App. Some modifications are needed before you can start using this. In the "Variables need to be replaced to start using the script" section, there are a couple of variables you will need to replace: 6 | 7 | * $tenantId = "tenant.onmicrosoft.com" #or in GUID format "00000000-0000-0000-0000-000000000000" 8 | * $teamsAppId = "00000000-0000-0000-0000-000000000000" # AppId of the Teams App Manifest 9 | * $graphAppId = "00000000-0000-0000-0000-000000000000" 10 | * $userAppId = "00000000-0000-0000-0000-000000000000" 11 | 12 | For the secrets, I recommend to an extra secret per App which you can delete after using this script. This way, it won't interfere with the configuration of the application. And as an added bonus, it's more secure because the script will only run with the newly created secrets. 13 | 14 | # **Check-AppRegistrations.ps1** 15 | This script is meant to retrieve the provisioned App Registrations and the secrets which are stored in the KeyVault are working together correctly or not. If an access token is being returned, it means that the combinations of AppId + AppSecrets are working. 16 | 17 | # **Check-GraphApp.ps1** 18 | This a simplified version of the Check-AppRegistrations script. If you just want to see if the AppId + AppSecret is working correctly, please use this one. It is meant to use if the App registration of the Graph App (e.g. the main App) is working correctly (e.g. combination of AppId + AppSecret) and also if the API Permissions are set correct to retrieve Groups and Users -------------------------------------------------------------------------------- /Wiki/Home.md: -------------------------------------------------------------------------------- 1 | # Company Communicator 2 | 3 | Company Communicator is a custom Teams app that enables corporate teams to create and send messages intended for multiple teams or large number of employees over chat allowing organization to reach employees right where they collaborate. Utilize this template for multiple scenarios such as new initiative announcements, employee onboarding, modern learning and development or organization-wide broadcasts. 4 | 5 | The app provides an easy interface for designated users to create, preview, collaborate and send messages. 6 | 7 | It provides a foundation to build custom targeted communication capabilities such as custom telemetry on how many users acknowledged or interacted with a message. 8 | 9 | ![Company Communicator compose message screen](images/company-communicator-compose.png) 10 | 11 | * [Solution overview](Solution-overview) 12 | * [Data stores](Data-stores) 13 | * [Cost estimate](Cost-estimate) 14 | * [Known limitations](Known-limitations) 15 | * [Localization](Localization) 16 | * Deploying the app 17 | * [Deployment guide](Deployment-guide) 18 | * [Deployment guide certificate](Deployment-guide-certificate) 19 | * [Deployment guide powershell](Deployment-guide-powershell) 20 | * [Troubleshooting](Troubleshooting) 21 | * Migrating to newer version 22 | * [v5](v5-migration-guide) 23 | * [v4](v4-migration-guide) 24 | * [v3](v3-migration-guide) 25 | * [v2](v2-migration-guide) 26 | * [Scaling Company Communicator](Scale-app) 27 | * [Extending Company Communicator](Taking-it-further) 28 | * [Release Notes](Release-notes) -------------------------------------------------------------------------------- /Wiki/Known-limitations.md: -------------------------------------------------------------------------------- 1 | # Known Limitations 2 | ## 1. Author/publishing experience is not supported on Mobile 3 | 4 | The tab where authors/creators of messages create a message is currently not supported on mobile. The recommended approach is to create the messages on desktop only. 5 | 6 | ## 2. Adaptive card doesn't support RTL 7 | 8 | The app supports localization. Only the adaptive card currently doesn't support RTL. -------------------------------------------------------------------------------- /Wiki/Localization.md: -------------------------------------------------------------------------------- 1 | # Localization 2 | The App currently supports the below locales. 3 | 4 | 1. ar-SA 5 | 2. de-DE 6 | 3. en-US 7 | 4. es-ES 8 | 5. fr-FR 9 | 6. he-IL 10 | 7. ja-JP 11 | 8. ko-KR 12 | 9. pt-BR 13 | 10. ru-RU 14 | 11. zh-CN 15 | 12. zh-TW 16 | 17 | You can find the translations in `Source/CompanyCommunicator/ClientApp/public/locales` and 18 | the resource strings can be found in `Source/CompanyCommunicator.Common/Resources`. 19 | 20 | **NOTE:** You can add/update the resources for other locales and update the configuration. -------------------------------------------------------------------------------- /Wiki/Scale-app.md: -------------------------------------------------------------------------------- 1 | # Scale 2 | If you need to scale the app for large number of users(greater than 200K), please follow the below steps. 3 | 4 | ## 1. Create new Storage Account for Durable function. 5 | 6 | 1. Find and goto the resource group which is used for the Company Communicator app deployment. 7 | 1. Click on **+ Create**. 8 | 1. Then, search for **Storage Account** and click on **Create**. 9 | 1. Now, fill in the fields such as **Storage account name** and click on **Review + Create**. 10 | 1. Once the resource is created, then goto Storage Account. 11 | 1. Under **Security + networking**, click on access keys. 12 | 1. Then, click on **Show keys** and copy the key1 connection string. 13 | 1. Now, goto the Company Communicator prep function and click on **Configuration**. 14 | 1. Update the value of **Azure.WebJobsStorage** with the connection string from step 7. 15 | 1. Click on **Save** to commit changes. 16 | 17 | > Please make sure to keep the below value less than 50rps, as going over this rate can get the bot blocked. 18 | ``` 19 | "serviceBus": { 20 | "messageHandlerOptions": { 21 | "maxConcurrentCalls": 30 22 | } 23 | } 24 | ``` 25 | 26 | 27 | -------------------------------------------------------------------------------- /Wiki/Taking-it-further.md: -------------------------------------------------------------------------------- 1 | Want to take a stab at extending Company Communicator? Here are some ideas: 2 | 3 | ## Extend the compose experience 4 | * Allow file attachments in the message. The app currently provides basic rich formatting of message body. 5 | * Allow existing messages as templates for new message creation. 6 | 7 | ## Message metrics 8 | Export actionable data on message replies, acknowledgments, reactions in detail. 9 | 10 | ## New message types 11 | * **Surveys/polls:** Send surveys and polls for employees to gather NPS on new initiatives or gather quick feedback on organization activities. -------------------------------------------------------------------------------- /Wiki/Telemetry.md: -------------------------------------------------------------------------------- 1 | The Company Communicator app logs telemetry to [Azure Application Insights](https://azure.microsoft.com/en-us/services/monitor/). You can go to the Application Insights blade of the Azure App Service to view basic telemetry about your services, such as requests, failures, and dependency errors. 2 | 3 | The Teams Bot integrates with Application Insights to gather bot activity analytics, as described [here](https://blog.botframework.com/2019/03/21/bot-analytics-behind-the-scenes/). 4 | 5 | The app logs a few kinds of events: 6 | 7 | `Trace` logs keeps the track of application events. 8 | 9 | `Exceptions` logs keeps the records of exceptions tracked in the application. 10 | -------------------------------------------------------------------------------- /Wiki/images/ARM-Deployment-Timeout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/ARM-Deployment-Timeout.png -------------------------------------------------------------------------------- /Wiki/images/CompanyCommunicatorCompose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/CompanyCommunicatorCompose.png -------------------------------------------------------------------------------- /Wiki/images/admin_consent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/admin_consent.png -------------------------------------------------------------------------------- /Wiki/images/admin_consent_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/admin_consent_error.png -------------------------------------------------------------------------------- /Wiki/images/admin_consent_url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/admin_consent_url.png -------------------------------------------------------------------------------- /Wiki/images/appinsights-migration-execution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/appinsights-migration-execution.png -------------------------------------------------------------------------------- /Wiki/images/appservice-dotnet-version.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/appservice-dotnet-version.png -------------------------------------------------------------------------------- /Wiki/images/appservice_sync_deployment_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/appservice_sync_deployment_error.png -------------------------------------------------------------------------------- /Wiki/images/appservice_sync_error_fix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/appservice_sync_error_fix.png -------------------------------------------------------------------------------- /Wiki/images/architecture_overview_v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/architecture_overview_v1.png -------------------------------------------------------------------------------- /Wiki/images/architecture_overview_v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/architecture_overview_v2.png -------------------------------------------------------------------------------- /Wiki/images/architecture_overview_v4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/architecture_overview_v4.png -------------------------------------------------------------------------------- /Wiki/images/authorization_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/authorization_fail.png -------------------------------------------------------------------------------- /Wiki/images/azure-config-app-step3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/azure-config-app-step3.png -------------------------------------------------------------------------------- /Wiki/images/azure_cli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/azure_cli.png -------------------------------------------------------------------------------- /Wiki/images/azurefunctions_runtime_version.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/azurefunctions_runtime_version.png -------------------------------------------------------------------------------- /Wiki/images/botchanneldod_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/botchanneldod_1.png -------------------------------------------------------------------------------- /Wiki/images/botchannelgovernment_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/botchannelgovernment_1.png -------------------------------------------------------------------------------- /Wiki/images/botchannelgovernment_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/botchannelgovernment_2.png -------------------------------------------------------------------------------- /Wiki/images/botchannelgovernment_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/botchannelgovernment_3.png -------------------------------------------------------------------------------- /Wiki/images/check_modules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/check_modules.png -------------------------------------------------------------------------------- /Wiki/images/company-communicator-compose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/company-communicator-compose.png -------------------------------------------------------------------------------- /Wiki/images/create-certificate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/create-certificate.png -------------------------------------------------------------------------------- /Wiki/images/create-log-analytics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/create-log-analytics.png -------------------------------------------------------------------------------- /Wiki/images/delete_application_uri.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/delete_application_uri.png -------------------------------------------------------------------------------- /Wiki/images/deploybutton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/deploybutton.png -------------------------------------------------------------------------------- /Wiki/images/deployment_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/deployment_success.png -------------------------------------------------------------------------------- /Wiki/images/disable_routing_rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/disable_routing_rule.png -------------------------------------------------------------------------------- /Wiki/images/dotnet_upgrade_execution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/dotnet_upgrade_execution.png -------------------------------------------------------------------------------- /Wiki/images/draft-message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/draft-message.png -------------------------------------------------------------------------------- /Wiki/images/export-cert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/export-cert.png -------------------------------------------------------------------------------- /Wiki/images/file-explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/file-explorer.png -------------------------------------------------------------------------------- /Wiki/images/frontdoor_designer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/frontdoor_designer.png -------------------------------------------------------------------------------- /Wiki/images/go_back_main_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/go_back_main_window.png -------------------------------------------------------------------------------- /Wiki/images/graph_permissions_access.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/graph_permissions_access.png -------------------------------------------------------------------------------- /Wiki/images/import-app-service-cert-finished.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/import-app-service-cert-finished.png -------------------------------------------------------------------------------- /Wiki/images/import-key-vault-cert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/import-key-vault-cert.png -------------------------------------------------------------------------------- /Wiki/images/log-analytics-overview-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/log-analytics-overview-page.png -------------------------------------------------------------------------------- /Wiki/images/log_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/log_folder.png -------------------------------------------------------------------------------- /Wiki/images/login_screen_first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/login_screen_first.png -------------------------------------------------------------------------------- /Wiki/images/login_screen_second.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/login_screen_second.png -------------------------------------------------------------------------------- /Wiki/images/manifest_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/manifest_folder.png -------------------------------------------------------------------------------- /Wiki/images/migrate-appinsights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/migrate-appinsights.png -------------------------------------------------------------------------------- /Wiki/images/migrated-appinsights-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/migrated-appinsights-overview.png -------------------------------------------------------------------------------- /Wiki/images/multitenant_app_creation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/multitenant_app_creation.png -------------------------------------------------------------------------------- /Wiki/images/multitenant_app_overview_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/multitenant_app_overview_1.png -------------------------------------------------------------------------------- /Wiki/images/multitenant_app_overview_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/multitenant_app_overview_2.png -------------------------------------------------------------------------------- /Wiki/images/multitenant_app_permissions_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/multitenant_app_permissions_1.png -------------------------------------------------------------------------------- /Wiki/images/multitenant_app_permissions_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/multitenant_app_permissions_2.png -------------------------------------------------------------------------------- /Wiki/images/multitenant_app_secret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/multitenant_app_secret.png -------------------------------------------------------------------------------- /Wiki/images/param_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/param_file.png -------------------------------------------------------------------------------- /Wiki/images/postdeployment_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/postdeployment_output.png -------------------------------------------------------------------------------- /Wiki/images/powershell_deployment_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/powershell_deployment_error.png -------------------------------------------------------------------------------- /Wiki/images/remove_permission.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/remove_permission.png -------------------------------------------------------------------------------- /Wiki/images/resource_availability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/resource_availability.png -------------------------------------------------------------------------------- /Wiki/images/send-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/send-options.png -------------------------------------------------------------------------------- /Wiki/images/sent-messages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/sent-messages.png -------------------------------------------------------------------------------- /Wiki/images/set_application_uri.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/set_application_uri.png -------------------------------------------------------------------------------- /Wiki/images/single_tenant_app_creation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/single_tenant_app_creation.png -------------------------------------------------------------------------------- /Wiki/images/single_tenant_app_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/single_tenant_app_overview.png -------------------------------------------------------------------------------- /Wiki/images/single_tenant_app_secret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/single_tenant_app_secret.png -------------------------------------------------------------------------------- /Wiki/images/support-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/support-banner.png -------------------------------------------------------------------------------- /Wiki/images/sync_changes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/sync_changes.png -------------------------------------------------------------------------------- /Wiki/images/tab_name_change_cc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/tab_name_change_cc.png -------------------------------------------------------------------------------- /Wiki/images/troubleshooting_appservicesyncerror_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/troubleshooting_appservicesyncerror_1.png -------------------------------------------------------------------------------- /Wiki/images/troubleshooting_appservicesyncerror_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/troubleshooting_appservicesyncerror_2.png -------------------------------------------------------------------------------- /Wiki/images/troubleshooting_appservicesyncerror_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/troubleshooting_appservicesyncerror_3.png -------------------------------------------------------------------------------- /Wiki/images/troubleshooting_deltalinkerror.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/troubleshooting_deltalinkerror.png -------------------------------------------------------------------------------- /Wiki/images/troubleshooting_permissionerror.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/troubleshooting_permissionerror.png -------------------------------------------------------------------------------- /Wiki/images/troubleshooting_roleassignmenterror.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/troubleshooting_roleassignmenterror.png -------------------------------------------------------------------------------- /Wiki/images/troubleshooting_sourcecontrols.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/troubleshooting_sourcecontrols.png -------------------------------------------------------------------------------- /Wiki/images/troubleshooting_teamsnamesemptyerror.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/troubleshooting_teamsnamesemptyerror.png -------------------------------------------------------------------------------- /Wiki/images/update_ad_app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/update_ad_app.png -------------------------------------------------------------------------------- /Wiki/images/update_author_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/update_author_list.png -------------------------------------------------------------------------------- /Wiki/images/update_banner_title_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/update_banner_title_logo.png -------------------------------------------------------------------------------- /Wiki/images/upload_certificate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/upload_certificate.png -------------------------------------------------------------------------------- /Wiki/images/version_app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/version_app.png -------------------------------------------------------------------------------- /Wiki/images/warning_message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeDev/microsoft-teams-apps-company-communicator/dcf3b169084d3fff7c1e4c5b68718fb33c3391dd/Wiki/images/warning_message.png -------------------------------------------------------------------------------- /deploy.cmd: -------------------------------------------------------------------------------- 1 | :: Copyright (c) Microsoft Corporation. 2 | :: Licensed under the MIT License. 3 | 4 | @if "%SCM_TRACE_LEVEL%" NEQ "4" @echo off 5 | 6 | IF "%SITE_ROLE%" == "app" ( 7 | deploy.app.cmd 8 | ) ELSE ( 9 | IF "%SITE_ROLE%" == "function" ( 10 | deploy.function.cmd 11 | ) ELSE ( 12 | echo You have to set SITE_ROLE setting to either "app" or "function" 13 | exit /b 1 14 | ) 15 | ) -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "6.0.100", 4 | "rollForward": "latestFeature" 5 | } 6 | } --------------------------------------------------------------------------------