[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6FD0EQRCBCDR402HDEW1MNX":3,"skill-same:01M6FD0EQRCBCDR402HDEW1MNX":50},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":23,"linkOnly":24,"markdownContent":25,"markdownBody":25,"frontMatter":26,"refName":27,"commitSha":28,"skillDirectory":29,"forksCount":30,"repositoryHtmlUrl":31,"repositoryHomepageUrl":32,"ownerHtmlUrl":33,"ownerBlogUrl":6,"ownerDescription":34,"updatedAt":35,"install":36,"resources":49},"01M6FD0EQRCBCDR402HDEW1MNX","azure-communication-common-java",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fmicrosoft\u002Fskills\u002Fazure-communication-common-java\u002FSKILL.md",[],[18,19,20,21,22],"azure","azure communication common java","communication","java","common","2026-11-10 10:12:30",false,"# Azure Communication Common (Java)\n\nShared authentication utilities and data structures for Azure Communication Services.\n\n## Installation\n\n```xml\n\u003Cdependency>\n    \u003CgroupId>com.azure\u003C\u002FgroupId>\n    \u003CartifactId>azure-communication-common\u003C\u002FartifactId>\n    \u003Cversion>1.4.0\u003C\u002Fversion>\n\u003C\u002Fdependency>\n```\n\n## Key Concepts\n\n| Class | Purpose |\n|-------|---------|\n| `CommunicationTokenCredential` | Authenticate users with ACS services |\n| `CommunicationTokenRefreshOptions` | Configure automatic token refresh |\n| `CommunicationUserIdentifier` | Identify ACS users |\n| `PhoneNumberIdentifier` | Identify PSTN phone numbers |\n| `MicrosoftTeamsUserIdentifier` | Identify Teams users |\n| `UnknownIdentifier` | Generic identifier for unknown types |\n\n## CommunicationTokenCredential\n\n### Static Token (Short-lived Clients)\n\n```java\nimport com.azure.communication.common.CommunicationTokenCredential;\n\n\u002F\u002F Simple static token - no refresh\nString userToken = \"\u003Cuser-access-token>\";\nCommunicationTokenCredential credential = new CommunicationTokenCredential(userToken);\n\n\u002F\u002F Use with Chat, Calling, etc.\nChatClient chatClient = new ChatClientBuilder()\n    .endpoint(\"https:\u002F\u002F\u003Cresource>.communication.azure.com\")\n    .credential(credential)\n    .buildClient();\n```\n\n### Proactive Token Refresh (Long-lived Clients)\n\n```java\nimport com.azure.communication.common.CommunicationTokenRefreshOptions;\nimport java.util.concurrent.Callable;\n\n\u002F\u002F Token refresher callback - called when token is about to expire\nCallable\u003CString> tokenRefresher = () -> {\n    \u002F\u002F Call your server to get a fresh token\n    return fetchNewTokenFromServer();\n};\n\n\u002F\u002F With proactive refresh\nCommunicationTokenRefreshOptions refreshOptions = new CommunicationTokenRefreshOptions(tokenRefresher)\n    .setRefreshProactively(true)      \u002F\u002F Refresh before expiry\n    .setInitialToken(currentToken);    \u002F\u002F Optional initial token\n\nCommunicationTokenCredential credential = new CommunicationTokenCredential(refreshOptions);\n```\n\n### Async Token Refresh\n\n```java\nimport java.util.concurrent.CompletableFuture;\n\n\u002F\u002F Async token fetcher\nCallable\u003CString> asyncRefresher = () -> {\n    CompletableFuture\u003CString> future = fetchTokenAsync();\n    return future.get();  \u002F\u002F Block until token is available\n};\n\nCommunicationTokenRefreshOptions options = new CommunicationTokenRefreshOptions(asyncRefresher)\n    .setRefreshProactively(true);\n\nCommunicationTokenCredential credential = new CommunicationTokenCredential(options);\n```\n\n## Entra ID (Azure AD) Authentication\n\n```java\nimport com.azure.identity.InteractiveBrowserCredentialBuilder;\nimport com.azure.communication.common.EntraCommunicationTokenCredentialOptions;\nimport java.util.Arrays;\nimport java.util.List;\n\n\u002F\u002F For Teams Phone Extensibility\nInteractiveBrowserCredential entraCredential = new InteractiveBrowserCredentialBuilder()\n    .clientId(\"\u003Cyour-client-id>\")\n    .tenantId(\"\u003Cyour-tenant-id>\")\n    .redirectUrl(\"\u003Cyour-redirect-uri>\")\n    .build();\n\nString resourceEndpoint = \"https:\u002F\u002F\u003Cresource>.communication.azure.com\";\nList\u003CString> scopes = Arrays.asList(\n    \"https:\u002F\u002Fauth.msft.communication.azure.com\u002FTeamsExtension.ManageCalls\"\n);\n\nEntraCommunicationTokenCredentialOptions entraOptions = \n    new EntraCommunicationTokenCredentialOptions(entraCredential, resourceEndpoint)\n        .setScopes(scopes);\n\nCommunicationTokenCredential credential = new CommunicationTokenCredential(entraOptions);\n```\n\n## Communication Identifiers\n\n### CommunicationUserIdentifier\n\n```java\nimport com.azure.communication.common.CommunicationUserIdentifier;\n\n\u002F\u002F Create identifier for ACS user\nCommunicationUserIdentifier user = new CommunicationUserIdentifier(\"8:acs:resource-id_user-id\");\n\n\u002F\u002F Get raw ID\nString rawId = user.getId();\n```\n\n### PhoneNumberIdentifier\n\n```java\nimport com.azure.communication.common.PhoneNumberIdentifier;\n\n\u002F\u002F E.164 format phone number\nPhoneNumberIdentifier phone = new PhoneNumberIdentifier(\"+14255551234\");\n\nString phoneNumber = phone.getPhoneNumber();  \u002F\u002F \"+14255551234\"\nString rawId = phone.getRawId();              \u002F\u002F \"4:+14255551234\"\n```\n\n### MicrosoftTeamsUserIdentifier\n\n```java\nimport com.azure.communication.common.MicrosoftTeamsUserIdentifier;\n\n\u002F\u002F Teams user identifier\nMicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier(\"\u003Cteams-user-id>\")\n    .setCloudEnvironment(CommunicationCloudEnvironment.PUBLIC);\n\n\u002F\u002F For anonymous Teams users\nMicrosoftTeamsUserIdentifier anonymousTeamsUser = new MicrosoftTeamsUserIdentifier(\"\u003Cteams-user-id>\")\n    .setAnonymous(true);\n```\n\n### UnknownIdentifier\n\n```java\nimport com.azure.communication.common.UnknownIdentifier;\n\n\u002F\u002F For identifiers of unknown type\nUnknownIdentifier unknown = new UnknownIdentifier(\"some-raw-id\");\n```\n\n## Identifier Parsing\n\n```java\nimport com.azure.communication.common.CommunicationIdentifier;\nimport com.azure.communication.common.CommunicationIdentifierModel;\n\n\u002F\u002F Parse raw ID to appropriate type\npublic CommunicationIdentifier parseIdentifier(String rawId) {\n    if (rawId.startsWith(\"8:acs:\")) {\n        return new CommunicationUserIdentifier(rawId);\n    } else if (rawId.startsWith(\"4:\")) {\n        String phone = rawId.substring(2);\n        return new PhoneNumberIdentifier(phone);\n    } else if (rawId.startsWith(\"8:orgid:\")) {\n        String teamsId = rawId.substring(8);\n        return new MicrosoftTeamsUserIdentifier(teamsId);\n    } else {\n        return new UnknownIdentifier(rawId);\n    }\n}\n```\n\n## Type Checking Identifiers\n\n```java\nimport com.azure.communication.common.CommunicationIdentifier;\n\npublic void processIdentifier(CommunicationIdentifier identifier) {\n    if (identifier instanceof CommunicationUserIdentifier) {\n        CommunicationUserIdentifier user = (CommunicationUserIdentifier) identifier;\n        System.out.println(\"ACS User: \" + user.getId());\n        \n    } else if (identifier instanceof PhoneNumberIdentifier) {\n        PhoneNumberIdentifier phone = (PhoneNumberIdentifier) identifier;\n        System.out.println(\"Phone: \" + phone.getPhoneNumber());\n        \n    } else if (identifier instanceof MicrosoftTeamsUserIdentifier) {\n        MicrosoftTeamsUserIdentifier teams = (MicrosoftTeamsUserIdentifier) identifier;\n        System.out.println(\"Teams User: \" + teams.getUserId());\n        System.out.println(\"Anonymous: \" + teams.isAnonymous());\n        \n    } else if (identifier instanceof UnknownIdentifier) {\n        UnknownIdentifier unknown = (UnknownIdentifier) identifier;\n        System.out.println(\"Unknown: \" + unknown.getId());\n    }\n}\n```\n\n## Token Access\n\n```java\nimport com.azure.core.credential.AccessToken;\n\n\u002F\u002F Get current token (for debugging\u002Flogging - don't expose!)\nCommunicationTokenCredential credential = new CommunicationTokenCredential(token);\n\n\u002F\u002F Sync access\nAccessToken accessToken = credential.getToken();\nSystem.out.println(\"Token expires: \" + accessToken.getExpiresAt());\n\n\u002F\u002F Async access\ncredential.getTokenAsync()\n    .subscribe(token -> {\n        System.out.println(\"Token: \" + token.getToken().substring(0, 20) + \"...\");\n        System.out.println(\"Expires: \" + token.getExpiresAt());\n    });\n```\n\n## Dispose Credential\n\n```java\n\u002F\u002F Clean up when done\ncredential.close();\n\n\u002F\u002F Or use try-with-resources\ntry (CommunicationTokenCredential cred = new CommunicationTokenCredential(options)) {\n    \u002F\u002F Use credential\n    chatClient.doSomething();\n}\n```\n\n## Cloud Environments\n\n```java\nimport com.azure.communication.common.CommunicationCloudEnvironment;\n\n\u002F\u002F Available environments\nCommunicationCloudEnvironment publicCloud = CommunicationCloudEnvironment.PUBLIC;\nCommunicationCloudEnvironment govCloud = CommunicationCloudEnvironment.GCCH;\nCommunicationCloudEnvironment dodCloud = CommunicationCloudEnvironment.DOD;\n\n\u002F\u002F Set on Teams identifier\nMicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier(\"\u003Cuser-id>\")\n    .setCloudEnvironment(CommunicationCloudEnvironment.GCCH);\n```\n\n## Environment Variables\n\n```bash\nAZURE_COMMUNICATION_ENDPOINT=https:\u002F\u002F\u003Cresource>.communication.azure.com\nAZURE_COMMUNICATION_USER_TOKEN=\u003Cuser-access-token>\n```\n\n## Best Practices\n\n1. **Proactive Refresh** - Always use `setRefreshProactively(true)` for long-lived clients\n2. **Token Security** - Never log or expose full tokens\n3. **Close Credentials** - Dispose of credentials when no longer needed\n4. **Error Handling** - Handle token refresh failures gracefully\n5. **Identifier Types** - Use specific identifier types, not raw strings\n\n## Common Usage Patterns\n\n```java\n\u002F\u002F Pattern: Create credential for Chat\u002FCalling client\npublic ChatClient createChatClient(String token, String endpoint) {\n    CommunicationTokenRefreshOptions refreshOptions = \n        new CommunicationTokenRefreshOptions(this::refreshToken)\n            .setRefreshProactively(true)\n            .setInitialToken(token);\n    \n    CommunicationTokenCredential credential = \n        new CommunicationTokenCredential(refreshOptions);\n    \n    return new ChatClientBuilder()\n        .endpoint(endpoint)\n        .credential(credential)\n        .buildClient();\n}\n\nprivate String refreshToken() {\n    \u002F\u002F Call your token endpoint\n    return tokenService.getNewToken();\n}\n```\n\n## Trigger Phrases\n\n- \"ACS authentication\", \"communication token credential\"\n- \"user access token\", \"token refresh\"\n- \"CommunicationUserIdentifier\", \"PhoneNumberIdentifier\"\n- \"Azure Communication Services authentication\"\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Fmicrosoft\u002Fskills\u002Fazure-communication-common-java",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":37,"prompt":47,"zipAvailable":48},[38,41,44],{"tool":39,"command":40},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill azure-communication-common-java",{"tool":42,"command":43},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill azure-communication-common-java",{"tool":45,"command":46},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill azure-communication-common-java","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fmicrosoft\u002Fskills\u002Fazure-communication-common-java\u002FSKILL.md",true,[],[51,65,75,84,90,97],{"skillNo":52,"name":53,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":54,"categories":55,"keywords":61,"publishedAt":23},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[56],{"categoryNo":57,"categoryName":58,"taxonomyType":59,"taxonomyTypeDesc":60},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[62,63,64],"model","model hierarchy","model hierarchy skill",{"skillNo":66,"name":67,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":71,"publishedAt":23},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[70],{"categoryNo":57,"categoryName":58,"taxonomyType":59,"taxonomyTypeDesc":60},[72,73,74],"MCP","zoom","zoom mcp",{"skillNo":76,"name":77,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":80,"publishedAt":23},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[81,82,83,73],"sdk","zoom apps sdk","apps",{"skillNo":85,"name":86,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":89,"publishedAt":23},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[86],{"skillNo":91,"name":92,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":96,"publishedAt":23},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[95],{"categoryNo":57,"categoryName":58,"taxonomyType":59,"taxonomyTypeDesc":60},[92],{"skillNo":98,"name":99,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":23},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[99]]