Hebrew Survey Builder
Problem
Running surveys in Hebrew is painful. Google Forms renders Hebrew text right-to-left automatically, but the hard part is choosing the right questions, phrasing them in natural Israeli Hebrew (not stiff literal translations from English), and actually creating the form without clicking through the UI. Most teams default to bad English templates run through Google Translate, which tank response rates.
This skill lets an agent build a complete Hebrew survey end-to-end using gws forms forms create + gws forms forms batchUpdate, returning a live, shareable form URL within a single prompt.
Instructions
Step 0: Decide if Google Forms is the right target
Start by asking which tool the user wants the survey deployed on:
- Google Forms, use the
gwsflow below (Steps 1-9). Produces a live, shareable URL. - No shell available (Claude Desktop, and any host that cannot run a local binary), take the same route as the non-Google platforms below:
gwsis a CLI, so the Google Forms deployment path is unavailable there by construction. Produce the Hebrew templates and the timing plan, and hand the user paste-ready content. - Typeform, SurveyMonkey, Tally, Microsoft Forms, email, Slack, WhatsApp, skip the
gwssteps. Go straight to Step 1 (pick template), then jump toreferences/export-to-other-platforms.mdfor per-tool paste-in instructions. The Hebrew question wording and Israeli timing rules apply regardless of platform.
If the user is deploying to Google Forms, confirm the gws CLI is installed and authenticated. These are two different checks:
gws forms --help # installed? prints usage
gws drive files list --params '{"pageSize": 1}' # authenticated? needs real credentials
--help exits 0 with no credentials at all, so on its own it proves nothing about auth. Skipping the second command is the most common way this flow dies at Step 2 with an auth error instead of at Step 0 with a clear one.
Command shape is gws <service> <resource> [sub-resource] <method>, so the forms resource inside the forms service is addressed as gws forms forms <method>. The doubled word is not a typo.
If the command is not found, tell the user to install the Google Workspace CLI from github.com/googleworkspace/cli (a pre-built binary, or via a package manager such as npm, Homebrew, or cargo, see the repo's install section for the current commands) and authenticate it. Do not attempt to fabricate a response. Do not use a different CLI. If the user does not want to install gws, offer to generate the templates in Markdown and point them to references/export-to-other-platforms.md instead.
Step 1: Pick the survey template
Ask the user which kind of survey they need. Map their intent to one of these templates in references/hebrew-survey-templates.md:
| Template | When to use | Scale |
|---|---|---|
nps |
Measure Israeli customer loyalty | 0-10 |
csat |
Rate a single interaction / order / support ticket | 1-5 |
ces |
Measure effort of a task (e.g. sign-up, checkout) | 1-7 |
event-feedback |
Post-event debrief (meetups, workshops, webinars) | mixed |
product-discovery |
Early-stage user interviews about a pain point | open-ended |
market-research |
Demand validation for a new Israeli product | mixed |
If the user's intent doesn't fit cleanly, ask one clarifying question. Don't force a template that doesn't match.
Step 2: Create the empty form
The create method only accepts the form title and document_title, per the Google Forms API. All other fields (description, items, settings) must be added in a separate batchUpdate call. This is a hard constraint, do not try to pass items at creation time.
gws forms forms create --json '{
"info": {
"title": "סקר NPS - <company name>",
"documentTitle": "NPS Survey <date>"
}
}'
Capture the formId from the response. You need it for every following call.
The documentTitle is the filename as it appears in Google Drive. Keep it ASCII so the file is easy to find in Drive; put the Hebrew in title (the title users see on the form itself).
Step 3: Add questions via batchUpdate
Use forms.batchUpdate with a requests array. Each question is a createItem request. To inspect the exact parameter shape first:
gws schema forms.forms.batchUpdate
Build the payload from the template you chose in Step 1. Example for a 2-question NPS form:
gws forms forms batchUpdate --params '{"formId": "<FORM_ID>"}' --json '{
"requests": [
{
"createItem": {
"item": {
"title": "עד כמה סביר שתמליצו עלינו לחבר או קולגה?",
"questionItem": {
"question": {
"required": true,
"scaleQuestion": {
"low": 0,
"high": 10,
"lowLabel": "בכלל לא סביר",
"highLabel": "בהחלט סביר"
}
}
}
},
"location": { "index": 0 }
}
},
{
"createItem": {
"item": {
"title": "מה הסיבה המרכזית לציון שנתתם?",
"questionItem": {
"question": {
"required": false,
"textQuestion": { "paragraph": true }
}
}
},
"location": { "index": 1 }
}
}
]
}'
location.index is the zero-based position of the item in the form. Always set it, even for a single-item insert, the API rejects the request otherwise.
Step 4: Write the intro and consent text into the form
create disallows description, so the anonymity line or the fuller notice has to be set here, in the same batchUpdate pass as the questions. If you skip this the form has no intro at all, and the consent obligations in Step 8 have no delivery path.
gws forms forms batchUpdate --params '{"formId": "<FORM_ID>"}' --json '{
"requests": [
{
"updateFormInfo": {
"info": { "description": "התשובות בסקר הזה אנונימיות ולא נאספים בו פרטים מזהים." },
"updateMask": "description"
}
}
]
}'
The bundled script does this for you: --intro anonymous writes the anonymity line, and --intro identified writes your --notice text AND prepends a required consent item at index 0, which is where Step 8 requires it to sit. Decide anonymous-vs-identifiable now, before the form is published, not after.
Step 5: Get the share URL
Fetch the form metadata and return the responderUri to the user:
gws forms forms get --params '{"formId": "<FORM_ID>"}'
The responderUri field is the URL to share with respondents. It does not work until the form is published; see Step 6. This is what the user actually wants, lead with it in your reply. Also include the formId so the user can re-open the form in the Forms UI later.
Step 6: Publish the form (MANDATORY since 30 June 2026)
A form created through the API no longer accepts responses until you publish it. Google changed the default: "forms created by the API after June 30, 2026 will be created in an unpublished state. You must publish the forms before they can accept responses", and "If no action is taken, then new forms created using APIs after June 30, 2026, will be in an unpublished state by default and won't receive responses."
This is the single most likely way to hand a user a dead survey. The form opens, looks correct, and silently collects nothing. Do not skip this step and do not treat it as optional polish.
# Inspect the exact publishSettings shape first
gws schema forms.forms.setPublishSettings
gws forms forms setPublishSettings \
--params '{"formId": "<FORM_ID>"}' \
--json '{"publishSettings": {"publishState": {"isPublished": true, "isAcceptingResponses": true}}, "updateMask": "publishState"}'
Then re-run gws forms forms get and confirm the publish state before you hand over the responderUri. Publish first, hand over the link second: the order is what stops you shipping a dead survey.
Two related notes:
- Legacy forms (created before the publishing model existed) do not support
publishSettingsat all, because they have no such field. Forms you create through the API do. - To restrict who can respond rather than sharing an open link, share the form with specific users via the Drive API's
permissions.create. That is a separate call, not apublishSettingsflag.
Step 7: Guide Sheets linking (UI step, not API)
The Google Forms API does not currently expose a method to connect a form's responses to a specific Google Sheet. This must be done once in the UI:
- Open the form in the Forms editor (the URL comes back from
gws forms forms get; copy theformIdinto the browser-side Forms UI, or open it from Drive). - Click the Responses tab.
- Click the green Sheets icon → Create a new spreadsheet (or select an existing one).
Tell the user this is a one-time click, and that after it's done, every new response will land in the linked Sheet automatically. Do not claim the skill handles this step.
If the user wants API-level response access instead, use gws forms forms responses list --params '{"formId": "<FORM_ID>"}' to pull responses and pipe them into gws sheets yourself.
Step 8: Pick the right send time for Israeli audiences
A perfectly worded survey sent at the wrong time tanks your response rate. Before you push the form, think about when it will land in people's inboxes:
- Avoid Friday afternoon and Shabbat. Observant recipients are offline; by Sunday it's buried.
- Avoid chag weeks entirely, Sukkot, Pesach, Rosh Hashanah, Yom Kippur period, Shavuot, Yom HaZikaron/Yom HaAtzmaut. Response rates collapse during these weeks.
- Best days: Sunday (fresh inboxes), Tuesday-Wednesday (strongest B2B engagement). Thursday is acceptable but drifts softer late in the day.
- Best hours: 09:00-11:00 morning window, 13:00-14:00 post-lunch lull. Avoid before 08:30 or after 20:00.
- Transactional surveys (post-ticket CSAT, post-event feedback) should fire immediately after the interaction, not on a batch schedule, but still hold them for Sunday morning if the event ended Thursday evening.
The full decision tree and per-survey-type cadence (NPS quarterly vs monthly, CSAT per-ticket vs batched, etc.) is in references/israeli-send-timing.md. Consult it before committing to a cadence.
Step 9: Share, and check consent before you send
Once Step 5 has published the form, the responder link works for anyone who has it, within the creator's Google account rules (Workspace domain restrictions still apply).
Consent and privacy. Keep NPS, CSAT, and CES responses anonymous by default, it both protects respondents and lifts response rates. Israeli law has required informed consent (הסכמה מדעת) for identifiable personal data since long before the recent reform. What Amendment 13 (in force 14 August 2025) changed here is mainly the notice you owe the respondent: who the controller is and how to reach them, what happens if they refuse, and their right to access and correct their data. So before you share the form, check whether it is actually anonymous, not just anonymous-looking:
- A form with no identifying field can still be identifiable. Emailing a personalized survey link to a customer list, or pre-filling a respondent token, re-identifies every answer even if the form asks for no name or email. Treat that flow as identifiable: tell recipients what you collect and why, give an opt-out, and don't reuse the list beyond this survey.
- Turn off "Collect email addresses" for anonymous external surveys. Inside a Google Workspace domain, Google Forms can auto-capture the respondent's account email, which silently breaks an "anonymous" promise. Disable it unless you actually need identity.
- Watch small samples. A segment question (עצמאי / שכיר / בעל עסק) plus a free-text comment on a small list (a meetup, a niche B2B audience) re-identifies people. Don't cross-tab or report segments with only a handful of responses.
- If you do need identity (e.g. a follow-up-contact NPS), add a leading required consent item ("אני מאשר/ת שאפשר ליצור איתי קשר בעקבות התשובות") before any identifying field, and never pre-tick it.
For a genuinely anonymous survey, a one-line intro ("התשובות אנונימיות" / "Responses are anonymous") is enough. For the identifiable flows above, give the fuller notice (what you collect, why, and an opt-out) rather than a single line. For forms that gather sensitive or government data, defer to israeli-gov-form-automator.
Recommended MCP Servers
| MCP | When to pair |
|---|---|
| None at time of writing | No Hebrew-survey or Google Forms MCP is published on skills-il yet. Use gws CLI directly. |
Reference Links
| Source | URL | What to check |
|---|---|---|
| Google Workspace CLI repo | https://github.com/googleworkspace/cli | Install instructions, release notes, auth flow |
| Official gws-forms skill | https://raw.githubusercontent.com/googleworkspace/cli/main/skills/gws-forms/SKILL.md | Canonical list of gws forms methods and constraints |
| Google Forms API v1 reference | https://developers.google.com/workspace/forms/api/reference/rest/v1/forms | Authoritative method list (create, get, batchUpdate, setPublishSettings) |
| Forms batchUpdate reference | https://developers.google.com/workspace/forms/api/reference/rest/v1/forms/batchUpdate | Request types (CreateItemRequest, UpdateItemRequest, etc.) |
| API changes to Google Forms | https://developers.google.com/workspace/forms/api/guides/api-changes-to-google-forms | The unpublished-by-default change and the publishing flow |
| gws shared conventions | https://raw.githubusercontent.com/googleworkspace/cli/main/skills/gws-shared/SKILL.md | Command shape and the JSON form of --params |
| Hebrew survey templates (local) | references/hebrew-survey-templates.md |
NPS, CSAT, CES, event, product discovery wording |
| Israeli send-time guide (local) | references/israeli-send-timing.md |
Day/hour guidance, chag weeks to avoid, cadence rules |
| Export to non-Google platforms (local) | references/export-to-other-platforms.md |
How to paste the Hebrew templates into Typeform, SurveyMonkey, Tally, Microsoft Forms, email/Slack |
Bundled Resources
Scripts
scripts/build_batchupdate_payload.py, take a template name (nps,csat,ces,event-feedback,product-discovery,market-research) and emit a ready-to-pipe JSON payload forgws forms forms batchUpdate --json.python3 scripts/build_batchupdate_payload.py --template nps --intro anonymous python3 scripts/build_batchupdate_payload.py --template product-discovery --topic 'ניהול הוצאות בעסק קטן' python3 scripts/build_batchupdate_payload.py --template event-feedback --sessions 'פתיחה,הרצאת אורח,פאנל' python3 scripts/build_batchupdate_payload.py --template ces --task 'את ההרשמה'--topicand--sessionsare required for their templates and the script exits non-zero without them. That is deliberate: those two templates have a slot in the respondent-facing question text, and a generic filler ("the problem we are researching", "the first part") produces a question nobody can answer meaningfully.--taskis optional but naming the task makes CES usable.--intro anonymous|identifiedsets the form description, andidentifiedalso prepends the required consent item at index 0.
References
references/hebrew-survey-templates.md, every template's question list in natural Israeli Hebrew, with scale labels, question types, and notes on when each template is appropriate.references/gws-forms-cheatsheet.md, the exact gws forms methods, command structure, and discovery commands, mirrored from the upstreamgws-formsskill so you can work offline.references/israeli-send-timing.md, when to send surveys to Israeli audiences (day of week, time of day, chag weeks to avoid, per-survey-type cadence rules).references/export-to-other-platforms.md, how to use the same Hebrew templates and timing rules with Typeform, SurveyMonkey, Tally, Microsoft Forms, or plain email/Slack when Google Forms is not the right tool.
Gotchas
These are the mistakes an agent will most likely make on first try:
- Trying to pass items at
createtime. Thecreatemethod only copiesinfo.titleandinfo.documentTitle. Everything else (description, items, settings) is disallowed. Upstream says only that these fields are disallowed, not whether they are dropped or rejected, so do not assume either: read the response rather than branching on an error that may never arrive, and confirm the created form is empty before youbatchUpdateinto it. - Calling
forms.updateinstead offorms.batchUpdate. Google Forms API v1 does NOT have aforms.updatemethod. The only methods on the forms resource arecreate,get,batchUpdate, andsetPublishSettings. If you seeupdatein older docs or blog posts, substitutebatchUpdate. - Assuming the API links responses to a Google Sheet. It doesn't. The "Link to Sheets" button is UI-only. Tell the user to do it once by hand, or poll
forms.responses.listand write to a Sheet yourself viagws sheets. - Translating English NPS phrasing literally. "How likely are you to recommend us to a friend or colleague?" translated word-for-word sounds stiff and passive in Hebrew. Use the wording in
references/hebrew-survey-templates.md, it was written in Hebrew first, not translated. This is the main reason bad surveys get bad response rates in Israel. - Forgetting
location.indexin acreateItemrequest. Even for a single-question insert,location.indexis required. Start at0and increment. - Handing over the
responderUriwithout publishing. Since 30 June 2026 an API-created form starts unpublished and accepts no responses. The link resolves, the form renders, and every submission is silently impossible. Always runsetPublishSettings(Step 6) before you give the user the link. - Writing
--params formId=<ID>. The--paramsflag takes a JSON object, notkey=value:--params '{"formId": "<ID>"}'. The CLI parses it strictly and rejects anything else. - Dropping the resource token. The command is
gws forms forms create, notgws forms create. The pattern isgws <service> <resource> <method>, and here both the service and the resource are calledforms. The same doubling shows up ingws schema forms.forms.batchUpdate, which the skill has always had right. - Using Hebrew in
documentTitle.documentTitleis the Drive filename. Some Drive search flows handle Hebrew filenames awkwardly, keepdocumentTitlein ASCII, put the Hebrew version ininfo.title(the user-facing form title).
Examples
Example 1: Quick NPS for an Israeli SaaS
User says: "אני צריך להפיץ NPS ללקוחות שלי, אפשר לבנות לי סקר?"
Actions:
- Pick the
npstemplate. gws forms forms createwith title "סקר NPS - ".gws forms forms batchUpdatewith the 2-question NPS payload fromreferences/hebrew-survey-templates.md.gws forms forms setPublishSettingsto publish (mandatory), thengws forms forms get→ return theresponderUri.- Tell the user how to link to Sheets in one click if they want responses in a spreadsheet.
Example 2: Post-event feedback for a meetup
User says: "Build a post-event survey in Hebrew for yesterday's Tel Aviv meetup, 5 questions max, include one about whether they'd come again."
Actions:
- Pick the
event-feedbacktemplate. - Trim it to 5 questions, keep "האם תחזרו למפגש הבא?" as the last question.
create+batchUpdate+setPublishSettings.- Return the share link.
Troubleshooting
Error: gws: command not found
Cause: Google Workspace CLI is not installed on PATH.
Solution: Install from https://github.com/googleworkspace/cli (download the pre-built binary for your OS, or use a package manager such as npm, Homebrew, or cargo, see the repo's install section), then re-authenticate. Do not attempt to substitute another CLI or curl the REST API directly unless the user explicitly asks.
Error: INVALID_ARGUMENT on gws forms forms create when passing items
Cause: create rejects everything except info.title and info.documentTitle.
Solution: Remove items, description, and settings from the create payload. Add them afterwards via batchUpdate.
Error: CreateItemRequest.location.index is required
Cause: The createItem request was missing location or location.index.
Solution: Always include "location": { "index": <number> } even for a single-item insert.
Error: forms.update not found
Cause: Calling a method that doesn't exist in the Google Forms API v1.
Solution: Use forms.batchUpdate with an updateItem request inside the requests array, not forms.update.
Error: an auth / permission failure on the first create
Cause: gws is installed but not authenticated, or is authenticated without the Forms and Drive scopes.
Solution: re-run the gws auth flow and grant Forms and Drive access, then re-check with gws drive files list --params '{"pageSize": 1}' before retrying Step 2.
The form link works but no responses ever arrive
Cause: the form was created through the API after 30 June 2026 and was never published, so it is not accepting responses.
Solution: run gws forms forms setPublishSettings (Step 6), then confirm with gws forms forms get before re-sharing the link.
Error: Invalid --params JSON
Cause: --params was given key=value instead of a JSON object.
Solution: --params '{"formId": "<ID>"}'. Wrap in single quotes so the shell leaves the inner double quotes alone.
Hebrew text appears left-to-right in the created form
Cause: Very rarely, a title that starts with an ASCII character will direct the paragraph LTR even though the body is Hebrew.
Solution: Put Hebrew first in title (no leading punctuation or number). Google Forms infers direction from the first strong character.