OAuth интеграции. Документация для разработчиков

OAuth интеграция в МТС Линк. Документация для разработчиков

Связанные статьи:


Что нужно сделать для запуска интеграции по OAuth:

  • Заключить партнерское соглашение и получить client_id 
  • Сгенерировать secret с помощью API /v3/partner-applications/{applicationId}/reset-secret
  • Определить список требуемых разрешений для работы приложения (доступ к мероприятия, файлам и тд)
  • Реализовать запрос доступа с помощью OAuth и интегрироваться с UserAPI
  • Провести финальный тест и добавить приложение в магазин интеграция МТС Линк


1. Получение client_id

После заключения партнерского приложения разработчик получает:

Параметр

Описание

Пример

client_id

Строка. Код партнера

myapp324234234234

application_id

Число. Код приложения

1


2. Создание secret

Чтобы получить secret нужно будет вызвать метод UserAPI (Получение secret для интеграции по OAuth):


curl --location --request POST 'https://userapi.mts-link.ru/v3/partner-applications/{applicationId}/reset-secret' \
--header 'x-auth-token: {apiKey}'

где
{ applicationId } - 1
{apiKey} - ключ к UserAPI вашего тестового стенда
Ответ:

{
"data": {
"secret": "{secret}"
}
}


3. Настройка тестового стенда

По умолчанию, все OAuth интеграции запрещены, чтобы предотвратить несанкционированный доступ. Администратору нужно явным образом разрешить интеграцию, тогда её смогут использовать другие сотрудники организации. 

Разрешить доступ можно через API.

curl --location --request POST 'https://userapi.mts-link.ru/v3/partner-application-clients/{applicationId}/enable' \

--header 'x-auth-token: {apiKey}'


Также администратор может разрешить в ЛК (Организация - Интеграции - OAuth-приожения)


Подробнее:

4. Разрешения на запуск методов

Необходимо запрашивать минимально необходимый список прав. Например, для выгрузки списка события достаточно доступа userapi_events_read. Ниже подробно перечислены доступы для вызова каждого метода UserAPI.

Список скоупов

NameDescription
userapi_contactsПолный доступ к контактам
userapi_contacts_readДоступ к чтению контактов
userapi_coursesПолный доступ к курсам
userapi_courses_readДоступ на чтение данных курсов
userapi_eventsПолный доступ к мероприятиям
userapi_events_readДоступ на чтение данных мероприятий
userapi_filesПолный доступ к файлам
userapi_files_readДоступ на чтение данных файлов
userapi_link_chatsПолный доступ к Линк-Чатам
userapi_link_chats_readДоступ на чтение данных Линк-Чатов
userapi_media_streamsДоступ к подписке на медиа-потоки мероприятия
userapi_organizationПолный доступ к управлению организацией
userapi_organization_readДоступ на чтение данных организации
userapi_recordsПолный доступ к записям мероприятий
userapi_records_readДоступ на чтение данных записей мероприятия
userapi_statisticsДоступ к статистике
userapi_testsПолный доступ к тестам
userapi_tests_readДоступ на чтение данных тестов
userapi_webhooksПолный доступ к веб-хукам
userapi_webhooks_readДоступ на чтение данных веб-хуков

Соответствие роутов скоупам 

MethodApiKey scopesOAuth scopes
1GET /userapi/brandingsuserapi_organization
userapi_organization_read
2GET /userapi/chats/channel/{channelId}userapi_link_chatsuserapi_link_chats
userapi_link_chats_readuserapi_link_chats_read
3GET /userapi/chats/channel/{channelId}/messagesuserapi_link_chatsuserapi_link_chats
userapi_link_chats_readuserapi_link_chats_read
4POST /userapi/chats/channels/createuserapi_link_chatsuserapi_link_chats
5POST /userapi/chats/channels/{channelId}/deleteuserapi_link_chatsuserapi_link_chats
6POST /userapi/chats/channels/{channelId}/send-messageuserapi_link_chatsuserapi_link_chats
7POST /userapi/chats/channels/{channelId}/updateuserapi_link_chatsuserapi_link_chats
8GET /userapi/chats/channels/{channelId}/usersuserapi_link_chatsuserapi_link_chats
userapi_link_chats_readuserapi_link_chats_read
9POST /userapi/chats/channels/{channelId}/users/adduserapi_link_chatsuserapi_link_chats
10POST /userapi/chats/channels/{channelId}/users/removeuserapi_link_chatsuserapi_link_chats
11GET /userapi/chats/channels/{userId}userapi_link_chatsuserapi_link_chats
userapi_link_chats_readuserapi_link_chats_read
12GET /userapi/chats/organization/membersuserapi_link_chatsuserapi_link_chats
userapi_link_chats_readuserapi_link_chats_read
13GET /userapi/chats/teamsuserapi_link_chatsuserapi_link_chats
userapi_link_chats_readuserapi_link_chats_read
14POST /userapi/chats/teams/createuserapi_link_chatsuserapi_link_chats
15POST /userapi/chats/teams/{teamId}/channels/adduserapi_link_chatsuserapi_link_chats
16POST /userapi/chats/teams/{teamId}/channels/removeuserapi_link_chatsuserapi_link_chats
17POST /userapi/chats/teams/{teamId}/deleteuserapi_link_chatsuserapi_link_chats
18POST /userapi/chats/teams/{teamId}/updateuserapi_link_chatsuserapi_link_chats
19POST /userapi/chats/teams/{teamId}/users/adduserapi_link_chatsuserapi_link_chats
20POST /userapi/chats/teams/{teamId}/users/removeuserapi_link_chatsuserapi_link_chats
21GET /userapi/contacts/searchuserapi_contacts
userapi_contacts_read
22POST /userapi/contacts/tags/adduserapi_contacts
23PUT /userapi/contacts/{contactId}userapi_contacts
24DELETE /userapi/contacts/{contactId}userapi_contacts
25GET /userapi/contacts/{contactId}userapi_contacts
userapi_contacts_read
26GET /userapi/contacts/{contactId}/useruserapi_contacts
userapi_contacts_read
27GET /userapi/converted-recordsuserapi_records
userapi_records_read
28POST /userapi/convertedrecords/{convertedRecordId}/canceluserapi_records
29GET /userapi/courses/{courseId}userapi_courses
userapi_courses_read
30GET /userapi/courses/{courseId}/groupsuserapi_courses
userapi_courses_read
31GET /userapi/courses/{courseId}/groups/{groupId}userapi_courses
userapi_courses_read
32GET /userapi/courses/{courseId}/groups/{groupId}/statisticsuserapi_courses
userapi_courses_read
33POST /userapi/eventsuserapi_eventsuserapi_events
userapi_internal_for_link_chats
34POST /userapi/events/calluserapi_events
userapi_internal_for_link_chats
35POST /userapi/events/{eventId}/filesuserapi_eventsuserapi_events
36DELETE /userapi/events/{eventId}/filesuserapi_events
37GET /userapi/events/{eventId}/filesuserapi_eventsuserapi_events
userapi_events_readuserapi_events_read
38DELETE /userapi/events/{eventId}/files/{fileId}userapi_eventsuserapi_events
39GET /userapi/events/{eventId}/files/{fileId}userapi_events
userapi_events_read
40PUT /userapi/events/{eventId}/files/{fileId}userapi_events
41POST /userapi/events/{eventId}/inviteuserapi_eventsuserapi_events
42PUT /userapi/events/{eventId}/moderateuserapi_events
43GET /userapi/events/{eventId}/participationsuserapi_events
userapi_events_read
44POST /userapi/events/{eventId}/registeruserapi_eventsuserapi_events
45POST /userapi/events/{eventId}/sessionsuserapi_eventsuserapi_events
userapi_internal_for_link_chats
46GET /userapi/eventsessions/endlessuserapi_eventsuserapi_events
userapi_events_readuserapi_events_read
47GET /userapi/eventsessions/endless/activitiesuserapi_eventsuserapi_events
userapi_events_readuserapi_events_read
48GET /userapi/eventsessions/filesuserapi_events
userapi_events_read
49PUT /userapi/eventsessions/{eventSessionId}userapi_eventsuserapi_events
50GET /userapi/eventsessions/{eventSessionId}userapi_eventsuserapi_events
userapi_events_readuserapi_events_read
userapi_internal_for_link_chats
51DELETE /userapi/eventsessions/{eventSessionId}userapi_events
52GET /userapi/eventsessions/{eventSessionId}/agendasuserapi_events
userapi_events_read
53POST /userapi/eventsessions/{eventSessionId}/chatuserapi_events
54DELETE /userapi/eventsessions/{eventSessionId}/chatuserapi_events
55GET /userapi/eventsessions/{eventSessionId}/chatuserapi_events
userapi_events_read
56PUT /userapi/eventsessions/{eventSessionId}/chat/messages/moderateuserapi_events
57GET /userapi/eventsessions/{eventSessionId}/converted-recordsuserapi_records
userapi_records_read
58POST /userapi/eventsessions/{eventSessionId}/filesuserapi_eventsuserapi_events
59DELETE /userapi/eventsessions/{eventSessionId}/filesuserapi_events
60GET /userapi/eventsessions/{eventSessionId}/filesuserapi_eventsuserapi_events
userapi_events_readuserapi_events_read
61PUT /userapi/eventsessions/{eventSessionId}/files/{fileId}userapi_events
62GET /userapi/eventsessions/{eventSessionId}/files/{fileId}userapi_events
userapi_events_read
63DELETE /userapi/eventsessions/{eventSessionId}/files/{fileId}userapi_eventsuserapi_events
64POST /userapi/eventsessions/{eventSessionId}/inviteuserapi_eventsuserapi_events
userapi_internal_for_link_chats
65POST /userapi/eventsessions/{eventSessionId}/media-streams/subscribeuserapi_media_streams
66POST /userapi/eventsessions/{eventSessionId}/media-streams/unsubscribeuserapi_media_streams
67GET /userapi/eventsessions/{eventSessionId}/participationsuserapi_eventsuserapi_events
userapi_events_readuserapi_events_read
68POST /userapi/eventsessions/{eventSessionId}/participations/remove-privacy-datauserapi_events
69GET /userapi/eventsessions/{eventSessionId}/questionsuserapi_events
userapi_events_read
70POST /userapi/eventsessions/{eventSessionId}/questionsuserapi_events
71DELETE /userapi/eventsessions/{eventSessionId}/questionsuserapi_events
72PUT /userapi/eventsessions/{eventSessionId}/questions/moderateuserapi_events
73PUT /userapi/eventsessions/{eventSessionId}/recordsuserapi_recordsuserapi_events
74POST /userapi/eventsessions/{eventSessionId}/records/conversionsuserapi_records
75POST /userapi/eventsessions/{eventSessionId}/registeruserapi_eventsuserapi_events
76PUT /userapi/eventsessions/{eventSessionId}/startuserapi_events
userapi_internal_for_link_chats
77PUT /userapi/eventsessions/{eventSessionId}/stopuserapi_events
userapi_internal_for_link_chats
78GET /userapi/eventsessions/{eventSessionId}/transcript/listuserapi_events
userapi_events_read
79POST /userapi/fileSystem/fileuserapi_filesuserapi_files
80GET /userapi/fileSystem/file/{id}userapi_filesuserapi_files
userapi_files_readuserapi_files_read
81DELETE /userapi/fileSystem/file/{id}userapi_filesuserapi_files
82GET /userapi/fileSystem/filesuserapi_filesuserapi_files
userapi_files_readuserapi_files_read
83GET /userapi/fileSystem/files/converted-recorduserapi_records
userapi_records_read
84POST /userapi/fileSystem/folderuserapi_files
85POST /userapi/groups/{groupId}/invitesuserapi_courses
86PUT /userapi/groups/{groupId}/invites/resenduserapi_courses
87PUT /userapi/groups/{groupId}/invites/resend/alluserapi_courses
88GET /userapi/invitation-link/urluserapi_organization
userapi_organization_read
userapi_internal_for_link_chats
89POST /userapi/membership/{membershipId}/deleteuserapi_organization
90GET /userapi/organization-groupsuserapi_organization
userapi_organization_read
91GET /userapi/organization/coursesuserapi_courses
userapi_courses_read
92GET /userapi/organization/courses/groupsuserapi_courses
userapi_courses_read
93GET /userapi/organization/events/scheduleuserapi_events
userapi_events_read
94GET /userapi/organization/events/{eventId}userapi_events
userapi_events_read
95PUT /userapi/organization/events/{eventId}userapi_eventsuserapi_events
96DELETE /userapi/organization/events/{eventId}userapi_eventsuserapi_events
97PUT /userapi/organization/events/{eventId}/moveuserapi_events
98GET /userapi/organization/eventsessions/streamFilesUrlsuserapi_records
userapi_records_read
99GET /userapi/organization/membersuserapi_organizationuserapi_organization
userapi_organization_readuserapi_organization_read
userapi_internal_for_link_chats
100GET /userapi/organization/users/{userId}/statisticsuserapi_statistics
101POST /userapi/organizations/invite-usersuserapi_organization
userapi_internal_for_link_chats
102POST /userapi/participations/deleteuserapi_events
103PUT /userapi/participations/kickuserapi_events
104PUT /userapi/participations/updateuserapi_events
105POST /userapi/partner-application-clients/{applicationId}/disableuserapi_organization
106POST /userapi/partner-application-clients/{applicationId}/enableuserapi_organization
107GET /userapi/partner-application-usersuserapi_organization
userapi_organization_read
108POST /userapi/partner-application-users/removeuserapi_organization
109GET /userapi/partner-applicationsuserapi_organization
userapi_organization_read
110POST /userapi/partner-applications/{partnerApplicationId}/reset-secretuserapi_organization
111GET /userapi/profileprofileprofile
112GET /userapi/recordsuserapi_records
userapi_records_read
113GET /userapi/records/conversions/{conversionId}userapi_records
userapi_records_read
114DELETE /userapi/records/{recordId}userapi_records
115PUT /userapi/records/{recordId}userapi_records
116POST /userapi/records/{recordId}/conversionsuserapi_records
117POST /userapi/records/{recordId}/shareuserapi_records
118GET /userapi/stats/eventsuserapi_statistics
119GET /userapi/stats/usersuserapi_statistics
120GET /userapi/stats/users/visitsuserapi_statistics
121POST /userapi/testsuserapi_tests
122GET /userapi/tests/listuserapi_tests
userapi_tests_read
123PUT /userapi/tests/{testId}userapi_tests
124DELETE /userapi/tests/{testId}userapi_tests
125GET /userapi/tests/{testId}userapi_tests
userapi_tests_read
126GET /userapi/tests/{testId}/customanswersuserapi_tests
userapi_tests_read
127GET /userapi/tests/{testId}/resultsuserapi_tests
userapi_tests_read
128POST /userapi/tests/{testId}/startuserapi_tests
129POST /userapi/testsessions/{testSessionId}/answersuserapi_tests
130PUT /userapi/testsessions/{testSessionId}/assessanswersuserapi_tests
131PUT /userapi/testsessions/{testSessionId}/stopuserapi_tests
132GET /userapi/timezonesuserapi_eventsuserapi_events
userapi_events_readuserapi_events_read
133GET /userapi/transcript/{transcriptId}userapi_events
userapi_events_read
134PUT /userapi/user/{userId}userapi_organization
userapi_internal_for_link_chats
135POST /userapi/users/{userId}/contactsuserapi_contacts
136GET /userapi/users/{userId}/events/scheduleuserapi_eventsuserapi_events
userapi_events_readuserapi_events_read
137GET /userapi/users/{userId}/tests/statsuserapi_tests
userapi_tests_read
138GET /userapi/webhooksuserapi_webhooks
userapi_webhooks_read
userapi_internal_for_link_chats
139POST /userapi/webhooks/createuserapi_webhooks
userapi_internal_for_link_chats
140POST /userapi/webhooks/{webhookId}/deleteuserapi_webhooks
userapi_internal_for_link_chats



5. Сценарий запроса токена

 5.1 Авторизация пользователя

Размещаете в вашем приложении кнопку "Подключить МТС Линк". При нажатии пользователя нужно перенаправить на страницу запроса доступа к данным пользователя. 

Формат ссылки: https://my.mts-link.ru/authorize?response_type=code
&client_id={clientId из шага 1}
&scope=userapi_events_read+userapi_events_write
&state={не обязательно, значение, которое вернем при обратном редиректе}

Опционально можно передать &redirect_uri=https://example-app.com/callback. Данный параметр указывает на какой url в этот раз отправить обратно, если зарегистрируете у нас более одного приложения.

После авторизации пользователя в МТС Линк и подтверждения им предоставления прав пользователь будет перенаправлен на указанный redirect_url с добавлением параметров code и state (если они его передавали).

?code={code}&state=123 

Возможные ошибки:

  • Тариф клиента не разрешает интеграцию по API

  • Приложение не разрешено для установки в данной организации

  • Приложение не найдено

5.2 Получение JWT-токена

Ваше приложение с использованием полученного code выполняет запрос для получения JWT-токена

curl --location 'https://my.mts-link.ru/api/idp/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id={clientId}' \
--data-urlencode 'client_secret={secret}' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code={code}'


Пример ответа

{

"token_type": "Bearer",    

"expires_in": 600,

"access_token": "...",

"refresh_token": "..."

}

5.3 Выполнение запросов к UserAPI от имени пользователя

Некоторые методы UserAPI поддерживают работу одновременно с разными типами ключей, но отличаются заголовки. Оба типа авторизации в API продолжат работать дальше.

  • для OAuth параметр: --header 'authorization: Bearer {access_token}'

  • для обычного API ключа: --header 'x-auth-token: {apiKey}'

Пример запроса временных зон:
curl --location --request POST 'https://userapi.mts-link.ru/v3/timezones' \ --header 'authorization: Bearer {access_token}'

где {access_token} - полученное в предыдущем пункте значение.

5.4 Актуализация токена

curl --location 'https://my.mts-link.ru/api/idp/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id={clientId}' \
--data-urlencode 'client_secret={secret}' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'refresh_token={refresh_token}'


5.5 Профиль текущего пользователя

API. Profile профиль пользователя (OAuth)

6. Управление токенами пользователей

Внутри личного кабинета МТС Линк пользователь видит список подключенных интеграций и может их удалить. При этом токен становится неактивным, все доступы приложения удаляются.

Администратор организации видит сессии пользователей и может при необходимости удалять сессии других пользователей, или запрещать приложение  с одновременным удалением сессий сразу для всех пользователей организации.

👆 На этом пока всё