Migrating an Apps Script Console to Go: Contracts and State

한국어로 읽기

TECH INSIGHT / EXPLAINED

Migrating an Apps Script web console to Go is a contract and operations project. First preserve what the browser sends and receives, then move long-running work behind that interface. The design below is a worked migration plan rather than a claim about a particular production deployment.

Three adult colleagues explain apps script go
AI-generated teaching illustration, not an actual operating screen or performance record.

Local execution of the actual project

These captures show the existing project UI or functions executed locally with non-private sample inputs. Each caption states the scope of the execution.

The original OnStockBot GAS-console HTML running locally. Only getParameters is replaced with sample data; the bot stays OFF. This is not a live Apps Script deployment, broker response, or order execution.
The original OnStockBot GAS-console HTML running locally. Only getParameters is replaced with sample data; the bot stays OFF. This is not a live Apps Script deployment, broker response, or order execution.
A local test error passed to the original GAS console’s getParameters failure callback. The bottom log records the settings-read error and the bot remains OFF. This checks a failure-display path to preserve during migration; it is not a real server incident or failed order.
A local test error passed to the original GAS console’s getParameters failure callback. The bottom log records the settings-read error and the bot remains OFF. This checks a failure-display path to preserve during migration; it is not a real server incident or failed order.

Choose the move for the actual constraint

Apps Script has execution and service quotas; verify the limits for the account and trigger type instead of assuming every trigger has the same six-minute rule. It provides LockService for concurrency control, PropertiesService for persisted values, and clasp for local development. Go is useful when an owned long-lived process and explicit I/O scheduling fit the task, but brings hosting, patching and authentication responsibilities.

Record a request/response contract

Keep action names only if their semantics still match. Preserve status codes, field types, null/error behavior, dates and authorization rules as well. A browser calling google.script.run needs a transport adapter; matching action names alone cannot keep it unchanged. Example contract:

POST /api {"action":"startBot","request_id":"start-17"}
200 {"ok":true,"data":{"state":"running","generation":8}}
POST /api {"action":"startBot","request_id":"start-17"}
200 {"ok":true,"data":{"state":"running","generation":8}}

Make start and stop idempotent

Under a lifecycle lock, check STOPPED before creating a runner; set STARTING and its generation, create context/cancel, then start exactly one worker. Repeated starts return the existing state. A stop request cancels that generation and waits for its done signal; only the matching generation may mark STOPPED. Cancellation is cooperative. Without a state check, two start requests can create two loops while overwriting the only cancel function.

Shadow the reads before switching writes

Replay recorded sanitized requests against both implementations and compare normalized responses. Move read-only routes first, then one write action with an idempotency key. Keep a rollback plan that prevents both old and new schedulers from executing actions simultaneously. Persist state in a chosen store and reconcile external effects after restart; in-memory state is convenient but disappears in a crash. Build Go for the target OS/architecture and verify any cgo/runtime dependencies rather than promise one binary runs everywhere.

Documentation and next steps

Content and examples reviewed: 2026-09-29

댓글