Мы хотим разместить часы на учетной записи Gmail, доступ к которой нам предоставлен.
(см. также https://developers.google.com/gmail/api/v1/reference/users/watch).
Для размещения часов требуется название темы PUB / SUB, которое у нас есть: projects/project-name/topics/topic-name
.
При создании этого мы устанавливаем права на публикацию для члена allAuthenticatedUsers
(предоставляет доступ любому пользователю, вошедшему в учетную запись Google).
Это работает, и мы можем получать уведомления о просмотре в теме и правильно использовать сообщения.
Теперь мы бы хотели еще больше ограничить права на публикацию, разрешив делать это только учетной записи службы.
Мы создали учетную запись службы (gmail-watch@project-name.iam.gserviceaccount.com
) и установили ее в качестве единственного издателя для этой темы.
Эта учетная запись службы также была настроена с ролью Pub/Sub Publisher
в IAM.
Теперь, когда мы вносим это изменение в код и пробуем его, мы получаем ошибку:
Google::Apis::ClientError (failedPrecondition: Bad Request)
Это код, fwiw:
require 'googleauth'
require 'google/apis/gmail_v1'
scope = 'https://mail.google.com/'
authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io: File.open('./config/google-service-account.json'),
scope: scope
)
Gmail = ::Google::Apis::GmailV1
service = Gmail::GmailService.new
service.authorization = authorizer
service.watch_user(
'user-email@gmail.com',
{
topic_name: 'projects/project-name/topics/topic-name',
label_ids: ['INBOX','SENT'],
label_filter_action: 'include'
},
{}
)
Мы также попытались установить параметр sub
в авторизации:
authorizer.sub = 'user-mail@gmail.com'
но ошибка та же, хотя после этого мы больше не можем получить токены доступа:
> authorizer.fetch_access_token!
Signet::AuthorizationError (Authorization failed. Server message:)
{
"error": "unauthorized_client",
"error_description": "Client is unauthorized to retrieve access tokens using this method."
}
Чего нам здесь не хватает?