Blog Post

Modern Work App Consult Blog
22 MIN READ

Build your first Alexa skill with Alexa.NET and Azure Functions - The basics

Matteo Pagani's avatar
Matteo Pagani
Icon for Microsoft rankMicrosoft
Jan 15, 2019
First published on MSDN on Nov 02, 2018 Amazon has recently released the vocal assistant Alexa and its lineup of Echo devices also in Italy. I had the chance to play with some o...
Updated Nov 22, 2022
Version 3.0
"}},"componentScriptGroups({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/tags/TagView/TagViewChip\"]})":[{"__ref":"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeDescription\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/ThreadedReplyList\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505307000"}]},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Deleted","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"MMM dd yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":null,"possibleValues":["en-US","es-ES"]},"repliesSortOrder":{"__typename":"InheritableStringSettingWithPossibleValues","key":"config.user_replies_sort_order","value":"DEFAULT","localValue":"DEFAULT","possibleValues":["DEFAULT","LIKES","PUBLISH_TIME","REVERSE_PUBLISH_TIME"]}},"deleted":false},"CachedAsset:pages-1746564049054":{"__typename":"CachedAsset","id":"pages-1746564049054","value":[{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"UserBlogPermissions.Page","type":"COMMUNITY","urlPath":"/c/user-blog-permissions/page","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllEvents","type":"CUSTOM","urlPath":"/Events","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"CommunityHub.Page","type":"CUSTOM","urlPath":"/Directory","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllBlogs.Page","type":"CUSTOM","urlPath":"/blogs","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"HealthCheckPage","type":"COMMUNITY","urlPath":"/health","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564049054,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}","userBanned":"We're sorry, but you have been banned from using this site.","userBannedReason":"You have been banned for the following reason: {reason}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc","height":512,"width":512,"mimeType":"image/png"},"Rank:rank:4":{"__typename":"Rank","id":"rank:4","position":6,"name":"Microsoft","color":"333333","icon":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/cmstNC05WEo0blc\"}"},"rankStyle":"OUTLINE"},"User:user:44595":{"__typename":"User","id":"user:44595","uid":44595,"login":"Matteo Pagani","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS00NDU5NS02MzA4OGkwNTU0MkU2NzQwODM2NTE0"},"rank":{"__ref":"Rank:rank:4"},"email":"","messagesCount":117,"biography":null,"topicsCount":39,"kudosReceivedCount":132,"kudosGivenCount":1,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2017-03-19T04:38:14.936-07:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":1},"Category:category:microsoft365":{"__typename":"Category","id":"category:microsoft365","entityType":"CATEGORY","displayId":"microsoft365","nodeType":"category","depth":3,"title":"Microsoft 365","shortTitle":"Microsoft 365","parent":{"__ref":"Category:category:products-services"},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:top":{"__typename":"Category","id":"category:top","entityType":"CATEGORY","displayId":"top","nodeType":"category","depth":0,"title":"Top","shortTitle":"Top"},"Category:category:communities":{"__typename":"Category","id":"category:communities","entityType":"CATEGORY","displayId":"communities","nodeType":"category","depth":1,"parent":{"__ref":"Category:category:top"},"title":"Communities","shortTitle":"Communities"},"Category:category:products-services":{"__typename":"Category","id":"category:products-services","entityType":"CATEGORY","displayId":"products-services","nodeType":"category","depth":2,"parent":{"__ref":"Category:category:communities"},"title":"Products","shortTitle":"Products"},"Blog:board:ModernWorkAppConsult":{"__typename":"Blog","id":"board:ModernWorkAppConsult","entityType":"BLOG","displayId":"ModernWorkAppConsult","nodeType":"board","depth":4,"conversationStyle":"BLOG","repliesProperties":{"__typename":"RepliesProperties","sortOrder":"REVERSE_PUBLISH_TIME","repliesFormat":"threaded"},"tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":true,"tagType":"PRESET_ONLY","description":"","title":"Modern Work App Consult Blog","shortTitle":"Modern Work App Consult Blog","parent":{"__ref":"Category:category:microsoft365"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:gxcuf89792"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:communities"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:products-services"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:microsoft365"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"theme":{"__ref":"Theme:customTheme1"},"boardPolicies":{"__typename":"BoardPolicies","canViewSpamDashBoard":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.access_spam_quarantine.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.access_spam_quarantine.allowed.accessDenied","args":[]}},"canArchiveMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.content_archivals.enable_content_archival_settings.accessDenied","key":"error.lithium.policies.content_archivals.enable_content_archival_settings.accessDenied","args":[]}},"canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}}}},"BlogTopicMessage:message:317930":{"__typename":"BlogTopicMessage","uid":317930,"subject":"Build your first Alexa skill with Alexa.NET and Azure Functions - The basics","id":"message:317930","revisionNum":3,"repliesCount":1,"author":{"__ref":"User:user:44595"},"depth":0,"hasGivenKudo":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"conversation":{"__ref":"Conversation:conversation:317930"},"messagePolicies":{"__typename":"MessagePolicies","canPublishArticleOnEdit":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","args":[]}},"canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"contentWorkflow":{"__typename":"ContentWorkflow","state":"PUBLISH","scheduledPublishTime":null,"scheduledTimezone":null,"userContext":{"__typename":"MessageWorkflowContext","canSubmitForReview":null,"canEdit":false,"canRecall":null,"canSubmitForPublication":null,"canReturnToAuthor":null,"canPublish":null,"canReturnToReview":null,"canSchedule":false},"shortScheduledTimezone":null},"readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:317930"},"teaser@stripHtml({\"truncateLength\":200})":"First published on MSDN on Nov 02, 2018 Amazon has recently released the vocal assistant Alexa and its lineup of Echo devices also in Italy.","body@stripHtml({\"truncateLength\":200})":" \n \n \n First published on MSDN on Nov 02, 2018\n \n \n Amazon has recently released the vocal assistant Alexa and its lineup of Echo devices also in Italy. I had the chance to play with some o...","body@stringLength":"50360","rawBody":"\n \n \n First published on MSDN on Nov 02, 2018\n \n
\n Amazon has recently released the vocal assistant Alexa and its lineup of Echo devices also in Italy. I had the chance to play with some of them during my trips in the US and I was pleasantly surprised by the quality of the voice interaction. They also have a good integration with the Microsoft ecosystem. You can connect an Office 365 calendar so that Alexa can read your daily appointments or create a new one; we have recently released\n \n Cortana for Alexa\n \n , which allows to interact with Cortana directly from an Echo device;\n \n we have announced that Skype will be released for Echo devices\n \n as well.\n
\n As such, I took the chance of the Italian release to make my house \"smarter\" and I purchased an Echo Plus with some smart devices, like bulbs and power plugs.\n
\n
\n I've immediately been intrigued by the concept of \"skills\", which are basically applications for a vocal assistant. A skill allows to bring 3rd party services to Alexa and to extend the features it can provide. You can find on the market smart home skills, which allow Alexa to control a huge number of smart devices; you can find flash briefing skills, which can deliver you daily news from the most important news sources; you can find games, unit converters, and so on.\n
\n
\n I've decided to start exploring how to build skills for Alexa and, at the beginning, I found myself outside my comfort zone. From a technical point of view, skills are basically REST endpoints. When you invoke a skill, Alexa performs a HTTP POST connection against your endpoint which contains, as payload, a JSON with all the details about the request, like the recognized command. Nothing too complex. However, the part which scared me a bit was the technical implementation, since the\n \n Alexa Skills Kit\n \n is all around using Java or JavaScript as development languages and Amazon AWS as a cloud platform to host the skill. Not exactly the technologies I'm most familiar with 😃\n
\n
\n The good news is that Amazon doesn't impose any specific requirement regarding the platform or the technology behind a skill. The only requirement is about the communication: your endpoint must be able to understand the JSON sent by Alexa and to reply back with another JSON which Alexa can interpret. So, why not trying to build an Alexa Skill using a language (C#), an editor (Visual Studio) and a cloud platform (Azure) I know?\n
\n
\n This is exactly what we're going to do in this series of posts!\n
\n

\n Choosing the right Azure service\n

\n
\n The suggested path to deploy Alexa skills is AWS Lambda, which is the serverless platform provided by Amazon. As such, the choice of which Azure service to use for me was easy: Azure Function, which is the Microsoft approach to serverless computing.\n
\n
\n The best development choice for Azure Function is .NET Core, which support is now official since Azure Functions 2.0 has reached GA during Ignite. From a high level point of view, our Azure Function will receive the JSON request, parse it and prepare the appropriate JSON response. However, there's a library that can save you from all the pain in having to manually serialize and deserialize every JSON response. It's called\n \n Alexa.NET\n \n and it's an open source library from\n \n Tim Heuer\n \n . If you are familiar with Windows development the name should ring a bell since Tim, before joining the Cloud Developer Advocate team in Microsoft, was responsible of the XAML client developer platform and tools.\n
\n

\n Let's create our first skill\n

\n
\n Alexa supports multiple types of skills, each of them with a dedicated set of APIs. The type of skill you want to build is based on the kind of experience you want to offer. There are skills specific for Flash Briefings, for music, for handling lists, for smart home devices, etc.\n
\n
\n The most flexible approach is to build a\n \n Custom Skill\n \n , which gives you the APIs to build any kind of experience, which can even go beyond voice. Alexa, in fact, supports also visual content (for devices with a screen, like the Echo Show or the Echo Dot) and cards (which are displayed within the application).\n
\n
\n In this series of posts we're going to explore custom skills and we will start with a very basic skill. We will query the feed of this blog to get some information, like the title of the last article published or the list of articles which belong to a specificy category. We won't introduce advanced concepts for the moment, like delivering visual content, cards, supporting authentication, etc.\n
\n The goal of these posts, in fact, isn't to turn you into a guru of Alexa skills, but to understand how you can become a guru and, at the same time, keep using familiar tools and technologies. If you want to know everything around skills development, the right place is the\n \n Alexa Developer documentation\n \n , which covers all the scenarios supported by the platform.\n
\n
\n The starting point to create a skill isn't actually the code, but the Amazon's developers dashboard. A skill, in fact, is made by two components:\n
\n \n
\n Go to the\n \n Alexa Developer\n \n website and, if you don't have an account, create a new one. You'll have to link to an existing Amazon account. Then open the\n \n Skills\n \n dashboard and you will see a page like the following one:\n
\n
\n \n
\n
\n Here you will see a list of all the skills you have created / submitted and a button,\n \n Create Skill\n \n , to create a new one. Press it to start the process.\n
\n
\n \n
\n
\n Here you'll have to choose:\n
\n \n
\n In the next step you'll be able to choose between one of the existing template, which will give you a preset list of supported voice commands. In our case we want full control over the process, so choose\n \n Start from scratch\n \n .\n
\n
\n \n
\n
\n That's all. Now you'll have access to the\n \n Alexa Developer Console\n \n , which contains all the tools you need to build the interaction model, test and distribute your Alexa Skill.\n
\n In the\n \n Skill builder checklist\n \n you can see an overview of the steps to take, which we're going to follow:\n
\n
\n \n
\n

\n Setting the invocation name\n

\n
\n The invocation name is the one which triggers the skills. For example, if the skill is called\n \n AppConsult\n \n , it means it can be triggered by saying\n \n Open AppConsult\n \n or\n \n Ask AppConsult\n \n followed by one of the supported commands.\n
\n By default, this field is set with the name you've chosen for the skill when you have created it. However, you can change it by clicking on\n \n Invocation\n \n and setting the\n \n Skill Invocation Name\n \n field:\n
\n
\n \n
\n

\n Defining the intents\n

\n
\n An\n \n intent\n \n is a command that the user can tell to your skill to perform an action. Typically, each command is mapped with an intent. Since we're going to start with a simple skill, let's start by adding a command to tell to the user the title of the last article published on this blog. Create on the\n \n Add\n \n button near the\n \n Intents\n \n section of the\n \n Interaction Model\n \n sidebar and give it a name. This name doesn't affect the way the command will be recognized, but it's the identifier that your function will receive when it's invoked. In my case, I called it\n \n LastPosts\n \n .\n
\n
\n Once you have created the intent, you can specify one or more\n \n Sample Utterances\n \n , which are the sentences that can trigger this command. Here are, for example, the ones I've created for my intent:\n
\n
\n \n
\n
\n For the moment ignore the\n \n Intent Slots\n \n section. It can be used when you create an intent which accepts a parameter, like \"show me the weather in\n \n Milan\n \n \".\n \n Milan\n \n , in the intent definition, is a slot because the user can pronounce the name of any city and, of course, the Alexa Developer Console doesn't expect us to create a sample utterance for each place in the world. We'll see more details on how to use it in another post.\n
\n
\n Now press the\n \n Save Model\n \n button at the top to save it.\n
\n

\n Building the model\n

\n
\n Every time you change the interaction model, by setting for example a new invocation name or by adding / editing / deleting an intent, you need to rebuild it. Think of this process like rebuilding a Visual Studio project once you have changed something in the code. The process will be done in the background and the portal will show you a notification once the build has been completed succesfully.\n
\n
\n In order to do it press the\n \n Build Model\n \n button that you will find at the top of the editor.\n
\n
\n \n
\n
\n \n
\n
\n That's all for the Invocation Model. Now we can wire it to some code! There's still one step in the checklist, called\n \n Endpoints\n \n , but we're going to complete it later.\n
\n

\n Let's build our Azure Function\n

\n
\n An Azure Function (or, generally speaking, the serverless paradigm) takes the Platform-as-a-Service approach to the next level, since you don't have to care not only of maintaning the hardware platform or patching the operating system, but neither of managing the application's platform itself. A function is exactly what the name suggests: a single method that can be invoked by one or more triggers, which are different kind of events.\n
\n
\n An Azure Function can be developed with multiple programming languages (C#, Java, JavaScript, etc.) and you can even write the code directly from the Azure portal. However, in our scenario, we need a little bit more power, since we need to leverage the Alexa.NET library mentioned in the beginning. As such, we're going to create our function with an IDE, since it offers us more flexibility. You can either use Visual Studio or Visual Studio Code. I'm choosing the first one because it's the IDE I know best, but the development / deployment experience will be the same also with Visual Studio Code.\n
\n
\n Open Visual Studio 2017 and create a new project using the template under\n \n Cloud -> Azure Functions\n \n .\n
\n
\n \n
\n
\n Make sure to:\n
\n \n
\n Visual Studio will create a project with just one class, called\n \n Function1\n \n , which contains the following definition:\n
\n \n public static class Function1\n
\n {\n
\n [FunctionName(\"Function1\")]\n
\n public static async Task<IActionResult> Run(\n
\n [HttpTrigger(AuthorizationLevel.Anonymous, \"get\", \"post\", Route = null)] HttpRequest req,\n
\n ILogger log)\n
\n {\n
\n log.LogInformation(\"C# HTTP trigger function processed a request.\");\n
\n
\n string name = req.Query[\"name\"];\n
\n
\n string requestBody = await new StreamReader(req.Body).ReadToEndAsync();\n
\n dynamic data = JsonConvert.DeserializeObject(requestBody);\n
\n name = name ?? data?.name;\n
\n
\n return name != null\n
\n ? (ActionResult)new OkObjectResult($\"Hello, {name}\")\n
\n : new BadRequestObjectResult(\"Please pass a name on the query string or in the request body\");\n
\n }\n
\n }\n
\n
\n
\n As you can see, a function is nothing more than a method called\n \n Run()\n \n , which is invoked when the function is triggered.\n
\n Here is how we will change the default template for our purposes:\n
\n \n
\n The default template contains a simple method which parses a query string parameter called\n \n name\n \n from the URL and returns it back to the caller prefixed by the world\n \n Hello\n \n . Of course we can safely ignore it, because we're going to replace it with the real code to interact with Alexa.\n
\n
\n As first step, we need to install Alexa.NET. Right click on the project, choose\n \n Manage NuGet packages\n \n , search and install the\n \n Alexa.NET\n \n package. Since we're already using NuGet, make sure to install also the package called\n \n Microsoft.SyndicationFeed.ReaderWriter\n \n . It will make easier parsing the RSS feed of the blog. Make sure also that the NuGet package to support the Azure Functions infrastructure (called\n \n Microsoft.NET.Sdk.Functions\n \n ) is up to date to the latest version.\n
\n
\n Now we can start writing some code. Let's start by handling the launch request, which is the default one. It's invoked when the user says\n \n Open\n \n followed by the invocation name of the skill.\n
\n \n [FunctionName(\"Alexa\")]\n
\n public static async Task<IActionResult> Run(\n
\n [HttpTrigger(AuthorizationLevel.Function, \"post\", Route = null)] HttpRequest req,\n
\n ILogger log)\n
\n {\n
\n string json = await req.ReadAsStringAsync();\n
\n var skillRequest = JsonConvert.DeserializeObject<SkillRequest>(json);\n
\n
\n var requestType = skillRequest.GetRequestType();\n
\n
\n if (requestType == typeof(LaunchRequest))\n
\n {\n
\n //handle the request\n
\n }\n
\n
\n return new OkResult();\n
\n }\n
\n
\n
\n As already mentioned, Alexa will send us the command through a JSON payload included in the body of the request. As such, the first step is to read the content of the body using the\n \n ReadAsStringAsync()\n \n method and then to deserialize it using JSON.NET. Alexa.NET offers a class called\n \n SkillRequest\n \n to map the content of a request, so we can simply use the\n \n DeserializeObject()\n \n method instead of manually performing the deserialization.\n
\n
\n Once we have the request, we can manipulate it to get all the info we need. The most important one is the type of request, since Alexa supports multiple types. We can retrieve this information by calling the\n \n GetRequestType()\n \n method. In case of a launch request, the result will be the\n \n LaunchRequest\n \n type. If that's the case, we can handle it in the proper way.\n
\n
\n Here is a simple example on how you can handle the launch request:\n
\n \n [FunctionName(\"Alexa\")]\n
\n public static async Task<IActionResult> Run(\n
\n [HttpTrigger(AuthorizationLevel.Function, \"post\", Route = null)] HttpRequest req,\n
\n ILogger log)\n
\n {\n
\n string json = await req.ReadAsStringAsync();\n
\n var skillRequest = JsonConvert.DeserializeObject<SkillRequest>(json);\n
\n
\n var requestType = skillRequest.GetRequestType();\n
\n
\n SkillResponse response = null;\n
\n
\n if (requestType == typeof(LaunchRequest))\n
\n {\n
\n response = ResponseBuilder.Tell(\"Welcome to AppConsult!\");\n
\n response.Response.ShouldEndSession = false;\n
\n }\n
\n
\n return new OkObjectResult(response);\n
\n }\n
\n
\n
\n Alexa.net offers a class called\n \n ResponseBuilder\n \n , which you can use to build\n \n SkillResponse\n \n objects. This class maps the JSON that Alexa expects as output of a request to perform an action.\n
\n The\n \n ResponseBuilder\n \n class offer multiple methods to return different kind of responses, from the basic (like\n \n Tell()\n \n ) to the most advanced ones (like\n \n AskWithCard()\n \n ).\n
\n Since we're just exploring the basic concepts, for the moment we'll just use the\n \n Tell()\n \n method, which just returns a voice sentence which is then spoken by Alexa. The best practice, in the launch scenario, is also to set the\n \n ShouldEndSession\n \n property of the response to\n \n false\n \n . This means that Alexa won't close the session, but it will keep it open waiting for other commands to send to the same skill. This will allow our skill to support the following interaction model:\n
\n \n
\n This way Alexa knows that the last command (\n \n Tell me the last article\n \n ) must be passed again to our skill; it isn't a generic Alexa command.\n
\n

\n Testing our skill\n

\n
\n Before building more complex scenarios, it would be nice to test the current code to make sure everything is working as expected. Amazon offers us two ways to test our skill:\n
\n \n
\n However, before testing the skill, we need to return to the original skill checklist since we are missing one important setting: the endpoint. So far, in fact, the code of our skill lives only on our computer but, in order to work properly, we need to expose it on a web server, so that the Amazon servers can access to it.\n
\n Since we're leveraging an Azure Function, the standard approach would be to publish our function on Azure. This way it will be assigned an URL, which we can set as endpoint on the Amazon portal.\n
\n
\n However, when we are in the testing phase, this approach has some drawbacks. Every time we make some changes to the code, we need in fact to publish a new version of the function to Azure. Additionally, Azure supports remote debugging, but it isn't as fast and reliable as local debugging\n
\n
\n It would be great to test the skill locally using Visual Studio, but we would need the Alexa engine to run on our machine, which isn't clearly feasible. Is there an easy way to achieve the best of both worlds? Yes, thanks to\n \n ngrok\n \n !\n
\n
\n \n Ngrok\n \n is an open source tool which helps developers during the testing phase of REST APIs, web hooks and, generally speaking, everything that needs to be hosted on a web server to work. Ngrok takes care of exposing your local server to Internet through a public URL with SSL support. This means that we can launch our Azure Function on our local machine and set, in the Alexa Developer Portal, the URL provided by ngrok as endpoint. This way Amazon will invoke the API like if it's running on the cloud but, in reality, all the requests will arrive on your local machine, allowing you to see detailed logs, to set breakpoints in Visual Studio, etc.\n
\n
\n As first step, register an account\n \n on the official website\n \n and then download the tool. It's a command line tool, so unzip the file wherever you prefer. Ideally, you should add the folder as a path in Windows, so that you can invoke ngrok from any location.\n
\n Now open Visual Studio and start the debugging on the Azure Function by pressing F5. You will see a command prompt popping out: it's the Azure Function Core Tool, which allows you to run an Azure Function locally. The command prompt will act also as a logging window. Every time the Azure Function will be triggered, we will see the details of the request and the response in the prompt.\n
\n Moreover, do you remember the\n \n ILogger\n \n object included in the signature of the\n \n Run()\n \n method of the function? Whenever you're going to log a message using this object, it will be displayed in this console.\n
\n
\n Once the function is started, you will see in the prompt a message like the following one:\n
\n
\n \n
\n
\n Take note of the port used to expose the function, which should be 7071. Now open a command prompt on the folder where you have uncompressed ngrok and launch the following command:\n
\n \n ngrok http 7071\n
\n
\n
\n Ngrok will start and it will expose the HTTP protocol through the 7071 port. In case Visual Studio has assigned to your web server a different port, replace 7071 with the right value.\n
\n While ngrok is up and running, you will see the following screen in the command prompt:\n
\n
\n \n
\n
\n As you can see from the forwarding section, ngrok is exposing your local webserver through HTTP and HTTPS. Since we're using the free plan, we will be assigned a random subdomain of the ngrok.io domain (like xyz.ngrok.io).\n
\n Now, from the outside, any service can reach the Azure Function exposed by our local web server on the 7071 port using this address.\n
\n
\n Now we're ready to configure our Alexa skill to use this interface. Return back to the Alexa Developer Console and, in the\n \n Build\n \n section, choose\n \n Endpoint\n \n :\n
\n
\n \n
\n
\n By default, the skill will be set to use the AWS Lambda service provided by Amazon. However, since in our case we're going to use Azure, choose\n \n HTTPS\n \n and then set the\n \n Default region\n \n section with the following values:\n
\n \n
\n As you can see, if you want to load balance your skill, you can provide different endpoints for different regions of the world. Otherwise, all the requests will be sent to the default endpoint, no matter where they're coming from.\n
\n
\n Now press\n \n Save endpoints\n \n at the top, then click on\n \n Test\n \n in the tab menu. You will access to the Alexa Simulator. As first step, you have to turn on testing support using the following switch:\n
\n
\n \n
\n
\n Now you have access to the simulator. On the left you have the chat window, where you can type the command you want to send to the skill. On the right, instead, you will see the last response from Alexa, followed by the JSON inputs and outputs.\n
\n Go on and type, in the chat window, the following command:\n
\n \n open AppConsult\n
\n
\n
\n If you have done everything correctly, you should see the request coming in the Azure Function console:\n
\n
\n \n
\n
\n The Alexa Simulator, instead, should reply with the welcome message we have included in the code and, on the right, you can see the JSON request which was submitted and the JSON response which was returned by our function:\n
\n
\n \n
\n
\n Our first Alexa skill is working! Great job!\n
\n
\n Take a look at the JSON. The input is the JSON representation of the\n \n SkillRequest\n \n class, while the output is representation of the\n \n SkillResponse\n \n class. To prove that we're actually testing using our local Azure Function, simply put a breakpoint in the first line of the function, than type again the\n \n open AppConsult\n \n command in the Alexa Simulator. You will see the breakpoint being hit and you will have the chance to perform step by step debugging, add watches, etc. This opportunity will be extremely useful when you're going to implement more complex scenarios. However, remember to act fast during the debugging. Alexa, in fact, will drop the session if the skill doesn't return any response in a timely fashion.\n
\n
\n From a skill point of view, we aren't doing anything special for the moment. Let's move on and handle our first intent.\n
\n

\n Handling an intent\n

\n
\n When we have created the invocation model, we have defined an intent call\n \n LastPosts\n \n . Let's see the code we need to add to our Azure Function to handle it:\n
\n \n [FunctionName(\"Alexa\")]\n
\n public static async Task<IActionResult> Run(\n
\n [HttpTrigger(AuthorizationLevel.Function, \"post\", Route = null)] HttpRequest req,\n
\n ILogger log)\n
\n {\n
\n string json = await req.ReadAsStringAsync();\n
\n var skillRequest = JsonConvert.DeserializeObject<SkillRequest>(json);\n
\n
\n var requestType = skillRequest.GetRequestType();\n
\n
\n SkillResponse response = null;\n
\n
\n if (requestType == typeof(LaunchRequest))\n
\n {\n
\n response = ResponseBuilder.Tell(\"Welcome to AppConsult!\");\n
\n response.Response.ShouldEndSession = false;\n
\n }\n
\n
\n else if (requestType == typeof(IntentRequest))\n
\n {\n
\n var intentRequest = skillRequest.Request as IntentRequest;\n
\n
\n if (intentRequest.Intent.Name == \"LastPosts\")\n
\n {\n
\n //handle the intent\n
\n }\n
\n }\n
\n
\n return new OkObjectResult(response);\n
\n }\n
\n
\n
\n We have added a new condition to the function: this time, we check if the request's type is\n \n IntentRequest\n \n . If that's the case, we can cast the request (stored inside the\n \n Request\n \n property of the\n \n SkillRequest\n \n class) to get all the information we need.\n
\n The most important one can be found in the\n \n Name\n \n property of the\n \n Intent\n \n class: it's the unique identifier of the intent that we have configured in the invocation model. This means that, whenever Alexa will understand one of the sample utterances linked to the intent (like\n \n tell me the last post\n \n ), it will invoke the function passing\n \n LastPosts\n \n as name.\n
\n If that's the case, we can handle the command in order to return to the user the expcted result. In our case, we're going to use the\n \n Microsoft.SyndicationFeed.ReaderWriter\n \n package we have previously installed to download the RSS feed of this blog, parse it and extract the most recent news. First let's define a helper method called\n \n ParseFeed()\n \n , which accepts as input the URL of a RSS feed:\n
\n \n private static async Task<List<string>> ParseFeed(string url)\n
\n {\n
\n List<string> news = new List<string>();\n
\n using (var xmlReader = XmlReader.Create(url, new XmlReaderSettings { Async = true }))\n
\n {\n
\n RssFeedReader feedReader = new RssFeedReader(xmlReader);\n
\n while (await feedReader.Read())\n
\n {\n
\n if (feedReader.ElementType == Microsoft.SyndicationFeed.SyndicationElementType.Item)\n
\n {\n
\n var item = await feedReader.ReadItem();\n
\n news.Add(item.Title);\n
\n }\n
\n }\n
\n }\n
\n
\n return news;\n
\n }\n
\n
\n
\n We create a new\n \n XmlReader\n \n object, which is incapsulated inside the\n \n RssFeedReader\n \n class, which makes simpler navigating through the XML tree of the feed. By using a\n \n while\n \n loop, we read each item of the feed using the\n \n Read()\n \n method. If the node we're reading is, indeed, a feed item, we read its content using the\n \n ReadItem()\n \n method and we extract the\n \n Title\n \n property.\n
\n
\n Now we can use this method to return to the\n \n Run()\n \n method of the function the full list of articles published on this blog:\n
\n \n [FunctionName(\"Alexa\")]\n
\n public static async Task<IActionResult> Run(\n
\n [HttpTrigger(AuthorizationLevel.Function, \"post\", Route = null)] HttpRequest req,\n
\n ILogger log)\n
\n {\n
\n string json = await req.ReadAsStringAsync();\n
\n var skillRequest = JsonConvert.DeserializeObject<SkillRequest>(json);\n
\n
\n var requestType = skillRequest.GetRequestType();\n
\n
\n SkillResponse response = null;\n
\n
\n if (requestType == typeof(LaunchRequest))\n
\n {\n
\n response = ResponseBuilder.Tell(\"Welcome to AppConsult!\");\n
\n response.Response.ShouldEndSession = false;\n
\n }\n
\n
\n else if (requestType == typeof(IntentRequest))\n
\n {\n
\n var intentRequest = skillRequest.Request as IntentRequest;\n
\n
\n if (intentRequest.Intent.Name == \"LastPosts\")\n
\n {\n
\n string rss = \"https://blogs.msdn.microsoft.com/appconsult/feed/\";\n
\n List<string> news = await ParseFeed(rss);\n
\n
\n string output = $\"The title of the last article is {news.FirstOrDefault()}\";\n
\n
\n response = ResponseBuilder.Tell(output);\n
\n }\n
\n }\n
\n
\n return new OkObjectResult(response);\n
\n }\n
\n
\n
\n The code is very similar to the one we have used to handle the launch request. We compose a message and we add the title of the first news retrieved from the RSS feed (which is the last published, from a chronological point of view). We create a\n \n SpeakResponse\n \n by calling the\n \n Tell()\n \n method of the\n \n ResponseBuilder\n \n class and, in the end, we encapsulate it inside a\n \n OkObjectResult\n \n object, which we return to Alexa.\n
\n
\n In order to try this new feature run again the Azure Function on your local machine. If you haven't terminated ngrok, it should be still up & running, ready to forward every request coming to your assigned URL to your local web server. As such, just open again the Alexa Simulator and, this time, type the following command:\n
\n \n open appconsult and tell me the latest article\n
\n
\n
\n If you have done everything correctly, Alexa should prompt you with the title of the last published article:\n
\n
\n \n
\n

\n Deploy the function on Azure\n

\n
\n Now that we have verified that our function is working as expected, we are ready to deploy it on Azure. This way, we can continue the testing without having to keep our Azure Function simulator up & running on our local machine.\n
\n The easiest way to publish our Azure Function is through Visual Studio. Right click on your project and choose\n \n Publish\n \n . You'll have the chance to publish it using an existing Azure App Service plan or to create a new one. In my case, I have chosen to create a new one. Regardless of your choice, make sure to enable the\n \n Run from ZIP (recommended)\n \n option. The Web Deploy approach, in fact, doesn't work very well with Azure Functions, since most of the times it will require you to go to the Azure portal and stop the function before being able to perform a new deploy.\n
\n
\n In the next step you'll be able to configure your Azure Function directly from Visual Studio:\n
\n
\n \n
\n
\n \n App name\n \n is the most important parameter, since it will determine the default URL assigned to it, which will be\n \n https://.azurewebsites.net\n \n .\n
\n The other dropdowns will allow you to choose which Azure subscription (in case you have multiple ones connected to the same account), Resource Group, Hosting Plan and Storage Account you want to use.\n
\n
\n Once you have finished press\n \n Create\n \n . The process will take a while because, other than deploying the files which compose your function, Visual Studio will also take care of creating all the required infrastructure on Azure to host it.\n
\n The next times, instead, the process will be much faster, since Visual Studio will just copy the updated files to the remote location.\n
\n
\n The last step is to go back to the Alexa Developer Console and change the endpoint. It shouldn't be anymore the URL assigned by ngrok, but we need to replace it with the one assigned by Azure. You can copy it directly from the Publish window:\n
\n
\n \n
\n
\n Just remember to add the API endpoint to the URL. In my case, since the URL of my Azure App Service is\n \n \n https://appconsultskill.azurewebsites.net\n \n \n , I had to specify as endpoint\n \n \n https://appconsultskill.azurewebsites.net/api/alexa\n \n \n .\n
\n
\n \n
\n
\n If you're planning to keep using the free Azure domain instead of your custom one, you can keep the option\n \n My development endpoint is a sub-domain of a domain that has a wildcart certificate from a certificate authority\n \n selected.\n
\n If you want to test that your function is still working also after the deployment, just go back to the Alexa Simulator. You should be able to repeat the same tests we've done before with success.\n
\n

\n Wrapping up\n

\n
\n In this (long) post we have seen how to build our first Alexa skill by reusing technologies and platforms we are familiar with: C#, Visual Studio and Azure. Despite being very simple, it's fully functional. However, we aren't quite ready to submit it to certification. In order to make it available to every user who owns an Echo device, in fact, we need to pass a technical validation and a manual certification. If we go to the Amazon Developer Console we will see a section called\n \n Certification\n \n , with a step called\n \n Functional test\n \n . This tool will run a series of technical tests on your skill, which are required to pass before being able to submit it for the manual certification.\n
\n
\n If you run the validation tool now you will see that, despite our skill is working fine in the simulator, it will fail multiple checks. The reason is that, in order to be submitted, a skill must:\n
\n
    \n
    \n
  1. \n Make sure the request is indeed coming from a trusted Amazon service. Since we're hosting the skill on a platform different than AWS Lambda, we need to manually take care of this validation.\n
  2. \n
    \n
  3. \n Handle properly not just the custom intents, but also the default ones provided by Alexa, like stop, cancel, etc.\n
  4. \n
    \n
\n
\n In the next post we'll see the steps to do. In the meantime, you can play with the sample source\n \n hosted on GitHub\n \n .\n
\n
\n Happy coding!\n \n","kudosSumWeight":0,"postTime":"2019-01-15T15:23:29.487-08:00","images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzRpMUYzMkQ4MjdDMjEzMjg2NA?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzZpMTJDNjcyMkMxMUNFN0QzOA?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzdpMkQzQjdDRTZFN0NEOTJFOA?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzhpODA0OUQ2QzJDNDk2RkI3Ng?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDU","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzlpRDA1OTcwODE1RjE4RDhBOQ?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDY","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODBpNzI4RTU5MENGNEUyRjIxNQ?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDc","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODFpRDhEMDNDRENFMDA5RjZBRg?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDg","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODJpODVGRkMyNUMyQjhDMDEzRg?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDk","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODRpMzE4RjFEOTA2RDdBRDE4OA?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDEw","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODVpOEVBQTgyNTUzOTA3MjU2MQ?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDEx","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODZpRjUwQTJGMTRBNjA4QTY1Ng?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDEy","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODdpMkU5QTZCNzMxODc0NjcyMw?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDEz","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODhpNjlENzkxQ0EzQkM1NUEyOA?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE0","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODlpQjQ2OTI0NkVGOEM5Njc1Mw?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE1","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTBpMTdENTVCRDhDREI2M0JERg?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE2","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTJpQzhDRjhCNEIzQzUzNTQwOQ?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE3","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTRpNkMxOTEzMTUzNEU2QkE2NA?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE4","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTZpMTFGMTEyNkE0Qzc4NzU1NA?revision=3\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE5","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTdpQTE1NEEyNUJCMzZFNUZGMQ?revision=3\"}"}}],"totalCount":19,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"attachments":{"__typename":"AttachmentConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"tags":{"__typename":"TagConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDE","node":{"__typename":"Tag","id":"tag:azure","text":"azure","time":"2016-09-06T09:34:09.130-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDI","node":{"__typename":"Tag","id":"tag:azure functions","text":"azure functions","time":"2017-12-08T04:35:32.257-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}}]},"timeToRead":22,"rawTeaser":"First published on MSDN on Nov 02, 2018 Amazon has recently released the vocal assistant Alexa and its lineup of Echo devices also in Italy.","introduction":"","coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""},"currentRevision":{"__ref":"Revision:revision:317930_3"},"latestVersion":{"__typename":"FriendlyVersion","major":"3","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":12095},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":null,"seoDescription":null,"placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[]},"blogMessagePolicies":{"__typename":"BlogMessagePolicies","canDoAuthoringActionsOnBlog":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","key":"error.lithium.policies.blog.action_can_do_authoring_action.accessDenied","args":[]}}},"archivalData":null,"customFields":[],"revisions({\"constraints\":{\"isPublished\":{\"eq\":true}},\"first\":1})":{"__typename":"RevisionConnection","totalCount":3},"body":"\n \n \n First published on MSDN on Nov 02, 2018\n \n
\n Amazon has recently released the vocal assistant Alexa and its lineup of Echo devices also in Italy. I had the chance to play with some of them during my trips in the US and I was pleasantly surprised by the quality of the voice interaction. They also have a good integration with the Microsoft ecosystem. You can connect an Office 365 calendar so that Alexa can read your daily appointments or create a new one; we have recently released\n \n Cortana for Alexa\n \n , which allows to interact with Cortana directly from an Echo device;\n \n we have announced that Skype will be released for Echo devices\n \n as well.\n
\n As such, I took the chance of the Italian release to make my house \"smarter\" and I purchased an Echo Plus with some smart devices, like bulbs and power plugs.\n
\n
\n I've immediately been intrigued by the concept of \"skills\", which are basically applications for a vocal assistant. A skill allows to bring 3rd party services to Alexa and to extend the features it can provide. You can find on the market smart home skills, which allow Alexa to control a huge number of smart devices; you can find flash briefing skills, which can deliver you daily news from the most important news sources; you can find games, unit converters, and so on.\n
\n
\n I've decided to start exploring how to build skills for Alexa and, at the beginning, I found myself outside my comfort zone. From a technical point of view, skills are basically REST endpoints. When you invoke a skill, Alexa performs a HTTP POST connection against your endpoint which contains, as payload, a JSON with all the details about the request, like the recognized command. Nothing too complex. However, the part which scared me a bit was the technical implementation, since the\n \n Alexa Skills Kit\n \n is all around using Java or JavaScript as development languages and Amazon AWS as a cloud platform to host the skill. Not exactly the technologies I'm most familiar with 😃\n
\n
\n The good news is that Amazon doesn't impose any specific requirement regarding the platform or the technology behind a skill. The only requirement is about the communication: your endpoint must be able to understand the JSON sent by Alexa and to reply back with another JSON which Alexa can interpret. So, why not trying to build an Alexa Skill using a language (C#), an editor (Visual Studio) and a cloud platform (Azure) I know?\n
\n
\n This is exactly what we're going to do in this series of posts!\n
\n

\n Choosing the right Azure service\n

\n
\n The suggested path to deploy Alexa skills is AWS Lambda, which is the serverless platform provided by Amazon. As such, the choice of which Azure service to use for me was easy: Azure Function, which is the Microsoft approach to serverless computing.\n
\n
\n The best development choice for Azure Function is .NET Core, which support is now official since Azure Functions 2.0 has reached GA during Ignite. From a high level point of view, our Azure Function will receive the JSON request, parse it and prepare the appropriate JSON response. However, there's a library that can save you from all the pain in having to manually serialize and deserialize every JSON response. It's called\n \n Alexa.NET\n \n and it's an open source library from\n \n Tim Heuer\n \n . If you are familiar with Windows development the name should ring a bell since Tim, before joining the Cloud Developer Advocate team in Microsoft, was responsible of the XAML client developer platform and tools.\n
\n

\n Let's create our first skill\n

\n
\n Alexa supports multiple types of skills, each of them with a dedicated set of APIs. The type of skill you want to build is based on the kind of experience you want to offer. There are skills specific for Flash Briefings, for music, for handling lists, for smart home devices, etc.\n
\n
\n The most flexible approach is to build a\n \n Custom Skill\n \n , which gives you the APIs to build any kind of experience, which can even go beyond voice. Alexa, in fact, supports also visual content (for devices with a screen, like the Echo Show or the Echo Dot) and cards (which are displayed within the application).\n
\n
\n In this series of posts we're going to explore custom skills and we will start with a very basic skill. We will query the feed of this blog to get some information, like the title of the last article published or the list of articles which belong to a specificy category. We won't introduce advanced concepts for the moment, like delivering visual content, cards, supporting authentication, etc.\n
\n The goal of these posts, in fact, isn't to turn you into a guru of Alexa skills, but to understand how you can become a guru and, at the same time, keep using familiar tools and technologies. If you want to know everything around skills development, the right place is the\n \n Alexa Developer documentation\n \n , which covers all the scenarios supported by the platform.\n
\n
\n The starting point to create a skill isn't actually the code, but the Amazon's developers dashboard. A skill, in fact, is made by two components:\n
\n \n
\n Go to the\n \n Alexa Developer\n \n website and, if you don't have an account, create a new one. You'll have to link to an existing Amazon account. Then open the\n \n Skills\n \n dashboard and you will see a page like the following one:\n
\n
\n \n
\n
\n Here you will see a list of all the skills you have created / submitted and a button,\n \n Create Skill\n \n , to create a new one. Press it to start the process.\n
\n
\n \n
\n
\n Here you'll have to choose:\n
\n \n
\n In the next step you'll be able to choose between one of the existing template, which will give you a preset list of supported voice commands. In our case we want full control over the process, so choose\n \n Start from scratch\n \n .\n
\n
\n \n
\n
\n That's all. Now you'll have access to the\n \n Alexa Developer Console\n \n , which contains all the tools you need to build the interaction model, test and distribute your Alexa Skill.\n
\n In the\n \n Skill builder checklist\n \n you can see an overview of the steps to take, which we're going to follow:\n
\n
\n \n
\n

\n Setting the invocation name\n

\n
\n The invocation name is the one which triggers the skills. For example, if the skill is called\n \n AppConsult\n \n , it means it can be triggered by saying\n \n Open AppConsult\n \n or\n \n Ask AppConsult\n \n followed by one of the supported commands.\n
\n By default, this field is set with the name you've chosen for the skill when you have created it. However, you can change it by clicking on\n \n Invocation\n \n and setting the\n \n Skill Invocation Name\n \n field:\n
\n
\n \n
\n

\n Defining the intents\n

\n
\n An\n \n intent\n \n is a command that the user can tell to your skill to perform an action. Typically, each command is mapped with an intent. Since we're going to start with a simple skill, let's start by adding a command to tell to the user the title of the last article published on this blog. Create on the\n \n Add\n \n button near the\n \n Intents\n \n section of the\n \n Interaction Model\n \n sidebar and give it a name. This name doesn't affect the way the command will be recognized, but it's the identifier that your function will receive when it's invoked. In my case, I called it\n \n LastPosts\n \n .\n
\n
\n Once you have created the intent, you can specify one or more\n \n Sample Utterances\n \n , which are the sentences that can trigger this command. Here are, for example, the ones I've created for my intent:\n
\n
\n \n
\n
\n For the moment ignore the\n \n Intent Slots\n \n section. It can be used when you create an intent which accepts a parameter, like \"show me the weather in\n \n Milan\n \n \".\n \n Milan\n \n , in the intent definition, is a slot because the user can pronounce the name of any city and, of course, the Alexa Developer Console doesn't expect us to create a sample utterance for each place in the world. We'll see more details on how to use it in another post.\n
\n
\n Now press the\n \n Save Model\n \n button at the top to save it.\n
\n

\n Building the model\n

\n
\n Every time you change the interaction model, by setting for example a new invocation name or by adding / editing / deleting an intent, you need to rebuild it. Think of this process like rebuilding a Visual Studio project once you have changed something in the code. The process will be done in the background and the portal will show you a notification once the build has been completed succesfully.\n
\n
\n In order to do it press the\n \n Build Model\n \n button that you will find at the top of the editor.\n
\n
\n \n
\n
\n \n
\n
\n That's all for the Invocation Model. Now we can wire it to some code! There's still one step in the checklist, called\n \n Endpoints\n \n , but we're going to complete it later.\n
\n

\n Let's build our Azure Function\n

\n
\n An Azure Function (or, generally speaking, the serverless paradigm) takes the Platform-as-a-Service approach to the next level, since you don't have to care not only of maintaning the hardware platform or patching the operating system, but neither of managing the application's platform itself. A function is exactly what the name suggests: a single method that can be invoked by one or more triggers, which are different kind of events.\n
\n
\n An Azure Function can be developed with multiple programming languages (C#, Java, JavaScript, etc.) and you can even write the code directly from the Azure portal. However, in our scenario, we need a little bit more power, since we need to leverage the Alexa.NET library mentioned in the beginning. As such, we're going to create our function with an IDE, since it offers us more flexibility. You can either use Visual Studio or Visual Studio Code. I'm choosing the first one because it's the IDE I know best, but the development / deployment experience will be the same also with Visual Studio Code.\n
\n
\n Open Visual Studio 2017 and create a new project using the template under\n \n Cloud -> Azure Functions\n \n .\n
\n
\n \n
\n
\n Make sure to:\n
\n \n
\n Visual Studio will create a project with just one class, called\n \n Function1\n \n , which contains the following definition:\n
\n \n public static class Function1\n
\n {\n
\n [FunctionName(\"Function1\")]\n
\n public static async Task<IActionResult> Run(\n
\n [HttpTrigger(AuthorizationLevel.Anonymous, \"get\", \"post\", Route = null)] HttpRequest req,\n
\n ILogger log)\n
\n {\n
\n log.LogInformation(\"C# HTTP trigger function processed a request.\");\n
\n
\n string name = req.Query[\"name\"];\n
\n
\n string requestBody = await new StreamReader(req.Body).ReadToEndAsync();\n
\n dynamic data = JsonConvert.DeserializeObject(requestBody);\n
\n name = name ?? data?.name;\n
\n
\n return name != null\n
\n ? (ActionResult)new OkObjectResult($\"Hello, {name}\")\n
\n : new BadRequestObjectResult(\"Please pass a name on the query string or in the request body\");\n
\n }\n
\n }\n
\n
\n
\n As you can see, a function is nothing more than a method called\n \n Run()\n \n , which is invoked when the function is triggered.\n
\n Here is how we will change the default template for our purposes:\n
\n \n
\n The default template contains a simple method which parses a query string parameter called\n \n name\n \n from the URL and returns it back to the caller prefixed by the world\n \n Hello\n \n . Of course we can safely ignore it, because we're going to replace it with the real code to interact with Alexa.\n
\n
\n As first step, we need to install Alexa.NET. Right click on the project, choose\n \n Manage NuGet packages\n \n , search and install the\n \n Alexa.NET\n \n package. Since we're already using NuGet, make sure to install also the package called\n \n Microsoft.SyndicationFeed.ReaderWriter\n \n . It will make easier parsing the RSS feed of the blog. Make sure also that the NuGet package to support the Azure Functions infrastructure (called\n \n Microsoft.NET.Sdk.Functions\n \n ) is up to date to the latest version.\n
\n
\n Now we can start writing some code. Let's start by handling the launch request, which is the default one. It's invoked when the user says\n \n Open\n \n followed by the invocation name of the skill.\n
\n \n [FunctionName(\"Alexa\")]\n
\n public static async Task<IActionResult> Run(\n
\n [HttpTrigger(AuthorizationLevel.Function, \"post\", Route = null)] HttpRequest req,\n
\n ILogger log)\n
\n {\n
\n string json = await req.ReadAsStringAsync();\n
\n var skillRequest = JsonConvert.DeserializeObject<SkillRequest>(json);\n
\n
\n var requestType = skillRequest.GetRequestType();\n
\n
\n if (requestType == typeof(LaunchRequest))\n
\n {\n
\n //handle the request\n
\n }\n
\n
\n return new OkResult();\n
\n }\n
\n
\n
\n As already mentioned, Alexa will send us the command through a JSON payload included in the body of the request. As such, the first step is to read the content of the body using the\n \n ReadAsStringAsync()\n \n method and then to deserialize it using JSON.NET. Alexa.NET offers a class called\n \n SkillRequest\n \n to map the content of a request, so we can simply use the\n \n DeserializeObject()\n \n method instead of manually performing the deserialization.\n
\n
\n Once we have the request, we can manipulate it to get all the info we need. The most important one is the type of request, since Alexa supports multiple types. We can retrieve this information by calling the\n \n GetRequestType()\n \n method. In case of a launch request, the result will be the\n \n LaunchRequest\n \n type. If that's the case, we can handle it in the proper way.\n
\n
\n Here is a simple example on how you can handle the launch request:\n
\n \n [FunctionName(\"Alexa\")]\n
\n public static async Task<IActionResult> Run(\n
\n [HttpTrigger(AuthorizationLevel.Function, \"post\", Route = null)] HttpRequest req,\n
\n ILogger log)\n
\n {\n
\n string json = await req.ReadAsStringAsync();\n
\n var skillRequest = JsonConvert.DeserializeObject<SkillRequest>(json);\n
\n
\n var requestType = skillRequest.GetRequestType();\n
\n
\n SkillResponse response = null;\n
\n
\n if (requestType == typeof(LaunchRequest))\n
\n {\n
\n response = ResponseBuilder.Tell(\"Welcome to AppConsult!\");\n
\n response.Response.ShouldEndSession = false;\n
\n }\n
\n
\n return new OkObjectResult(response);\n
\n }\n
\n
\n
\n Alexa.net offers a class called\n \n ResponseBuilder\n \n , which you can use to build\n \n SkillResponse\n \n objects. This class maps the JSON that Alexa expects as output of a request to perform an action.\n
\n The\n \n ResponseBuilder\n \n class offer multiple methods to return different kind of responses, from the basic (like\n \n Tell()\n \n ) to the most advanced ones (like\n \n AskWithCard()\n \n ).\n
\n Since we're just exploring the basic concepts, for the moment we'll just use the\n \n Tell()\n \n method, which just returns a voice sentence which is then spoken by Alexa. The best practice, in the launch scenario, is also to set the\n \n ShouldEndSession\n \n property of the response to\n \n false\n \n . This means that Alexa won't close the session, but it will keep it open waiting for other commands to send to the same skill. This will allow our skill to support the following interaction model:\n
\n \n
\n This way Alexa knows that the last command (\n \n Tell me the last article\n \n ) must be passed again to our skill; it isn't a generic Alexa command.\n
\n

\n Testing our skill\n

\n
\n Before building more complex scenarios, it would be nice to test the current code to make sure everything is working as expected. Amazon offers us two ways to test our skill:\n
\n \n
\n However, before testing the skill, we need to return to the original skill checklist since we are missing one important setting: the endpoint. So far, in fact, the code of our skill lives only on our computer but, in order to work properly, we need to expose it on a web server, so that the Amazon servers can access to it.\n
\n Since we're leveraging an Azure Function, the standard approach would be to publish our function on Azure. This way it will be assigned an URL, which we can set as endpoint on the Amazon portal.\n
\n
\n However, when we are in the testing phase, this approach has some drawbacks. Every time we make some changes to the code, we need in fact to publish a new version of the function to Azure. Additionally, Azure supports remote debugging, but it isn't as fast and reliable as local debugging\n
\n
\n It would be great to test the skill locally using Visual Studio, but we would need the Alexa engine to run on our machine, which isn't clearly feasible. Is there an easy way to achieve the best of both worlds? Yes, thanks to\n \n ngrok\n \n !\n
\n
\n \n Ngrok\n \n is an open source tool which helps developers during the testing phase of REST APIs, web hooks and, generally speaking, everything that needs to be hosted on a web server to work. Ngrok takes care of exposing your local server to Internet through a public URL with SSL support. This means that we can launch our Azure Function on our local machine and set, in the Alexa Developer Portal, the URL provided by ngrok as endpoint. This way Amazon will invoke the API like if it's running on the cloud but, in reality, all the requests will arrive on your local machine, allowing you to see detailed logs, to set breakpoints in Visual Studio, etc.\n
\n
\n As first step, register an account\n \n on the official website\n \n and then download the tool. It's a command line tool, so unzip the file wherever you prefer. Ideally, you should add the folder as a path in Windows, so that you can invoke ngrok from any location.\n
\n Now open Visual Studio and start the debugging on the Azure Function by pressing F5. You will see a command prompt popping out: it's the Azure Function Core Tool, which allows you to run an Azure Function locally. The command prompt will act also as a logging window. Every time the Azure Function will be triggered, we will see the details of the request and the response in the prompt.\n
\n Moreover, do you remember the\n \n ILogger\n \n object included in the signature of the\n \n Run()\n \n method of the function? Whenever you're going to log a message using this object, it will be displayed in this console.\n
\n
\n Once the function is started, you will see in the prompt a message like the following one:\n
\n
\n \n
\n
\n Take note of the port used to expose the function, which should be 7071. Now open a command prompt on the folder where you have uncompressed ngrok and launch the following command:\n
\n \n ngrok http 7071\n
\n
\n
\n Ngrok will start and it will expose the HTTP protocol through the 7071 port. In case Visual Studio has assigned to your web server a different port, replace 7071 with the right value.\n
\n While ngrok is up and running, you will see the following screen in the command prompt:\n
\n
\n \n
\n
\n As you can see from the forwarding section, ngrok is exposing your local webserver through HTTP and HTTPS. Since we're using the free plan, we will be assigned a random subdomain of the ngrok.io domain (like xyz.ngrok.io).\n
\n Now, from the outside, any service can reach the Azure Function exposed by our local web server on the 7071 port using this address.\n
\n
\n Now we're ready to configure our Alexa skill to use this interface. Return back to the Alexa Developer Console and, in the\n \n Build\n \n section, choose\n \n Endpoint\n \n :\n
\n
\n \n
\n
\n By default, the skill will be set to use the AWS Lambda service provided by Amazon. However, since in our case we're going to use Azure, choose\n \n HTTPS\n \n and then set the\n \n Default region\n \n section with the following values:\n
\n \n
\n As you can see, if you want to load balance your skill, you can provide different endpoints for different regions of the world. Otherwise, all the requests will be sent to the default endpoint, no matter where they're coming from.\n
\n
\n Now press\n \n Save endpoints\n \n at the top, then click on\n \n Test\n \n in the tab menu. You will access to the Alexa Simulator. As first step, you have to turn on testing support using the following switch:\n
\n
\n \n
\n
\n Now you have access to the simulator. On the left you have the chat window, where you can type the command you want to send to the skill. On the right, instead, you will see the last response from Alexa, followed by the JSON inputs and outputs.\n
\n Go on and type, in the chat window, the following command:\n
\n \n open AppConsult\n
\n
\n
\n If you have done everything correctly, you should see the request coming in the Azure Function console:\n
\n
\n \n
\n
\n The Alexa Simulator, instead, should reply with the welcome message we have included in the code and, on the right, you can see the JSON request which was submitted and the JSON response which was returned by our function:\n
\n
\n \n
\n
\n Our first Alexa skill is working! Great job!\n
\n
\n Take a look at the JSON. The input is the JSON representation of the\n \n SkillRequest\n \n class, while the output is representation of the\n \n SkillResponse\n \n class. To prove that we're actually testing using our local Azure Function, simply put a breakpoint in the first line of the function, than type again the\n \n open AppConsult\n \n command in the Alexa Simulator. You will see the breakpoint being hit and you will have the chance to perform step by step debugging, add watches, etc. This opportunity will be extremely useful when you're going to implement more complex scenarios. However, remember to act fast during the debugging. Alexa, in fact, will drop the session if the skill doesn't return any response in a timely fashion.\n
\n
\n From a skill point of view, we aren't doing anything special for the moment. Let's move on and handle our first intent.\n
\n

\n Handling an intent\n

\n
\n When we have created the invocation model, we have defined an intent call\n \n LastPosts\n \n . Let's see the code we need to add to our Azure Function to handle it:\n
\n \n [FunctionName(\"Alexa\")]\n
\n public static async Task<IActionResult> Run(\n
\n [HttpTrigger(AuthorizationLevel.Function, \"post\", Route = null)] HttpRequest req,\n
\n ILogger log)\n
\n {\n
\n string json = await req.ReadAsStringAsync();\n
\n var skillRequest = JsonConvert.DeserializeObject<SkillRequest>(json);\n
\n
\n var requestType = skillRequest.GetRequestType();\n
\n
\n SkillResponse response = null;\n
\n
\n if (requestType == typeof(LaunchRequest))\n
\n {\n
\n response = ResponseBuilder.Tell(\"Welcome to AppConsult!\");\n
\n response.Response.ShouldEndSession = false;\n
\n }\n
\n
\n else if (requestType == typeof(IntentRequest))\n
\n {\n
\n var intentRequest = skillRequest.Request as IntentRequest;\n
\n
\n if (intentRequest.Intent.Name == \"LastPosts\")\n
\n {\n
\n //handle the intent\n
\n }\n
\n }\n
\n
\n return new OkObjectResult(response);\n
\n }\n
\n
\n
\n We have added a new condition to the function: this time, we check if the request's type is\n \n IntentRequest\n \n . If that's the case, we can cast the request (stored inside the\n \n Request\n \n property of the\n \n SkillRequest\n \n class) to get all the information we need.\n
\n The most important one can be found in the\n \n Name\n \n property of the\n \n Intent\n \n class: it's the unique identifier of the intent that we have configured in the invocation model. This means that, whenever Alexa will understand one of the sample utterances linked to the intent (like\n \n tell me the last post\n \n ), it will invoke the function passing\n \n LastPosts\n \n as name.\n
\n If that's the case, we can handle the command in order to return to the user the expcted result. In our case, we're going to use the\n \n Microsoft.SyndicationFeed.ReaderWriter\n \n package we have previously installed to download the RSS feed of this blog, parse it and extract the most recent news. First let's define a helper method called\n \n ParseFeed()\n \n , which accepts as input the URL of a RSS feed:\n
\n \n private static async Task<List<string>> ParseFeed(string url)\n
\n {\n
\n List<string> news = new List<string>();\n
\n using (var xmlReader = XmlReader.Create(url, new XmlReaderSettings { Async = true }))\n
\n {\n
\n RssFeedReader feedReader = new RssFeedReader(xmlReader);\n
\n while (await feedReader.Read())\n
\n {\n
\n if (feedReader.ElementType == Microsoft.SyndicationFeed.SyndicationElementType.Item)\n
\n {\n
\n var item = await feedReader.ReadItem();\n
\n news.Add(item.Title);\n
\n }\n
\n }\n
\n }\n
\n
\n return news;\n
\n }\n
\n
\n
\n We create a new\n \n XmlReader\n \n object, which is incapsulated inside the\n \n RssFeedReader\n \n class, which makes simpler navigating through the XML tree of the feed. By using a\n \n while\n \n loop, we read each item of the feed using the\n \n Read()\n \n method. If the node we're reading is, indeed, a feed item, we read its content using the\n \n ReadItem()\n \n method and we extract the\n \n Title\n \n property.\n
\n
\n Now we can use this method to return to the\n \n Run()\n \n method of the function the full list of articles published on this blog:\n
\n \n [FunctionName(\"Alexa\")]\n
\n public static async Task<IActionResult> Run(\n
\n [HttpTrigger(AuthorizationLevel.Function, \"post\", Route = null)] HttpRequest req,\n
\n ILogger log)\n
\n {\n
\n string json = await req.ReadAsStringAsync();\n
\n var skillRequest = JsonConvert.DeserializeObject<SkillRequest>(json);\n
\n
\n var requestType = skillRequest.GetRequestType();\n
\n
\n SkillResponse response = null;\n
\n
\n if (requestType == typeof(LaunchRequest))\n
\n {\n
\n response = ResponseBuilder.Tell(\"Welcome to AppConsult!\");\n
\n response.Response.ShouldEndSession = false;\n
\n }\n
\n
\n else if (requestType == typeof(IntentRequest))\n
\n {\n
\n var intentRequest = skillRequest.Request as IntentRequest;\n
\n
\n if (intentRequest.Intent.Name == \"LastPosts\")\n
\n {\n
\n string rss = \"https://blogs.msdn.microsoft.com/appconsult/feed/\";\n
\n List<string> news = await ParseFeed(rss);\n
\n
\n string output = $\"The title of the last article is {news.FirstOrDefault()}\";\n
\n
\n response = ResponseBuilder.Tell(output);\n
\n }\n
\n }\n
\n
\n return new OkObjectResult(response);\n
\n }\n
\n
\n
\n The code is very similar to the one we have used to handle the launch request. We compose a message and we add the title of the first news retrieved from the RSS feed (which is the last published, from a chronological point of view). We create a\n \n SpeakResponse\n \n by calling the\n \n Tell()\n \n method of the\n \n ResponseBuilder\n \n class and, in the end, we encapsulate it inside a\n \n OkObjectResult\n \n object, which we return to Alexa.\n
\n
\n In order to try this new feature run again the Azure Function on your local machine. If you haven't terminated ngrok, it should be still up & running, ready to forward every request coming to your assigned URL to your local web server. As such, just open again the Alexa Simulator and, this time, type the following command:\n
\n \n open appconsult and tell me the latest article\n
\n
\n
\n If you have done everything correctly, Alexa should prompt you with the title of the last published article:\n
\n
\n \n
\n

\n Deploy the function on Azure\n

\n
\n Now that we have verified that our function is working as expected, we are ready to deploy it on Azure. This way, we can continue the testing without having to keep our Azure Function simulator up & running on our local machine.\n
\n The easiest way to publish our Azure Function is through Visual Studio. Right click on your project and choose\n \n Publish\n \n . You'll have the chance to publish it using an existing Azure App Service plan or to create a new one. In my case, I have chosen to create a new one. Regardless of your choice, make sure to enable the\n \n Run from ZIP (recommended)\n \n option. The Web Deploy approach, in fact, doesn't work very well with Azure Functions, since most of the times it will require you to go to the Azure portal and stop the function before being able to perform a new deploy.\n
\n
\n In the next step you'll be able to configure your Azure Function directly from Visual Studio:\n
\n
\n \n
\n
\n \n App name\n \n is the most important parameter, since it will determine the default URL assigned to it, which will be\n \n https://.azurewebsites.net\n \n .\n
\n The other dropdowns will allow you to choose which Azure subscription (in case you have multiple ones connected to the same account), Resource Group, Hosting Plan and Storage Account you want to use.\n
\n
\n Once you have finished press\n \n Create\n \n . The process will take a while because, other than deploying the files which compose your function, Visual Studio will also take care of creating all the required infrastructure on Azure to host it.\n
\n The next times, instead, the process will be much faster, since Visual Studio will just copy the updated files to the remote location.\n
\n
\n The last step is to go back to the Alexa Developer Console and change the endpoint. It shouldn't be anymore the URL assigned by ngrok, but we need to replace it with the one assigned by Azure. You can copy it directly from the Publish window:\n
\n
\n \n
\n
\n Just remember to add the API endpoint to the URL. In my case, since the URL of my Azure App Service is\n \n \n https://appconsultskill.azurewebsites.net\n \n \n , I had to specify as endpoint\n \n \n https://appconsultskill.azurewebsites.net/api/alexa\n \n \n .\n
\n
\n \n
\n
\n If you're planning to keep using the free Azure domain instead of your custom one, you can keep the option\n \n My development endpoint is a sub-domain of a domain that has a wildcart certificate from a certificate authority\n \n selected.\n
\n If you want to test that your function is still working also after the deployment, just go back to the Alexa Simulator. You should be able to repeat the same tests we've done before with success.\n
\n

\n Wrapping up\n

\n
\n In this (long) post we have seen how to build our first Alexa skill by reusing technologies and platforms we are familiar with: C#, Visual Studio and Azure. Despite being very simple, it's fully functional. However, we aren't quite ready to submit it to certification. In order to make it available to every user who owns an Echo device, in fact, we need to pass a technical validation and a manual certification. If we go to the Amazon Developer Console we will see a section called\n \n Certification\n \n , with a step called\n \n Functional test\n \n . This tool will run a series of technical tests on your skill, which are required to pass before being able to submit it for the manual certification.\n
\n
\n If you run the validation tool now you will see that, despite our skill is working fine in the simulator, it will fail multiple checks. The reason is that, in order to be submitted, a skill must:\n
\n
    \n
    \n
  1. \n Make sure the request is indeed coming from a trusted Amazon service. Since we're hosting the skill on a platform different than AWS Lambda, we need to manually take care of this validation.\n
  2. \n
    \n
  3. \n Handle properly not just the custom intents, but also the default ones provided by Alexa, like stop, cancel, etc.\n
  4. \n
    \n
\n
\n In the next post we'll see the steps to do. In the meantime, you can play with the sample source\n \n hosted on GitHub\n \n .\n
\n
\n Happy coding!\n \n"},"Conversation:conversation:317930":{"__typename":"Conversation","id":"conversation:317930","solved":false,"topic":{"__ref":"BlogTopicMessage:message:317930"},"lastPostingActivityTime":"2022-11-22T12:16:28.592-08:00","lastPostTime":"2019-07-29T04:56:06.328-07:00","unreadReplyCount":1,"isSubscribed":false},"ModerationData:moderation_data:317930":{"__typename":"ModerationData","id":"moderation_data:317930","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzRpMUYzMkQ4MjdDMjEzMjg2NA?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzRpMUYzMkQ4MjdDMjEzMjg2NA?revision=3","title":"","associationType":"BODY","width":1204,"height":434,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzZpMTJDNjcyMkMxMUNFN0QzOA?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzZpMTJDNjcyMkMxMUNFN0QzOA?revision=3","title":"","associationType":"BODY","width":994,"height":894,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzdpMkQzQjdDRTZFN0NEOTJFOA?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzdpMkQzQjdDRTZFN0NEOTJFOA?revision=3","title":"","associationType":"BODY","width":1229,"height":581,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzhpODA0OUQ2QzJDNDk2RkI3Ng?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzhpODA0OUQ2QzJDNDk2RkI3Ng?revision=3","title":"","associationType":"BODY","width":445,"height":753,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzlpRDA1OTcwODE1RjE4RDhBOQ?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3NzlpRDA1OTcwODE1RjE4RDhBOQ?revision=3","title":"","associationType":"BODY","width":974,"height":388,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODBpNzI4RTU5MENGNEUyRjIxNQ?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODBpNzI4RTU5MENGNEUyRjIxNQ?revision=3","title":"","associationType":"BODY","width":1227,"height":667,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODFpRDhEMDNDRENFMDA5RjZBRg?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODFpRDhEMDNDRENFMDA5RjZBRg?revision=3","title":"","associationType":"BODY","width":457,"height":130,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODJpODVGRkMyNUMyQjhDMDEzRg?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODJpODVGRkMyNUMyQjhDMDEzRg?revision=3","title":"","associationType":"BODY","width":461,"height":162,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODRpMzE4RjFEOTA2RDdBRDE4OA?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODRpMzE4RjFEOTA2RDdBRDE4OA?revision=3","title":"","associationType":"BODY","width":1456,"height":840,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODVpOEVBQTgyNTUzOTA3MjU2MQ?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODVpOEVBQTgyNTUzOTA3MjU2MQ?revision=3","title":"","associationType":"BODY","width":1838,"height":1020,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODZpRjUwQTJGMTRBNjA4QTY1Ng?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODZpRjUwQTJGMTRBNjA4QTY1Ng?revision=3","title":"","associationType":"BODY","width":1453,"height":706,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODdpMkU5QTZCNzMxODc0NjcyMw?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODdpMkU5QTZCNzMxODc0NjcyMw?revision=3","title":"","associationType":"BODY","width":614,"height":1462,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODhpNjlENzkxQ0EzQkM1NUEyOA?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODhpNjlENzkxQ0EzQkM1NUEyOA?revision=3","title":"","associationType":"BODY","width":876,"height":234,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODlpQjQ2OTI0NkVGOEM5Njc1Mw?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3ODlpQjQ2OTI0NkVGOEM5Njc1Mw?revision=3","title":"","associationType":"BODY","width":1235,"height":341,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTBpMTdENTVCRDhDREI2M0JERg?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTBpMTdENTVCRDhDREI2M0JERg?revision=3","title":"","associationType":"BODY","width":1263,"height":844,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTJpQzhDRjhCNEIzQzUzNTQwOQ?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTJpQzhDRjhCNEIzQzUzNTQwOQ?revision=3","title":"","associationType":"BODY","width":801,"height":702,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTRpNkMxOTEzMTUzNEU2QkE2NA?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTRpNkMxOTEzMTUzNEU2QkE2NA?revision=3","title":"","associationType":"BODY","width":800,"height":600,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTZpMTFGMTEyNkE0Qzc4NzU1NA?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTZpMTFGMTEyNkE0Qzc4NzU1NA?revision=3","title":"","associationType":"BODY","width":637,"height":336,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTdpQTE1NEEyNUJCMzZFNUZGMQ?revision=3\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zMTc5MzAtNjc3OTdpQTE1NEEyNUJCMzZFNUZGMQ?revision=3","title":"","associationType":"BODY","width":823,"height":299,"altText":null},"Revision:revision:317930_3":{"__typename":"Revision","id":"revision:317930_3","lastEditTime":"2022-11-22T12:16:28.592-08:00"},"BlogReplyMessage:message:777285":{"__typename":"BlogReplyMessage","id":"message:777285","conversation":{"__ref":"Conversation:conversation:317930"},"author":{"__ref":"User:user:383658"},"revisionNum":3,"uid":777285,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Blog:board:ModernWorkAppConsult"},"subject":"Re: Build your first Alexa skill with Alexa.NET and Azure Functions - The basics","readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:777285"},"parent":{"__ref":"BlogTopicMessage:message:317930"},"body":"

Hi !

 

It's quite an old message, but I'm trying to migrate my function from Amazon Lambda (Node.js) to Azure Function (C#). I follow all the steps you mentioned (using the Alexa.Net Wrapper available in Nuget packages).

 

I develop locally, on my machine, and it's okay : 

- My function works well : I test with postman to simulate Alexa calls. Response are corrects.

- I plug very well my alexa console to my local function (using Ngrok like you recommend) : and results are all okay.

- I plublish without problems my function to Azure, using Visual Studio plugin (like you mentioned, with the option you recommend) : function deployed very well.

 

But, when it's published, I cannot call my function in Azure cloud. All my calls failed. Using postman, or Alexa test functionality.

 

I think my function is not visible from the web (because using it in locally way - ngrok - works fine), but I don't know where I should look settings. I thought that, with \"anonymous\" access and using the right url (I use the correct one, like you said), all will work easily... 

 

Have you an idea where I should look why my function is not reachable ? A way to test ? Quite anoying because I'm almost at the end of my goal and it seems it's a problem with Azure, not my function... 

If you have an idea, I take it !

 

Regards,

--

Sylvain

","body@stringLength":"1485","rawBody":"

Hi !

 

It's quite an old message, but I'm trying to migrate my function from Amazon Lambda (Node.js) to Azure Function (C#). I follow all the steps you mentioned (using the Alexa.Net Wrapper available in Nuget packages).

 

I develop locally, on my machine, and it's okay : 

- My function works well : I test with postman to simulate Alexa calls. Response are corrects.

- I plug very well my alexa console to my local function (using Ngrok like you recommend) : and results are all okay.

- I plublish without problems my function to Azure, using Visual Studio plugin (like you mentioned, with the option you recommend) : function deployed very well.

 

But, when it's published, I cannot call my function in Azure cloud. All my calls failed. Using postman, or Alexa test functionality.

 

I think my function is not visible from the web (because using it in locally way - ngrok - works fine), but I don't know where I should look settings. I thought that, with \"anonymous\" access and using the right url (I use the correct one, like you said), all will work easily... 

 

Have you an idea where I should look why my function is not reachable ? A way to test ? Quite anoying because I'm almost at the end of my goal and it seems it's a problem with Azure, not my function... 

If you have an idea, I take it !

 

Regards,

--

Sylvain

","kudosSumWeight":0,"repliesCount":0,"postTime":"2019-07-29T04:56:06.328-07:00","images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"attachments":{"__typename":"AttachmentConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"timeToRead":1,"currentRevision":{"__ref":"Revision:revision:777285_3"},"latestVersion":{"__typename":"FriendlyVersion","major":"3","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":7847},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"messagePolicies":{"__typename":"MessagePolicies","canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"customFields":[],"replies":{"__typename":"MessageConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"CachedAsset:theme:customTheme1-1746564048493":{"__typename":"CachedAsset","id":"theme:customTheme1-1746564048493","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["default"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"favicon-1730836283320.png","imageLastModified":"1730836286415","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"favicon-1730836271365.png","imageLastModified":"1730836274203","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1300px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_BROWSER","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"3px","borderRadius":"3px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"16px","paddingXHero":"60px","fontStyle":"NORMAL","fontWeight":"700","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-200)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-200)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"LIGHT","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.16)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.12)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-link-color)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","defaultMessageFontFamily":"var(--lia-bs-font-family-base)","forumColor":"#4099E2","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#148563","blogColor":"#1CBAA0","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#4C6B90","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#FF8000","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#D13A1F","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#333333","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#717171","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0069D4","secondary":"#333333","bodyText":"#1E1E1E","bodyBg":"#FFFFFF","info":"#409AE2","success":"#41C5AE","warning":"#FCC844","danger":"#BC341B","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#D3F5A4","#243A5E"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Segoe UI","fontStyle":"NORMAL","fontWeight":"400","h1FontSize":"34px","h2FontSize":"32px","h3FontSize":"28px","h4FontSize":"24px","h5FontSize":"20px","h6FontSize":"16px","lineHeight":"1.3","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":"","imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"40px","defaultMessageHeaderMarginBottom":"20px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"40px","specialMessageHeaderMarginBottom":"20px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Segoe UI","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.5","fontSizeBase":"16px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"14px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[{"source":"SERVER","name":"Segoe UI","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"},{"style":"NORMAL","weight":"300","__typename":"FontStyleData"},{"style":"NORMAL","weight":"600","__typename":"FontStyleData"},{"style":"NORMAL","weight":"700","__typename":"FontStyleData"},{"style":"ITALIC","weight":"400","__typename":"FontStyleData"}],"assetNames":["SegoeUI-normal-400.woff2","SegoeUI-normal-300.woff2","SegoeUI-normal-600.woff2","SegoeUI-normal-700.woff2","SegoeUI-italic-400.woff2"],"__typename":"CustomFont"},{"source":"SERVER","name":"MWF Fluent Icons","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"}],"assetNames":["MWFFluentIcons-normal-400.woff2"],"__typename":"CustomFont"}],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1745505307000","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:quilt:o365.prod:pages/blogs/BlogMessagePage:board:ModernWorkAppConsult-1746740537375":{"__typename":"CachedAsset","id":"quilt:o365.prod:pages/blogs/BlogMessagePage:board:ModernWorkAppConsult-1746740537375","value":{"id":"BlogMessagePage","container":{"id":"Common","headerProps":{"backgroundImageProps":null,"backgroundColor":null,"addComponents":null,"removeComponents":["community.widget.bannerWidget"],"componentOrder":null,"__typename":"QuiltContainerSectionProps"},"headerComponentProps":{"community.widget.breadcrumbWidget":{"disableLastCrumbForDesktop":false}},"footerProps":null,"footerComponentProps":null,"items":[{"id":"blog-article","layout":"ONE_COLUMN","bgColor":null,"showTitle":null,"showDescription":null,"textPosition":null,"textColor":null,"sectionEditLevel":"LOCKED","bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"OneColumnQuiltSection","columnMap":{"main":[{"id":"blogs.widget.blogArticleWidget","className":"lia-blog-container","props":null,"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"}},{"id":"section-1729184836777","layout":"MAIN_SIDE","bgColor":"transparent","showTitle":false,"showDescription":false,"textPosition":"CENTER","textColor":"var(--lia-bs-body-color)","sectionEditLevel":null,"bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"MainSideQuiltSection","columnMap":{"main":[],"side":[],"__typename":"MainSideSectionColumns"}}],"__typename":"QuiltContainer"},"__typename":"Quilt","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1745505307000","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-pages/blogs/BlogMessagePage-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-pages/blogs/BlogMessagePage-1745505307000","value":{"title":"{contextMessageSubject} | {communityTitle}","errorMissing":"This blog post cannot be found","name":"Blog Message Page","section.blog-article.title":"Blog Post","archivedMessageTitle":"This Content Has Been Archived","section.section-1729184836777.title":"","section.section-1729184836777.description":"","section.CncIde.title":"Blog Post","section.tifEmD.description":"","section.tifEmD.title":""},"localOverride":false},"CachedAsset:quiltWrapper:o365.prod:Common:1746563987353":{"__typename":"CachedAsset","id":"quiltWrapper:o365.prod:Common:1746563987353","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"community.widget.navbarWidget","props":{"showUserName":true,"showRegisterLink":true,"useIconLanguagePicker":true,"useLabelLanguagePicker":true,"className":"QuiltComponent_lia-component-edit-mode__0nCcm","links":{"sideLinks":[],"mainLinks":[{"children":[],"linkType":"INTERNAL","id":"gxcuf89792","params":{},"routeName":"CommunityPage"},{"children":[],"linkType":"EXTERNAL","id":"external-link","url":"/Directory","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft365","params":{"categoryId":"microsoft365"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows","params":{"categoryId":"Windows"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-microsoft365-copilot-link","params":{"categoryId":"Microsoft365Copilot"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-teams","params":{"categoryId":"MicrosoftTeams"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-securityand-compliance","params":{"categoryId":"microsoft-security"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"azure","params":{"categoryId":"Azure"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-content_management-link","params":{"categoryId":"Content_Management"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"exchange","params":{"categoryId":"Exchange"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows-server","params":{"categoryId":"Windows-Server"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"outlook","params":{"categoryId":"Outlook"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-endpoint-manager","params":{"categoryId":"microsoftintune"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-2","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities","url":"/","target":"BLANK"},{"children":[{"linkType":"INTERNAL","id":"a-i","params":{"categoryId":"AI"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"education-sector","params":{"categoryId":"EducationSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"partner-community","params":{"categoryId":"PartnerCommunity"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"i-t-ops-talk","params":{"categoryId":"ITOpsTalk"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"healthcare-and-life-sciences","params":{"categoryId":"HealthcareAndLifeSciences"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-mechanics","params":{"categoryId":"MicrosoftMechanics"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"public-sector","params":{"categoryId":"PublicSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-m-b","params":{"categoryId":"MicrosoftforNonprofits"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"io-t","params":{"categoryId":"IoT"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"startupsat-microsoft","params":{"categoryId":"StartupsatMicrosoft"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"driving-adoption","params":{"categoryId":"DrivingAdoption"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-1","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities-1","url":"/","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external","url":"/Blogs","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external-1","url":"/Events","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft-learn-1","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-learn-blog","params":{"boardId":"MicrosoftLearnBlog","categoryId":"MicrosoftLearn"},"routeName":"BlogBoardPage"},{"linkType":"EXTERNAL","id":"external-10","url":"https://learningroomdirectory.microsoft.com/","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-3","url":"https://docs.microsoft.com/learn/dynamics365/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-4","url":"https://docs.microsoft.com/learn/m365/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-5","url":"https://docs.microsoft.com/learn/topics/sci/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-6","url":"https://docs.microsoft.com/learn/powerplatform/?wt.mc_id=techcom_header-webpage-powerplatform","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-7","url":"https://docs.microsoft.com/learn/github/?wt.mc_id=techcom_header-webpage-github","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-8","url":"https://docs.microsoft.com/learn/teams/?wt.mc_id=techcom_header-webpage-teams","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-9","url":"https://docs.microsoft.com/learn/dotnet/?wt.mc_id=techcom_header-webpage-dotnet","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-2","url":"https://docs.microsoft.com/learn/azure/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"}],"linkType":"INTERNAL","id":"microsoft-learn","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"community-info-center","params":{"categoryId":"Community-Info-Center"},"routeName":"CategoryPage"}]},"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","controllerHighlightColor":"hsla(30, 100%, 50%)","linkFontWeight":"400","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkBoxShadowHover":"none","linkFontSize":"14px","backgroundOpacity":0.8,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","hamburgerColor":"var(--lia-nav-controller-icon-color)","linkTextBorderBottom":"none","brandLogoHeight":"30px","linkBgHoverColor":"transparent","linkLetterSpacing":"normal","collapseMenuDividerOpacity":0.16,"dropdownPaddingBottom":"15px","paddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"1px solid var(--lia-bs-border-color)","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","collapseMenuDividerBg":"var(--lia-nav-link-color)","linkColor":"var(--lia-bs-body-color)","linkJustifyContent":"flex-start","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","controllerTextColor":"var(--lia-nav-controller-icon-color)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-body-color)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid var(--lia-bs-body-color)","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","linkPaddingX":"10px","linkPaddingY":"5px","paddingTop":"15px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkBgColor":"transparent","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkDropdownPaddingY":"9px","controllerIconColor":"var(--lia-bs-body-color)","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"var(--lia-bs-body-color)"},"showSearchIcon":false,"languagePickerStyle":"iconAndLabel"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"transparent","linkHighlightColor":"var(--lia-bs-primary)","visualEffects":{"showBottomBorder":true},"linkTextColor":"var(--lia-bs-gray-700)"},"__typename":"QuiltComponent"},{"id":"custom.widget.community_banner","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"usePageWidth":false,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.HeroBanner","props":{"widgetVisibility":"signedInOrAnonymous","usePageWidth":false,"useTitle":true,"cMax_items":3,"useBackground":false,"title":"","lazyLoad":false,"widgetChooser":"custom.widget.HeroBanner"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.MicrosoftFooter","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1745505307000","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.community_banner-en-us-1746740526123":{"__typename":"CachedAsset","id":"component:custom.widget.community_banner-en-us-1746740526123","value":{"component":{"id":"custom.widget.community_banner","template":{"id":"community_banner","markupLanguage":"HANDLEBARS","style":".community-banner {\n a.top-bar.btn {\n top: 0px;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0px;\n background: #0068b8;\n color: white;\n padding: 10px 0px;\n display: block;\n box-shadow: none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0px !important;\n font-size: 14px;\n }\n}\n","texts":{},"defaults":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.community_banner","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"community announcement text","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_community_banner_community-banner_1x9u2_1 {\n a.custom_widget_community_banner_top-bar_1x9u2_2.custom_widget_community_banner_btn_1x9u2_2 {\n top: 0;\n width: 100%;\n z-index: 999;\n text-align: center;\n left: 0;\n background: #0068b8;\n color: white;\n padding: 0.625rem 0;\n display: block;\n box-shadow: none !important;\n border: none !important;\n border-radius: none !important;\n margin: 0 !important;\n font-size: 0.875rem;\n }\n}\n","tokens":{"community-banner":"custom_widget_community_banner_community-banner_1x9u2_1","top-bar":"custom_widget_community_banner_top-bar_1x9u2_2","btn":"custom_widget_community_banner_btn_1x9u2_2"}},"form":null},"localOverride":false},"CachedAsset:component:custom.widget.HeroBanner-en-us-1746740526123":{"__typename":"CachedAsset","id":"component:custom.widget.HeroBanner-en-us-1746740526123","value":{"component":{"id":"custom.widget.HeroBanner","template":{"id":"HeroBanner","markupLanguage":"REACT","style":null,"texts":{"searchPlaceholderText":"Search this community","followActionText":"Follow","unfollowActionText":"Following","searchOnHoverText":"Please enter your search term(s) and then press return key to complete a search.","blogs.sidebar.pagetitle":"Latest Blogs | Microsoft Tech Community","followThisNode":"Follow this node","unfollowThisNode":"Unfollow this node"},"defaults":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.HeroBanner","form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"__typename":"Component","localOverride":false},"globalCss":null,"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"}},"localOverride":false},"CachedAsset:component:custom.widget.MicrosoftFooter-en-us-1746740526123":{"__typename":"CachedAsset","id":"component:custom.widget.MicrosoftFooter-en-us-1746740526123","value":{"component":{"id":"custom.widget.MicrosoftFooter","template":{"id":"MicrosoftFooter","markupLanguage":"HANDLEBARS","style":".context-uhf {\n min-width: 280px;\n font-size: 15px;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.c-uhff-link {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.c-uhff {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.c-uhff-nav {\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n .c-heading-4 {\n color: #616161;\n word-break: break-word;\n font-size: 15px;\n line-height: 20px;\n padding: 36px 0 4px;\n font-weight: 600;\n }\n .c-uhff-nav-row {\n .c-uhff-nav-group {\n display: block;\n float: left;\n min-height: 1px;\n vertical-align: text-top;\n padding: 0 12px;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.c-list.f-bare {\n font-size: 11px;\n line-height: 16px;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 8px 0;\n margin: 0;\n }\n }\n }\n }\n}\n.c-uhff-base {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 30px 5% 16px;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.c-uhff-ccpa {\n font-size: 11px;\n line-height: 16px;\n float: left;\n margin: 3px 0;\n }\n a.c-uhff-ccpa:hover {\n text-decoration: underline;\n }\n ul.c-list {\n font-size: 11px;\n line-height: 16px;\n float: right;\n margin: 3px 0;\n color: #616161;\n li {\n padding: 0 24px 4px 0;\n display: inline-block;\n }\n }\n .c-list.f-bare {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 30px 24px 16px;\n }\n}\n\n.social-share {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n\n.sharing-options {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 43px;\n border-radius: 0px 7px 7px 0px;\n}\n.linkedin-icon {\n border-top-right-radius: 7px;\n}\n.linkedin-icon:hover {\n border-radius: 0;\n}\n.social-share-rss-image {\n border-bottom-right-radius: 7px;\n}\n.social-share-rss-image:hover {\n border-radius: 0;\n}\n\n.social-link-footer {\n position: relative;\n display: block;\n margin: -2px 0;\n transition: all 0.2s ease;\n}\n.social-link-footer:hover .linkedin-icon {\n border-radius: 0;\n}\n.social-link-footer:hover .social-share-rss-image {\n border-radius: 0;\n}\n\n.social-link-footer img {\n width: 40px;\n height: auto;\n transition: filter 0.3s ease;\n}\n\n.social-share-list {\n width: 40px;\n}\n.social-share-rss-image {\n width: 40px;\n}\n\n.share-icon {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n\n.share-icon:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n\n.share-icon:hover .label {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n\n.label {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 10px;\n top: 50%;\n transform: translateY(-50%);\n height: 40px;\n border-radius: 0 6px 6px 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 5px 20px 8px;\n margin-left: -1px;\n}\n.linkedin {\n background-color: #0474b4;\n}\n.facebook {\n background-color: #3c5c9c;\n}\n.twitter {\n background-color: white;\n color: black;\n}\n.reddit {\n background-color: #fc4404;\n}\n.mail {\n background-color: #848484;\n}\n.bluesky {\n background-color: white;\n color: black;\n}\n.rss {\n background-color: #ec7b1c;\n}\n#RSS {\n width: 40px;\n height: 40px;\n}\n\n@media (max-width: 991px) {\n .social-share {\n display: none;\n }\n}\n","texts":{"New tab":"What's New","New 1":"Surface Laptop Studio 2","New 2":"Surface Laptop Go 3","New 3":"Surface Pro 9","New 4":"Surface Laptop 5","New 5":"Surface Studio 2+","New 6":"Copilot in Windows","New 7":"Microsoft 365","New 8":"Windows 11 apps","Store tab":"Microsoft Store","Store 1":"Account Profile","Store 2":"Download Center","Store 3":"Microsoft Store Support","Store 4":"Returns","Store 5":"Order tracking","Store 6":"Certified Refurbished","Store 7":"Microsoft Store Promise","Store 8":"Flexible Payments","Education tab":"Education","Edu 1":"Microsoft in education","Edu 2":"Devices for education","Edu 3":"Microsoft Teams for Education","Edu 4":"Microsoft 365 Education","Edu 5":"How to buy for your school","Edu 6":"Educator Training and development","Edu 7":"Deals for students and parents","Edu 8":"Azure for students","Business tab":"Business","Bus 1":"Microsoft Cloud","Bus 2":"Microsoft Security","Bus 3":"Dynamics 365","Bus 4":"Microsoft 365","Bus 5":"Microsoft Power Platform","Bus 6":"Microsoft Teams","Bus 7":"Microsoft Industry","Bus 8":"Small Business","Developer tab":"Developer & IT","Dev 1":"Azure","Dev 2":"Developer Center","Dev 3":"Documentation","Dev 4":"Microsoft Learn","Dev 5":"Microsoft Tech Community","Dev 6":"Azure Marketplace","Dev 7":"AppSource","Dev 8":"Visual Studio","Company tab":"Company","Com 1":"Careers","Com 2":"About Microsoft","Com 3":"Company News","Com 4":"Privacy at Microsoft","Com 5":"Investors","Com 6":"Diversity and inclusion","Com 7":"Accessiblity","Com 8":"Sustainibility"},"defaults":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.MicrosoftFooter","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_MicrosoftFooter_context-uhf_105bp_1 {\n min-width: 17.5rem;\n font-size: 0.9375rem;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-link_105bp_12 {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff_105bp_12 {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35 {\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n .custom_widget_MicrosoftFooter_c-heading-4_105bp_49 {\n color: #616161;\n word-break: break-word;\n font-size: 0.9375rem;\n line-height: 1.25rem;\n padding: 2.25rem 0 0.25rem;\n font-weight: 600;\n }\n .custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57 {\n .custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58 {\n display: block;\n float: left;\n min-height: 0.0625rem;\n vertical-align: text-top;\n padding: 0 0.75rem;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 0.5rem 0;\n margin: 0;\n }\n }\n }\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff-base_105bp_94 {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 1.875rem 5% 1rem;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: left;\n margin: 0.1875rem 0;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107:hover {\n text-decoration: underline;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: right;\n margin: 0.1875rem 0;\n color: #616161;\n li {\n padding: 0 1.5rem 0.25rem 0;\n display: inline-block;\n }\n }\n .custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 1.875rem 1.5rem 1rem;\n }\n}\n.custom_widget_MicrosoftFooter_social-share_105bp_138 {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n.custom_widget_MicrosoftFooter_sharing-options_105bp_146 {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 2.6875rem;\n border-radius: 0 0.4375rem 0.4375rem 0;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-top-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-bottom-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 {\n position: relative;\n display: block;\n margin: -0.125rem 0;\n transition: all 0.2s ease;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 img {\n width: 2.5rem;\n height: auto;\n transition: filter 0.3s ease;\n}\n.custom_widget_MicrosoftFooter_social-share-list_105bp_188 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195 {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover .custom_widget_MicrosoftFooter_label_105bp_207 {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n.custom_widget_MicrosoftFooter_label_105bp_207 {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 0.625rem;\n top: 50%;\n transform: translateY(-50%);\n height: 2.5rem;\n border-radius: 0 0.375rem 0.375rem 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1.25rem 0.3125rem 1.25rem 0.5rem;\n margin-left: -0.0625rem;\n}\n.custom_widget_MicrosoftFooter_linkedin_105bp_156 {\n background-color: #0474b4;\n}\n.custom_widget_MicrosoftFooter_facebook_105bp_237 {\n background-color: #3c5c9c;\n}\n.custom_widget_MicrosoftFooter_twitter_105bp_240 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_reddit_105bp_244 {\n background-color: #fc4404;\n}\n.custom_widget_MicrosoftFooter_mail_105bp_247 {\n background-color: #848484;\n}\n.custom_widget_MicrosoftFooter_bluesky_105bp_250 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_rss_105bp_254 {\n background-color: #ec7b1c;\n}\n#custom_widget_MicrosoftFooter_RSS_105bp_1 {\n width: 2.5rem;\n height: 2.5rem;\n}\n@media (max-width: 991px) {\n .custom_widget_MicrosoftFooter_social-share_105bp_138 {\n display: none;\n }\n}\n","tokens":{"context-uhf":"custom_widget_MicrosoftFooter_context-uhf_105bp_1","c-uhff-link":"custom_widget_MicrosoftFooter_c-uhff-link_105bp_12","c-uhff":"custom_widget_MicrosoftFooter_c-uhff_105bp_12","c-uhff-nav":"custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35","c-heading-4":"custom_widget_MicrosoftFooter_c-heading-4_105bp_49","c-uhff-nav-row":"custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57","c-uhff-nav-group":"custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58","c-list":"custom_widget_MicrosoftFooter_c-list_105bp_78","f-bare":"custom_widget_MicrosoftFooter_f-bare_105bp_78","c-uhff-base":"custom_widget_MicrosoftFooter_c-uhff-base_105bp_94","c-uhff-ccpa":"custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107","social-share":"custom_widget_MicrosoftFooter_social-share_105bp_138","sharing-options":"custom_widget_MicrosoftFooter_sharing-options_105bp_146","linkedin-icon":"custom_widget_MicrosoftFooter_linkedin-icon_105bp_156","social-share-rss-image":"custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162","social-link-footer":"custom_widget_MicrosoftFooter_social-link-footer_105bp_169","social-share-list":"custom_widget_MicrosoftFooter_social-share-list_105bp_188","share-icon":"custom_widget_MicrosoftFooter_share-icon_105bp_195","label":"custom_widget_MicrosoftFooter_label_105bp_207","linkedin":"custom_widget_MicrosoftFooter_linkedin_105bp_156","facebook":"custom_widget_MicrosoftFooter_facebook_105bp_237","twitter":"custom_widget_MicrosoftFooter_twitter_105bp_240","reddit":"custom_widget_MicrosoftFooter_reddit_105bp_244","mail":"custom_widget_MicrosoftFooter_mail_105bp_247","bluesky":"custom_widget_MicrosoftFooter_bluesky_105bp_250","rss":"custom_widget_MicrosoftFooter_rss_105bp_254","RSS":"custom_widget_MicrosoftFooter_RSS_105bp_1"}},"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1745505307000","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1745505307000","value":{"messageMarkedAsSpam":"This post has been marked as spam","messageMarkedAsSpam@board:TKB":"This article has been marked as spam","messageMarkedAsSpam@board:BLOG":"This post has been marked as spam","messageMarkedAsSpam@board:FORUM":"This discussion has been marked as spam","messageMarkedAsSpam@board:OCCASION":"This event has been marked as spam","messageMarkedAsSpam@board:IDEA":"This idea has been marked as spam","manageSpam":"Manage Spam","messageMarkedAsAbuse":"This post has been marked as abuse","messageMarkedAsAbuse@board:TKB":"This article has been marked as abuse","messageMarkedAsAbuse@board:BLOG":"This post has been marked as abuse","messageMarkedAsAbuse@board:FORUM":"This discussion has been marked as abuse","messageMarkedAsAbuse@board:OCCASION":"This event has been marked as abuse","messageMarkedAsAbuse@board:IDEA":"This idea has been marked as abuse","preModCommentAuthorText":"This comment will be published as soon as it is approved","preModCommentModeratorText":"This comment is awaiting moderation","messageMarkedAsOther":"This post has been rejected due to other reasons","messageMarkedAsOther@board:TKB":"This article has been rejected due to other reasons","messageMarkedAsOther@board:BLOG":"This post has been rejected due to other reasons","messageMarkedAsOther@board:FORUM":"This discussion has been rejected due to other reasons","messageMarkedAsOther@board:OCCASION":"This event has been rejected due to other reasons","messageMarkedAsOther@board:IDEA":"This idea has been rejected due to other reasons","messageArchived":"This post was archived on {date}","relatedUrl":"View Related Content","relatedContentText":"Showing related content","archivedContentLink":"View Archived Content"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1745505307000","value":{"anonymous":"Anonymous","author":"{messageAuthorLogin}","authorBy":"{messageAuthorLogin}","board":"{messageBoardTitle}","replyToUser":" to {parentAuthor}","showMoreReplies":"Show More","replyText":"Reply","repliesText":"Replies","markedAsSolved":"Marked as Solution","movedMessagePlaceholder.BLOG":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.TKB":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.FORUM":"{count, plural, =0 {This reply has been} other {These replies have been} }","movedMessagePlaceholder.IDEA":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.OCCASION":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholderUrlText":"moved.","messageStatus":"Status: ","statusChanged":"Status changed: {previousStatus} to {currentStatus}","statusAdded":"Status added: {status}","statusRemoved":"Status removed: {status}","labelExpand":"expand replies","labelCollapse":"collapse replies","unhelpfulReason.reason1":"Content is outdated","unhelpfulReason.reason2":"Article is missing information","unhelpfulReason.reason3":"Content is for a different Product","unhelpfulReason.reason4":"Doesn't match what I was searching for"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageDeepLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageDeepLink-1745505307000","value":{"viewFullDiscussion@board:FORUM":"View Full Discussion ({repliesCount} Replies)","viewFullDiscussion@board:BLOG":"View Full Discussion ({repliesCount} Comments)","viewFullDiscussion@board:TKB":"View Full Discussion ({repliesCount} Comments)","viewFullDiscussion@board:IDEA":"View Full Discussion ({repliesCount} Comments)","viewFullDiscussion@board:OCCASION":"View Full Discussion ({repliesCount} Comments)","showParents@board:FORUM":"Show Parent Replies","showParents@board:BLOG":"Show Parent Comments","showParents@board:TKB":"Show Parent Comments","showParents@board:IDEA":"Show Parent Comments","showParents@board:OCCASION":"Show Parent Comments"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1745505307000","value":{"leaveReply":"Leave a reply...","leaveReply@board:BLOG@message:root":"Leave a comment...","leaveReply@board:TKB@message:root":"Leave a comment...","leaveReply@board:IDEA@message:root":"Leave a comment...","leaveReply@board:OCCASION@message:root":"Leave a comment...","repliesTurnedOff.FORUM":"Replies are turned off for this topic","repliesTurnedOff.BLOG":"Comments are turned off for this topic","repliesTurnedOff.TKB":"Comments are turned off for this topic","repliesTurnedOff.IDEA":"Comments are turned off for this topic","repliesTurnedOff.OCCASION":"Comments are turned off for this topic","infoText":"Stop poking me!"},"localOverride":false},"Category:category:Exchange":{"__typename":"Category","id":"category:Exchange","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Outlook":{"__typename":"Category","id":"category:Outlook","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Community-Info-Center":{"__typename":"Category","id":"category:Community-Info-Center","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:EducationSector":{"__typename":"Category","id":"category:EducationSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:DrivingAdoption":{"__typename":"Category","id":"category:DrivingAdoption","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Azure":{"__typename":"Category","id":"category:Azure","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows-Server":{"__typename":"Category","id":"category:Windows-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftTeams":{"__typename":"Category","id":"category:MicrosoftTeams","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PublicSector":{"__typename":"Category","id":"category:PublicSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:IoT":{"__typename":"Category","id":"category:IoT","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:HealthcareAndLifeSciences":{"__typename":"Category","id":"category:HealthcareAndLifeSciences","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:ITOpsTalk":{"__typename":"Category","id":"category:ITOpsTalk","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftLearn":{"__typename":"Category","id":"category:MicrosoftLearn","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:MicrosoftLearnBlog":{"__typename":"Blog","id":"board:MicrosoftLearnBlog","blogPolicies":{"__typename":"BlogPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:AI":{"__typename":"Category","id":"category:AI","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftMechanics":{"__typename":"Category","id":"category:MicrosoftMechanics","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftforNonprofits":{"__typename":"Category","id":"category:MicrosoftforNonprofits","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:StartupsatMicrosoft":{"__typename":"Category","id":"category:StartupsatMicrosoft","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PartnerCommunity":{"__typename":"Category","id":"category:PartnerCommunity","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Microsoft365Copilot":{"__typename":"Category","id":"category:Microsoft365Copilot","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows":{"__typename":"Category","id":"category:Windows","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Content_Management":{"__typename":"Category","id":"category:Content_Management","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft-security":{"__typename":"Category","id":"category:microsoft-security","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoftintune":{"__typename":"Category","id":"category:microsoftintune","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"CachedAsset:text:en_US-components/community/Navbar-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1745505307000","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","gxcuf89792":"Tech Community","external-1":"Events","s-m-b":"Nonprofit Community","windows-server":"Windows Server","education-sector":"Education Sector","driving-adoption":"Driving Adoption","Common-content_management-link":"Content Management","microsoft-learn":"Microsoft Learn","s-q-l-server":"Content Management","partner-community":"Microsoft Partner Community","microsoft365":"Microsoft 365","external-9":".NET","external-8":"Teams","external-7":"Github","products-services":"Products","external-6":"Power Platform","communities-1":"Topics","external-5":"Microsoft Security","planner":"Outlook","external-4":"Microsoft 365","external-3":"Dynamics 365","azure":"Azure","healthcare-and-life-sciences":"Healthcare and Life Sciences","external-2":"Azure","microsoft-mechanics":"Microsoft Mechanics","microsoft-learn-1":"Community","external-10":"Learning Room Directory","microsoft-learn-blog":"Blog","windows":"Windows","i-t-ops-talk":"ITOps Talk","external-link-1":"View All","microsoft-securityand-compliance":"Microsoft Security","public-sector":"Public Sector","community-info-center":"Lounge","external-link-2":"View All","microsoft-teams":"Microsoft Teams","external":"Blogs","microsoft-endpoint-manager":"Microsoft Intune","startupsat-microsoft":"Startups at Microsoft","exchange":"Exchange","a-i":"AI and Machine Learning","io-t":"Internet of Things (IoT)","Common-microsoft365-copilot-link":"Microsoft 365 Copilot","outlook":"Microsoft 365 Copilot","external-link":"Community Hubs","communities":"Products"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1745505307000","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1745505307000","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1745505307000","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1745505307000","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1745505307000","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCoverImage-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCoverImage-1745505307000","value":{"coverImageTitle":"Cover Image"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeTitle-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeTitle-1745505307000","value":{"nodeTitle":"{nodeTitle, select, community {Community} other {{nodeTitle}}} "},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTimeToRead-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTimeToRead-1745505307000","value":{"minReadText":"{min} MIN READ"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1745505307000","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1745505307000","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1745505307000","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1745505307000","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1745505307000","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCustomFields-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1745505307000","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1745505307000","value":{"lastUpdatedDatePublished":"{publishCount, plural, one{Published} other{Updated}} {date}","lastUpdatedDateDraft":"Created {date}","version":"Version {major}.{minor}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1745505307000","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyButton-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1745505307000","value":{"repliesCount":"{count}","title":"Reply","title@board:BLOG@message:root":"Comment","title@board:TKB@message:root":"Comment","title@board:IDEA@message:root":"Comment","title@board:OCCASION@message:root":"Comment"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1745505307000","value":{"sendMessage":"Send Message","actionMessage":"Follow this blog board to get notified when there's new activity","coAuthor":"CO-PUBLISHER","contributor":"CONTRIBUTOR","userProfile":"View Profile","iconlink":"Go to {name} {type}"},"localOverride":false},"Rank:rank:37":{"__typename":"Rank","id":"rank:37","position":18,"name":"Copper Contributor","color":"333333","icon":null,"rankStyle":"TEXT"},"User:user:383658":{"__typename":"User","id":"user:383658","uid":383658,"login":"TheoOrl45","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/m_assets/avatars/default/avatar-6.svg?time=0"},"rank":{"__ref":"Rank:rank:37"},"email":"","messagesCount":1,"biography":null,"topicsCount":0,"kudosReceivedCount":0,"kudosGivenCount":0,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2019-07-29T04:48:05.967-07:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":0},"ModerationData:moderation_data:777285":{"__typename":"ModerationData","id":"moderation_data:777285","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"Revision:revision:777285_3":{"__typename":"Revision","id":"revision:777285_3","lastEditTime":"2019-07-29T04:58:49.583-07:00"},"QueryVariables:ReplyList:message:777285:3":{"__typename":"QueryVariables","id":"ReplyList:message:777285:3","value":{"id":"message:777285","first":10,"sorts":{"postTime":{"direction":"DESC"}},"repliesFirst":3,"repliesFirstDepthThree":1,"repliesSorts":{"postTime":{"direction":"DESC"}},"useAvatar":true,"useAuthorLogin":true,"useAuthorRank":true,"useBody":true,"useKudosCount":true,"useTimeToRead":false,"useMedia":false,"useReadOnlyIcon":false,"useRepliesCount":true,"useSearchSnippet":false,"useAcceptedSolutionButton":false,"useSolvedBadge":false,"useAttachments":false,"attachmentsFirst":5,"useTags":false,"useNodeAncestors":false,"useUserHoverCard":false,"useNodeHoverCard":false,"useModerationStatus":true,"usePreviewSubjectModal":false,"useMessageStatus":true}},"ROOT_MUTATION":{"__typename":"Mutation"},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1745505307000","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1745505307000","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1745505307000","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagView/TagViewChip-1745505307000","value":{"tagLabelName":"Tag name {tagName}"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1745505307000","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeAvatar-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeAvatar-1745505307000","value":{"altTitle":"Node avatar for {nodeTitle}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeDescription-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeDescription-1745505307000","value":{"description":"{description}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1745505307000","value":{"title":"{count, plural, one{# Reply} other{# Replies}}","title@board:BLOG":"{count, plural, one{# Comment} other{# Comments}}","title@board:TKB":"{count, plural, one{# Comment} other{# Comments}}","title@board:IDEA":"{count, plural, one{# Comment} other{# Comments}}","title@board:OCCASION":"{count, plural, one{# Comment} other{# Comments}}","noRepliesTitle":"No Replies","noRepliesTitle@board:BLOG":"No Comments","noRepliesTitle@board:TKB":"No Comments","noRepliesTitle@board:IDEA":"No Comments","noRepliesTitle@board:OCCASION":"No Comments","noRepliesDescription":"Be the first to reply","noRepliesDescription@board:BLOG":"Be the first to comment","noRepliesDescription@board:TKB":"Be the first to comment","noRepliesDescription@board:IDEA":"Be the first to comment","noRepliesDescription@board:OCCASION":"Be the first to comment","messageReadOnlyAlert:BLOG":"Comments have been turned off for this post","messageReadOnlyAlert:TKB":"Comments have been turned off for this article","messageReadOnlyAlert:IDEA":"Comments have been turned off for this idea","messageReadOnlyAlert:FORUM":"Replies have been turned off for this discussion","messageReadOnlyAlert:OCCASION":"Comments have been turned off for this event"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1745505307000","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false}}}},"page":"/blogs/BlogMessagePage/BlogMessagePage","query":{"boardId":"modernworkappconsult","messageSubject":"build-your-first-alexa-skill-with-alexa-net-and-azure-functions---the-basics","messageId":"317930","replyId":"777285"},"buildId":"-gVUpXaWnPcjlrLJZ92B7","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"o365","openTelemetryServiceVersion":"25.3.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/customComponent/CustomComponent/CustomComponent.tsx","./components/blogs/BlogArticleWidget/BlogArticleWidget.tsx","./components/messages/MessageView/MessageViewStandard/MessageViewStandard.tsx","./components/external/components/ExternalComponent.tsx","./components/customComponent/CustomComponentContent/TemplateContent.tsx","../shared/client/components/common/List/UnwrappedList/UnwrappedList.tsx","./components/tags/TagView/TagView.tsx","./components/tags/TagView/TagViewChip/TagViewChip.tsx"],"appGip":true,"scriptLoader":[{"id":"analytics","src":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/pagescripts/1730819800000/analytics.js?page.id=BlogReplyPage&entity.id=board%3Amodernworkappconsult&entity.id=message%3A777285","strategy":"afterInteractive"}]}