Следуя документации Microsoft, нас пытаются вызвать Graph API для получения содержимого расшифровки.
Полезная информация:
MicrosoftAppType=MultiTenant
MicrosoftAppId=2dacff5b-9494-45b4-90f1-df6953d401aa
MicrosoftAppTenantId=91e213e9-498d-46b9-bc35-cd0aa9390b45
SubscriptionId=1106df7f-3a2b-4b98-80ff-7ab8738177d
MeetingID=MSpiYTc2OWFjOC0wOTc1LTRiOTctYTlmOS03NWFlYzZiNjEwMDQqMCoqMTk6bWVldGluZ19OV1ZsTmpoaU9Ua3RNV000WWkwME1HSmhMV0ZoT1RZdE0yUmlObVk0WmpnMk9HUTVAdGhyZWFkLnYy
TranscriptID=VjIjIzFiYTc2OWFjOC0wOTc1LTRiOTctYTlmOS03NWFlYzZiNjEwMDQ5MWUyMTNlOS00OThkLTQ2YjktYmMzNS1jZDBhYTkzOTBiNDUwNDAwMDAwMDgyMDBFMDAwNzRDNUI3MTAxQTgyRTAwODAwMDAwMDAwNDQ4MzI0ZjY2ZGQyZGEwMTAwMDAwMDAwMDAwMDAwMDAxMDAwMDAwMGEzMWUzOWY1MDhhZWM5NGVhZWM2ZDlkYzEwMjIzNWQ3IyMwZjM1MWUxNy1mMjRjLTRiZmUtYTM4NC0zZDdmN2ZmODliMzE=
Разрешение приложения/RSC (мы добавили необходимое разрешение в манифест)
Сначала мы создали GraphClient с учетными данными нашего приложения следующим образом:
// @azure/identityconst
credential = new ClientSecretCredential(
process.env.MicrosoftAppTenantId,
process.env.MicrosoftAppId,
process.env.MicrosoftAppPassword
);
// @microsoft/microsoft-graph-client/authProviders/azureTokenCredentials
const authProvider = new TokenCredentialAuthenticationProvider(credential, {
['https://graph.microsoft.com/.default']
});
const graphClient = Client.initWithMiddleware({ authProvider: authProvider });
Мы успешно создали подписку следующим образом:
const transcriptSubscription = {
changeType: 'created',
notificationUrl: 'https://6ebd-2405-201-1021-7808-298c-d664-4dae-fff3.ngrok-free.app/notificationClient',
lifecycleNotificationUrl: 'https://6ebd-2405-201-1021-7808-298c-d664-4dae-fff3.ngrok-free.app/api/lifecycleNotifications',
resource: 'communications/onlineMeetings/getAllTranscripts?useResourceSpecificConsentBasedAuthorization=true',
includeResourceData: true,
encryptionCertificate: '{valid certificate}',
encryptionCertificateId:'{validId}',
expirationDateTime: '2024-07-11T11:00:00.0000000Z',
clientState: '{secretClientState}'
};
await graphClient.api('/subscriptions')
.post(transcriptSubscription).then((res) =>
{
console.info('Subscription:', res);
}).catch((err) => {
console.info('Error:', err);
});
Результаты этого кода создают действительную подписку
res: {
'@odata.context': 'https://graph.microsoft.com/v1.0/$metadata#subscriptions/$entity',
id: '1106df7f-3a2b-4b98-80ff-7ab8738177d9',
resource: 'communications/onlineMeetings/getAllTranscripts?useResourceSpecificConsentBasedAuthorization=true',
applicationId: '2dacff5b-9494-45b4-90f1-df6953d401aa',
changeType: 'created',
clientState: '{secretClientState}',
notificationUrl: 'https://6ebd-2405-201-1021-7808-298c-d664-4dae-fff3.ngrok-free.app/notificationClient',
notificationQueryOptions: null,
lifecycleNotificationUrl: 'https://6ebd-2405-201-1021-7808-298c-d664-4dae-fff3.ngrok-free.app/api/lifecycleNotifications',
expirationDateTime: '2024-07-11T11:00:00Z',
creatorId: 'b3d2c52d-3d02-43bf-bd27-6408d62af8a1',
includeResourceData: true,
latestSupportedTlsVersion: 'v1_2', // Other data}
Мы слушаем арендатора, поэтому события принимаются так, как ожидалось:
subscriptionId: '1106df7f-3a2b-4b98-80ff-7ab8738177d9',
changeType: 'created',
clientState: '{secretClientState}',
subscriptionExpirationDateTime: '2024-07-11T11:00:00+00:00',
resource: "communications/onlineMeetings('MSpiYTc2OWFjOC0wOTc1LTRiOTctYTlmOS03NWFlYzZiNjEwMDQqMCoqMTk6bWVldGluZ19OV1ZsTmpoaU9Ua3RNV000WWkwME1HSmhMV0ZoT1RZdE0yUmlObVk0WmpnMk9HUTVAdGhyZWFkLnYy')/transcripts('VjIjIzFiYTc2OWFjOC0wOTc1LTRiOTctYTlmOS03NWFlYzZiNjEwMDQ5MWUyMTNlOS00OThkLTQ2YjktYmMzNS1jZDBhYTkzOTBiNDUwNDAwMDAwMDgyMDBFMDAwNzRDNUI3MTAxQTgyRTAwODAwMDAwMDAwNDQ4MzI0ZjY2ZGQyZGEwMTAwMDAwMDAwMDAwMDAwMDAxMDAwMDAwMGEzMWUzOWY1MDhhZWM5NGVhZWM2ZDlkYzEwMjIzNWQ3IyMwZjM1MWUxNy1mMjRjLTRiZmUtYTM4NC0zZDdmN2ZmODliMzE=')",// Other data
Когда мы пытаемся вызвать API контента:
await graphClient
.api(`users/${ process.env.MicrosoftAppId }/onlineMeetings/${ meetingId }/transcripts/${ transcriptId }`)
.get()
.then((dataFromResponse) => {
console.info('### dataFromResponse:', dataFromResponse);
})
.catch((error) => {
console.info('### error:', error);
});
Мы получаем ответ об ошибке следующего содержания:
body: `{
"code":"Forbidden","message":"Application is not allowed to perform operations on the user '2dacff5b-9494-45b4-90f1-df6953d401aa', neither is allowed access through RSC permission evaluation.",
"innerError":{"date":"2024-07-10T02:45:09","request-id":"81fbbe48-d368-41d0-b5ab-f1a3e59f237a",
"client-request-id":"34e6cbfd-a622-0969-e57e-cc9c3c4e04c0"
}}`
Мое приложение участвует в подписке, и мы также пробовали использовать «бета-версию», но результат тот же.
Как получить расшифровку через Graph API?
Первым делом:
Обязательно добавьте следующие разрешения API Microsoft Graph при регистрации приложения.
ОнлайнВстречи.Читать.Все
OnlineMeetingTranscript.Читать.Все
Дайте согласие администратора на разрешения API.
Второе:
Вам необходимо создать политику доступа к приложению, чтобы разрешить приложению доступ к онлайн-собраниям от имени пользователя.
Вот команды для настройки политики доступа к приложениям:
--> Импорт-модуль MicrosoftTeams
--> Connect-MicrosoftTeams
--> New-CsApplicationAccessPolicy -Identity «PolicyName» -AppIds «App-regID» -Description «Некоторое описание»
--> Grant-CsApplicationAccessPolicy -PolicyName «PolicyName» -Identity «UserID»
Предоставьте эту политику, используя свой идентификатор пользователя Azure.
После создания и предоставления этой политики доступа вы сможете использовать API Graph для доступа к содержимому стенограмм с использованием токена аутентификации регистрации вашего приложения.
Для справки: https://learn.microsoft.com/en-us/graph/cloud-communication-online-meeting-application-access-policy
Примечание. Не присваивайте политике статус -Global. Потому что тогда любой член арендатора сможет получить доступ к расшифровкам любых собраний.
Тем не менее мы сталкиваемся с той же проблемой. Мы можем что-нибудь еще сделать, @Вивек Панчал?
@shwetachikhalikar, вы вызываете эту конечную точку API Graph, чтобы получить расшифровку, верно? --> GET /users/{userId}/onlineMeetings/{meetingId}/transcripts/{transcriptId} Я вижу, что вы используете «process.env.MicrosoftAppId» вместо userID. Вы должны использовать тот же идентификатор пользователя, с помощью которого вы предоставили политику доступа.
Рад был помочь!!!
Все равно ошибка та же