Skip to content

Commit

Permalink
Update copilot.eligibility.getEligibilityInfo to retrieve info from…
Browse files Browse the repository at this point in the history
… host (#2554)

* Update `isSupported` to reflect whether the hub has provided support for `copilot.eligibility` sub-capability.
* Updated eligibility function to send a message to the host to retrieve the eligibility info if necessary
* Update `getEligibilityInfo` to use `sendMessageToParentAsync` and expect an `AppEligibilityInformation | SdkError` back
* Update unit tests
* Add validation of response

---------

Co-authored-by: Erin <[email protected]>
  • Loading branch information
erinha and erinha authored Oct 16, 2024
1 parent 8969fc2 commit 4e7dee4
Show file tree
Hide file tree
Showing 6 changed files with 307 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ const CopilotAPIs = (): ReactElement => {
ApiWithoutInput({
name: 'getEligibilityInfo',
title: 'Get the app Eligibility Information',
onClick: async () => `${JSON.stringify(copilot.eligibility.getEligibilityInfo())}`,
onClick: async () => {
const result = await copilot.eligibility.getEligibilityInfo();
return JSON.stringify(result);
},
});

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Updated `copilot.eligibility.getEligibilityInfo` to be async and get the eligibility info from the host if it is not already available.",
"packageName": "@microsoft/teams-js",
"email": "[email protected]",
"dependentChangeType": "patch"
}
1 change: 1 addition & 0 deletions packages/teams-js/src/internal/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export const enum ApiName {
Conversations_OpenConversation = 'conversations.openConversation',
Conversations_RegisterCloseConversationHandler = 'conversations.registerCloseConversationHandler',
Conversations_RegisterStartConversationHandler = 'conversations.registerStartConversationHandler',
Copilot_Eligibility_GetEligibilityInfo = 'copilot.eligibility.getEligibilityInfo',
Dialog_AdaptiveCard_Bot_Open = 'dialog.adaptiveCard.bot.open',
Dialog_AdaptiveCard_Open = 'dialog.adaptiveCard.open',
Dialog_RegisterMessageForChildHandler = 'dialog.registerMessageForChildHandler',
Expand Down
54 changes: 49 additions & 5 deletions packages/teams-js/src/private/copilot.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { sendAndUnwrap } from '../internal/communication';
import { ensureInitialized } from '../internal/internalAPIs';
import { ApiName, ApiVersionNumber, getApiVersionTag, getLogger } from '../internal/telemetry';
import { errorNotSupportedOnPlatform } from '../public/constants';
import { AppEligibilityInformation } from '../public/interfaces';
import { AppEligibilityInformation, isSdkError, SdkError } from '../public/interfaces';
import { runtime } from '../public/runtime';

const copilotTelemetryVersionNumber: ApiVersionNumber = ApiVersionNumber.V_2;
const copilotLogger = getLogger('copilot');
/**
* @beta
* @hidden
Expand All @@ -29,7 +33,10 @@ export namespace copilot {
* @throws Error if {@linkcode app.initialize} has not successfully completed
*/
export function isSupported(): boolean {
return ensureInitialized(runtime) && !!runtime.hostVersionsInfo?.appEligibilityInformation;
return (
ensureInitialized(runtime) &&
(!!runtime.hostVersionsInfo?.appEligibilityInformation || !!runtime.supports.copilot?.eligibility)
);
}

/**
Expand All @@ -41,12 +48,49 @@ export namespace copilot {
*
* @throws Error if {@linkcode app.initialize} has not successfully completed
*/
export function getEligibilityInfo(): AppEligibilityInformation {
export async function getEligibilityInfo(): Promise<AppEligibilityInformation> {
ensureInitialized(runtime);
if (!isSupported()) {
throw errorNotSupportedOnPlatform;
throw new Error(`Error code: ${errorNotSupportedOnPlatform.errorCode}, message: Not supported on platform`);
}
return runtime.hostVersionsInfo!.appEligibilityInformation!;

// Return the eligibility information if it is already available
if (runtime.hostVersionsInfo?.appEligibilityInformation) {
copilotLogger('Eligibility information is already available on runtime.');
return runtime.hostVersionsInfo!.appEligibilityInformation;
}

copilotLogger('Eligibility information is not available on runtime. Requesting from host.');
// Send message to host SDK to get eligibility information
const response = await sendAndUnwrap<AppEligibilityInformation | SdkError>(
getApiVersionTag(copilotTelemetryVersionNumber, ApiName.Copilot_Eligibility_GetEligibilityInfo),
ApiName.Copilot_Eligibility_GetEligibilityInfo,
);

if (isSdkError(response)) {
throw new Error(
`Error code: ${response.errorCode}, message: ${response.message ?? 'Failed to get eligibility information from the host.'}`,
);
}
// validate response
if (!isEligibilityInfoValid(response)) {
throw new Error('Error deserializing eligibility information');
}
return response;
}

function isEligibilityInfoValid(eligibilityInfo: AppEligibilityInformation): boolean {
if (
eligibilityInfo.ageGroup === undefined ||
eligibilityInfo.cohort === undefined ||
eligibilityInfo.userClassification === undefined ||
eligibilityInfo.isCopilotEligible === undefined ||
eligibilityInfo.isCopilotEnabledRegion === undefined ||
eligibilityInfo.isOptedOutByAdmin === undefined
) {
return false;
}
return true;
}
}
}
3 changes: 3 additions & 0 deletions packages/teams-js/src/public/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ interface IRuntimeV4 extends IBaseRuntime {
readonly chat?: {};
readonly clipboard?: {};
readonly conversations?: {};
readonly copilot?: {
readonly eligibility?: {};
};
readonly dialog?: {
readonly card?: {
readonly bot?: {};
Expand Down
Loading

0 comments on commit 4e7dee4

Please sign in to comment.