Status Update
Comments
se...@google.com <se...@google.com> #2
Hello,
Can you format the description in order to make it clearer? You can use markdown to differentiate between text or scripts.
Also, from the
To receive notifications, the topic must grant publish privileges to the Forms service account serviceAccount:
forms-notifications@system.gserviceaccount.com . Only the project that owns a topic may create a watch with it.
Regards
[Deleted User] <[Deleted User]> #3
Thank you, I can't edit my original so I'm reformatting in this comment. Also, I confirmed I have added the Google-managed service account as a Principal Pub/Sub Publisher on my Pub/Sub Topic.
A short description of the issue:
Cannot create a "watch". Calling form_service.create_watch( form_id, create_watch_request_object )
errors 400 with "Project does not have necessary OAuth permissions from authorizing user.", status: FAILED_PRECONDITION.
I have torn down my setup and followed the docs again and achieved the same result.
NEW EDIT AS OF 8/15/2022 - I have also tried enabling Domain-wide Delegation of Authority (for my user-managed service account, with same drive/auth scope mentioned in below code snippet), and waited over 24 hours to ensure affect. No change in outcome when rerunning the code.
What steps will reproduce the problem?
Using Ruby on Rails console, a user-managed service account with GOOGLE_APPLICATION_CREDENTIALS env var pointing to local keyfile.json, create and batch update a form — followed by the create_watch call. The first two steps work, but the latter fails.
What is the expected output?
I expect the "watch" to be created successfully. I expect the form_service
to succeed the same way it succeeded creating and updating the form.
What do you see instead?
Sending HTTP post https://forms.googleapis.com/v1/forms/1RBaUdGd13Q4fH-93Xjddb6tAbPGoYezwJTS-r3Nmh2g/watches?
400
#<HTTP::Message:0x0000000114b063b8 @http_header=#<HTTP::Message::Headers:0x0000000114b06390 @http_version="1.1", @body_size=0, @chunked=false, @request_method="POST", @request_uri=#<Addressable::URI:0x444a8 URI:https://forms.googleapis.com/v1/forms/1RBaUdGd13Q4fH-93Xjddb6tAbPGoYezwJTS-r3Nmh2g/watches?>, @request_query=nil, @request_absolute_uri=nil, @status_code=400, @reason_phrase="Bad Request", @body_type=nil, @body_charset=nil, @body_date=nil, @body_encoding=#<Encoding:UTF-8>, @is_request=false, @header_item=[["Vary", "Origin"], ["Vary", "X-Origin"], ["Vary", "Referer"], ["Content-Type", "application/json; charset=UTF-8"], ["Content-Encoding", "gzip"], ["Date", "Fri, 12 Aug 2022 23:30:41 GMT"], ["Server", "ESF"], ["Cache-Control", "private"], ["X-XSS-Protection", "0"], ["X-Frame-Options", "SAMEORIGIN"], ["X-Content-Type-Options", "nosniff"], ["Alt-Svc", "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""], ["Transfer-Encoding", "chunked"]], @dumped=false>, @peer_cert=#<OpenSSL::X509::Certificate: subject=#<OpenSSL::X509::Name CN=upload.video.google.com>, issuer=#<OpenSSL::X509::Name CN=GTS CA 1C3,O=Google Trust Services LLC,C=US>, serial=#<OpenSSL::BN:0x0000000114b4df60>, not_before=2022-07-18 08:24:35 UTC, not_after=2022-10-10 08:24:34 UTC>, @http_body=#<HTTP::Message::Body:0x0000000114b062a0 @body="{\n \"error\": {\n \"code\": 400,\n \"message\": \"Project does not have necessary OAuth permissions from authorizing user.\",\n \"status\": \"FAILED_PRECONDITION\"\n }\n}\n", @size=0, @positions=nil, @chunk_size=nil>, @previous=nil>
Caught error Invalid request
Error - #<Google::Apis::ClientError: Invalid request status_code: 400 header: #<HTTP::Message::Headers:0x0000000114b4c9a8 @http_version="1.1", @body_size=0, @chunked=false, @request_method="POST", @request_uri=#<Addressable::URI:0x444a8 URI:https://forms.googleapis.com/v1/forms/1RBaUdGd13Q4fH-93Xjddb6tAbPGoYezwJTS-r3Nmh2g/watches?>, @request_query=nil, @request_absolute_uri=nil, @status_code=400, @reason_phrase="Bad Request", @body_type=nil, @body_charset=nil, @body_date=nil, @body_encoding=#<Encoding:UTF-8>, @is_request=false, @header_item=[["Vary", "Origin"], ["Vary", "X-Origin"], ["Vary", "Referer"], ["Content-Type", "application/json; charset=UTF-8"], ["Content-Encoding", "gzip"], ["Date", "Fri, 12 Aug 2022 23:30:41 GMT"], ["Server", "ESF"], ["Cache-Control", "private"], ["X-XSS-Protection", "0"], ["X-Frame-Options", "SAMEORIGIN"], ["X-Content-Type-Options", "nosniff"], ["Alt-Svc", "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""], ["Transfer-Encoding", "chunked"]], @dumped=false> body: "{\n \"error\": {\n \"code\": 400,\n \"message\": \"Project does not have necessary OAuth permissions from authorizing user.\",\n \"status\": \"FAILED_PRECONDITION\"\n }\n}\n">
Please provide any applicable error messages.
errors 400 with "Project does not have necessary OAuth permissions from authorizing user.", status: FAILED_PRECONDITION
If possible, provide a small code sample that reproduces the issue. The sample should run as-is or with minimal setup.
I paste this code into Rails Console to run it. The form is created and updated successfully. The "watch" fails to be created with aforementioned error.
def form_service
scopes = [ "https://www.googleapis.com/auth/drive" ]
authorizer = Google::Auth.get_application_default(scopes)
form_service = Google::Apis::FormsV1::FormsService.new
form_service.authorization = authorizer
form_service
end
# 1. Create a barebones Google Form
form_object = {
info: { title: 'Form Title' }
}
form = form_service.create_form(form_object)
# 2. Update the form with question and choices
def timezone_options
Google::Apis::FormsV1::Option.new(value: 'UTC')
end
def timezone_choice_question
Google::Apis::FormsV1::ChoiceQuestion.new(type: 'RADIO', options: [timezone_options])
end
def timezone_question
Google::Apis::FormsV1::Question.new(choice_question: timezone_choice_question)
end
def timezone_question_item
Google::Apis::FormsV1::QuestionItem.new(question: timezone_question)
end
def timezone_item
Google::Apis::FormsV1::Item.new(
title: "What's your time zone?",
question_item: timezone_question_item
)
end
def timezone_create_item_request
Google::Apis::FormsV1::CreateItemRequest.new(
item: timezone_item,
location: Google::Apis::FormsV1::Location.new(index: 0)
)
end
def batch_update_form_request_object
timezone_request_create_item = Google::Apis::FormsV1::Request.new(create_item: timezone_create_item_request)
Google::Apis::FormsV1::BatchUpdateFormRequest.new(
requests: [timezone_request_create_item],
include_form_in_response: true
)
end
batch_update_response = form_service.batch_update_form(form.form_id, batch_update_form_request_object)
# 3. Create the watch so that form submissions (responses) notify Pub/Sub
def cloud_pubsub_topic
# TODO: update with your own pubsub topic name
Google::Apis::FormsV1::CloudPubsubTopic.new(topic_name: 'projects/durable-destiny-123456/topics/some-topic')
end
def watch_target
Google::Apis::FormsV1::WatchTarget.new(topic: cloud_pubsub_topic)
end
def watch
Google::Apis::FormsV1::Watch.new(event_type: 'RESPONSES', target: watch_target)
end
def create_watch_request_object
Google::Apis::FormsV1::CreateWatchRequest.new(watch: watch)
end
watch_response = form_service.create_watch( form.form_id, create_watch_request_object )
se...@google.com <se...@google.com> #4
[Deleted User] <[Deleted User]> #5
Yes, please see attached screenshot. Also, I had mentioned that I am able to create and update the form, so I assume I can only do that having the Google Forms API enabled.
The problem arises when I try to create the "watch". What else can I do to help you assess this issue?
se...@google.com <se...@google.com> #6
Hi,
Thank you for the answer.
I am trying to reproduce this and will come back as soon as possible.
Regards.
[Deleted User] <[Deleted User]> #7
Thank you for researching this problem. Let me know if I can provide any extra information and I will be happy to provide.
[Deleted User] <[Deleted User]> #8
It is over a week you have responded, that is not good and should not be so. It won't take you more than a day to replicate this this issue. This issue was reported on the 13th of August, in 4 days it'll be a month. You can't release an API and act lackadaisical with support when it is not working well. Please do better and respond faster
se...@google.com <se...@google.com> #9
Hello,
Apologies for the delay, we are still investigating this behavior, will update as soon as possible.
Regards.
se...@google.com <se...@google.com> #10
Hi,
I have been able to reproduce this behavior and I have forwarded it internally.
Regards.
ag...@gmail.com <ag...@gmail.com> #11
zh...@trimble.com <zh...@trimble.com> #12
I am experiencing the same exact problem with my service account.
Shall we ask for an update on this?
Thanks.
zh...@trimble.com <zh...@trimble.com> #13
zh...@trimble.com <zh...@trimble.com> #14
sh...@gmail.com <sh...@gmail.com> #15
is...@google.com <is...@google.com>
de...@oxfordlock.org <de...@oxfordlock.org> #16
co...@gmail.com <co...@gmail.com> #17
I am also facing the same issue with Python 3.7 and using Service Account credentials.
Thanks.
jp...@google.com <jp...@google.com>
co...@gmail.com <co...@gmail.com> #18
ta...@gmail.com <ta...@gmail.com> #19
mb...@gmail.com <mb...@gmail.com> #20
su...@verkada.com <su...@verkada.com> #21
se...@gmail.com <se...@gmail.com> #22
mb...@gmail.com <mb...@gmail.com> #23
cl...@gmail.com <cl...@gmail.com> #24
no...@atos.net <no...@atos.net> #25
"The solution we opted for was to create an endpoint that can be manually triggered, we would plan for a cron job to be setup in the prod environment that would call this endpoint repeatedly after a set interval. This also allows us to manually decide when to trigger processing of new reviews in tests"
ar...@deliveryhero.com <ar...@deliveryhero.com> #26
[Deleted User] <[Deleted User]> #27
ai...@gmail.com <ai...@gmail.com> #28
ai...@gmail.com <ai...@gmail.com> #29
we...@skywarder.eu <we...@skywarder.eu> #30
If I'm missing something please tell me.
ed...@gmail.com <ed...@gmail.com> #31
Thanks in advance.
Description
First, check the existing issues to ensure that the bug has not been reported:
If the issue has already been reported, click the star next to the issue number to receive updates. We prioritize issues with the most stars. Add comments to the issue if you have further details.
If your issue has not been reported, please provide:
-----------------------------------------------------------------------------------------------------------------------------
A short description of the issue:
Cannot create a "watch". Calling `form_service.create_watch( form_id, create_watch_request_object )` errors 400 with "Project does not have necessary OAuth permissions from authorizing user.", status: FAILED_PRECONDITION.
I have torn down my setup and followed the docs again and achieved the same result.
What steps will reproduce the problem?
Using Ruby on Rails console, a user-managed service account with GOOGLE_APPLICATION_CREDENTIALS env var pointing to local keyfile.json, create and batch update a form — followed by the create_watch call. The first two steps work, but the latter fails.
What is the expected output?
I expect the "watch" to be created successfully. I expect the form_service to succeed the same way it succeeded creating and updating the form.
What do you see instead?
Sending HTTP post
400
#<HTTP::Message:0x0000000114b063b8 @http_header=#<HTTP::Message::Headers:0x0000000114b06390 @http_version="1.1", @body_size=0, @chunked=false, @request_method="POST", @request_uri=#<Addressable::URI:0x444a8 URI:
Caught error Invalid request
Error - #<Google::Apis::ClientError: Invalid request status_code: 400 header: #<HTTP::Message::Headers:0x0000000114b4c9a8 @http_version="1.1", @body_size=0, @chunked=false, @request_method="POST", @request_uri=#<Addressable::URI:0x444a8 URI:
Please provide any applicable error messages.
errors 400 with "Project does not have necessary OAuth permissions from authorizing user.", status: FAILED_PRECONDITION
If possible, provide a small code sample that reproduces the issue. The sample should run as-is or with minimal setup.
def form_service
scopes = [ "
authorizer = Google::Auth.get_application_default(scopes)
form_service = Google::Apis::FormsV1::FormsService.new
form_service.authorization = authorizer
form_service
end
# 1. Create a barebones Google Form
form_object = {
info: { title: 'Form Title' }
}
form = form_service.create_form(form_object)
# 2. Update the form with question and choices
def timezone_options
Google::Apis::FormsV1::Option.new(value: 'UTC')
end
def timezone_choice_question
Google::Apis::FormsV1::ChoiceQuestion.new(type: 'RADIO', options: [timezone_options])
end
def timezone_question
Google::Apis::FormsV1::Question.new(choice_question: timezone_choice_question)
end
def timezone_question_item
Google::Apis::FormsV1::QuestionItem.new(question: timezone_question)
end
def timezone_item
Google::Apis::FormsV1::Item.new(
title: "What's your time zone?",
question_item: timezone_question_item
)
end
def timezone_create_item_request
Google::Apis::FormsV1::CreateItemRequest.new(
item: timezone_item,
location: Google::Apis::FormsV1::Location.new(index: 0)
)
end
def batch_update_form_request_object
timezone_request_create_item = Google::Apis::FormsV1::Request.new(create_item: timezone_create_item_request)
Google::Apis::FormsV1::BatchUpdateFormRequest.new(
requests: [timezone_request_create_item],
include_form_in_response: true
)
end
batch_update_response = form_service.batch_update_form(form.form_id, batch_update_form_request_object)
# 3. Create the watch so that form submissions (responses) notify Pub/Sub, which will push a message to my endpoint
def cloud_pubsub_topic
Google::Apis::FormsV1::CloudPubsubTopic.new(topic_name: 'projects/durable-destiny-123456/topics/some-topic') # TODO: update with your own pubsub topic name
end
def watch_target
Google::Apis::FormsV1::WatchTarget.new(topic: cloud_pubsub_topic)
end
def watch
Google::Apis::FormsV1::Watch.new(event_type: 'RESPONSES', target: watch_target)
end
def create_watch_request_object
Google::Apis::FormsV1::CreateWatchRequest.new(watch: watch)
end
watch_response = form_service.create_watch( form.form_id, create_watch_request_object )