Using google script urlfetchapp to update form

I am working on a file collection form.

The idea is to have a single form to collect files (from respondents) for whatever purposes my workmates have.

They are using email/google forms to accept files but that is unnecessarily cumbersome.

To make managing these forms easy, I want the people in my office to be able to categorize, add new requirements and set deadlines in the dropdown.

I will convert their inputs from a spreadsheet as choices in the xlsxform then redeploy to the published google sheet (the url that ends in .xlsx) to kobo.

I have the rest of the deployment part figured out except patching the forms in googlescript.

The curl example in the API doc and my google script

curl -X PATCH -F xls_file=@/path/to/form.xls
function patchForm() {
  var payload = "@" + " 
  var scriptProperties = PropertiesService.getScriptProperties();
  var url = "";
  var params = {
    "method" : scriptProperties.getProperties()["method"],
    "headers": {"Authorization" : scriptProperties.getProperties()["Authorization"]},
    "xls_url": payload
  UrlFetchApp.fetch(url, headers = params);


It doesnt work.

I think the problem is converting the xls_file/xls_url but IDK

Hi @mkmortera, have you managed to run through the process correctly just using the shell? I’m not familiar with Google Script, so I’ll leave that to the community to assist. You could also use an external file to manage (with either pulldata() or select_one_from_file / select_multiple_from_file) which could be simpler to maintain (if I’m understanding your requirement correctly). You can then just replace that external file rather than the form itself.

1 Like

I can, but I’d like to avoid that as much as possible. Theyd have to spend time to reach out to me every time and I have to reupload every time. That defeats the purpose. Will post here once I figure this out

Im looking at this KoBo API examples, using new KPI endpoints

Is it possible to change the xls_link instead? If so what is the curl request for changing the xls_link using the v2 api?

I wasnt able to figure out how to convert a curl request but I was able to make a what I want using Google Forms/Google Scripts.

The downside is you cant use cascade select in Google Forms but it works, files and folders are automatically shared to the one who made the request to collect files.

Hi @mkmortera, I suggested that approach as it’s potentially easier to automate rather than adding more manual work, but perhaps I’m not fully understanding your use case.

Can you clarify what you mean by:

change the xls_link

And maybe why you would want to change it.

If it’s easier to achieve your goal with Google Forms and Google Scripts together, then go for it :+1:

1 Like

in the v2 link there is an example where you can edit a form via:
curl --silent --user jnm_api:some-secret-phrase --header ‘Accept: application/json’ -X PATCH --form name=‘My New Name’

Looking at the API the xlsx file is kept in the “xls_link” with value:

I think it is possible to update the xlsx file by

modifying the curl in the sample with
curl --silent --user jnm_api:some-secret-phrase --header ‘Accept: application/json’ -X PATCH --form xls_link = “published google sheet link”

But I wasn’t able to try since I was able to may it work using google form+sheet+script

Being able to update the form/replace the choices is nice.
I would be able to create a dropdown of prior incidents (submission id/text value entered in the form) so respondents can link prior incidents to a new incident with only google script, as requested by my boss.

I think I misunderstood you, possible to replace only the external file via api?
Then use the external file as choice?
Like this?

Hi @mkmortera, ok I understand what you’re trying to do. Unfortunately it’s a bit more involved than that — the xls_link is generated internally and is not the URL-linked xlsform. There are three steps you need to follow to replace and redeploy a form:

  1. Replace the form, with a URL-linked form in your case:
curl -X POST 'http://<kf url>/api/v2/imports/' \
-F "destination=http://<kf url>/api/v2/assets/<asset uid>/" \
-F url=\?output\=xlsx \
-F "name=<project name>" \
-H "Authorization: Token <token>"
  1. Get the version_id from the asset:
curl http://<kf url>/api/v2/assets/<asset uid>.json \ 
-H "Authorization: Token <token>" \
| jq ".version_id"
  1. Redeploy the asset with the new version_id:
curl -X PATCH http://<kf urld>/api/v2/assets/<asset uid>/deployment/ \
-F active=true \
-F version_id=<version id> \
-H "Authorization: Token <token>" \
-H 'Accept: application/json'

If you are wanting to go the form media route rather than replacing the form itself, then that is the correct thread to follow. In essence: to update the media you need to delete the existing media file and then replace it with the updated one.

1 Like

The upcoming “case management” feature being released later this month may solve this issue for you without all the effort:

1 Like