Sample workflows

This page provides sample workflow definitions to help you understand the Workflows syntax and its common usage patterns.

Authentication

For all samples that communicate with other Google Cloud resources, your workflow must be associated with a service account that has sufficient privileges to access those resources. To learn more about granting roles to service accounts, see granting, changing, and revoking access to resources. To learn how to change the service account associated with a workflow, see updating a workflow. For more information about authentication, see making authenticated requests from within a workflow.

HTTP requests

These samples demonstrate making HTTP requests.

Making an external HTTP POST request

This sample makes a POST request to an external HTTP endpoint.

YAML

- getMessage:
    call: http.post
    args:
      url: https://www.example.com/endpoint
      body:
        someVal: "Hello World"
        anotherVal: 123
    result: theMessage
- returnValue:
    return: ${theMessage.body}

JSON

[
  {
    "getMessage": {
      "call": "http.post",
      "args": {
        "url": "https://www.example.com/endpoint",
        "body": {
          "someVal": "Hello World",
          "anotherVal": 123
        }
      },
      "result": "theMessage"
    }
  },
  {
    "returnValue": {
      "return": "${theMessage.body}"
    }
  }
]

Making an external HTTP GET request with headers

This sample makes an HTTP GET request with a custom header. You can also supply custom header definitions when making other types of HTTP requests.

YAML

- getMessage:
    call: http.get
    args:
      url: https://www.example.com/endpoint
      headers:
        Content-Type: "text/plain"
      query:
        someVal: "Hello World"
        anotherVal: 123
    result: theMessage
- returnValue:
    return: ${theMessage.body}

JSON

[
  {
    "getMessage": {
      "call": "http.get",
      "args": {
        "url": "https://www.example.com/endpoint",
        "headers": {
          "Content-Type": "text/plain"
        },
        "query": {
          "someVal": "Hello World",
          "anotherVal": 123
        }
      },
      "result": "theMessage"
    }
  },
  {
    "returnValue": {
      "return": "${theMessage.body}"
    }
  }
]

Variables, expressions, and runtime arguments

These samples demonstrate assigning values to variables, evaluating expressions, and accessing runtime arguments.

Assigning variables

This sample assigns string and number values to variables. Variable assignments are executed sequentially.

YAML

- firstStep:
    assign:
      - SomeName: "Sherlock"
      - AnotherName: "Ada"
      - SomeIntegerNumber: 27
      - SomeDoubleNumber: 4.1

JSON

[
  {
    "firstStep": {
      "assign": [
        {
          "SomeName": "Sherlock"
        },
        {
          "AnotherName": "Ada"
        },
        {
          "SomeIntegerNumber": 27
        },
        {
          "SomeDoubleNumber": 4.1
        }
      ]
    }
  }
]

Evaluating an expression with type casting

This sample uses an expression to assign the value of a variable. The FullName variable uses the LastName variable defined above it.

YAML

- getMessage:
    assign:
      - name: "Harsha"
      - lastName: "Kapoor"
      - fullName: ${name+" "+lastName}
      - temperatureC: 27
      - temperatureF: ${temperatureC * 9/5 + 32}
      - temperatureMsg: ${"Current temperature is "+string(temperatureF)+" F"}
- returnValue:
    return: ${temperatureMsg}

JSON

[
  {
    "getMessage": {
      "assign": [
        {
          "name": "Harsha"
        },
        {
          "lastName": "Kapoor"
        },
        {
          "fullName": "${name+\" \"+lastName}"
        },
        {
          "temperatureC": 27
        },
        {
          "temperatureF": "${temperatureC * 9/5 + 32}"
        },
        {
          "temperatureMsg": "${\"Current temperature is \"+string(temperatureF)+\" F\"}"
        }
      ]
    }
  },
  {
    "returnValue": {
      "return": "${temperatureMsg}"
    }
  }
]

Accessing runtime arguments

This sample accesses runtime arguments passed to the workflow as part of the execution request. All arguments are stored in the same dictionary, declared as a parameter of the main workflow.

When running this workflow, pass in runtime arguments using the following format:

{"firstName":"Sherlock", "lastName":"Holmes"}

YAML

main:
  params: [args]
  steps:
  - step1:
      assign:
        - outputVar: ${"Hello " + args.firstName + " " + args.lastName}
  - step2:
      return: ${outputVar}

JSON

{
  "main": {
    "params": [
      "args"
    ],
    "steps": [
      {
        "step1": {
          "assign": [
            {
              "outputVar": "${\"Hello \" + args.firstName + \" \" + args.lastName}"
            }
          ]
        }
      },
      {
        "step2": {
          "return": "${outputVar}"
        }
      }
    ]
  }
}

Declaring a dictionary and an array

This sample defines both a dictionary and a few arrays. Array definitions can be made inline using square brackets or as a list with one item per line.

YAML

- firstStep:
    assign:
      - myDictionary:
          name: Lila
          lastName: Barton
          birthYear: 1990
      - myArray1: [1, 2, 3]
      - myArray2:
          - 1
          - 2
          - 3
      - myArray3: ["Grzegorz", "Irina", "Yufei"]

JSON

[
  {
    "firstStep": {
      "assign": [
        {
          "myDictionary": {
            "name": "Lila",
            "lastName": "Barton",
            "birthYear": 1990
          }
        },
        {
          "myArray1": [
            1,
            2,
            3
          ]
        },
        {
          "myArray2": [
            1,
            2,
            3
          ]
        },
        {
          "myArray3": [
            "Grzegorz",
            "Irina",
            "Yufei"
          ]
        }
      ]
    }
  }
]

Iterating through an array

This sample iterates through an array of strings and concatenates them together. This workflow definition can be modified to process other arrays.

YAML

- define:
    assign:
      - array: ["foo", "ba", "r"]
      - result: ""
      - i: 0
- check_condition:
    switch:
      - condition: ${len(array) > i}
        next: iterate
    next: exit_loop
- iterate:
    assign:
      - result: ${result + array[i]}
      - i: ${i+1}
    next: check_condition
- exit_loop:
    return:
        concat_result: ${result}

JSON

[
  {
    "define": {
      "assign": [
        {
          "array": [
            "foo",
            "ba",
            "r"
          ]
        },
        {
          "result": ""
        },
        {
          "i": 0
        }
      ]
    }
  },
  {
    "check_condition": {
      "switch": [
        {
          "condition": "${len(array) > i}",
          "next": "iterate"
        }
      ],
      "next": "exit_loop"
    }
  },
  {
    "iterate": {
      "assign": [
        {
          "result": "${result + array[i]}"
        },
        {
          "i": "${i+1}"
        }
      ],
      "next": "check_condition"
    }
  },
  {
    "exit_loop": {
      "return": {
        "concat_result": "${result}"
      }
    }
  }
]

Step order

Implicit step ordering

This sample shows implicit step ordering within a workflow. By default, the steps of a workflow are executed in the order they appear in the workflow definition.

YAML

- firstStep:
    call: http.get
    args:
      url: https://www.example.com/callA
- secondStep:
    call: http.get
    args:
      url: https://www.example.com/callB
- thirdStep:
    call: http.get
    args:
      url: https://www.example.com/callC

JSON

[
  {
    "firstStep": {
      "call": "http.get",
      "args": {
        "url": "https://www.example.com/callA"
      }
    }
  },
  {
    "secondStep": {
      "call": "http.get",
      "args": {
        "url": "https://www.example.com/callB"
      }
    }
  },
  {
    "thirdStep": {
      "call": "http.get",
      "args": {
        "url": "https://www.example.com/callC"
      }
    }
  }
]

Explicit step ordering using jumps

This sample uses the next: command to explicitly define the sequence of workflow steps. In this example, steps are executed in a different order than they appear in the workflow definition.

YAML

- firstStep:
    call: http.get
    args:
      url: https://www.somewhere.com/callA
    next: secondStep
- thirdStep:
    call: http.get
    args:
      url: https://www.somewhere.com/callB
    next: end
- secondStep:
    call: http.get
    args:
      url: https://www.somewhere.com/callC
    next: thirdStep

JSON

[
  {
    "firstStep": {
      "call": "http.get",
      "args": {
        "url": "https://www.somewhere.com/callA"
      },
      "next": "secondStep"
    }
  },
  {
    "thirdStep": {
      "call": "http.get",
      "args": {
        "url": "https://www.somewhere.com/callB"
      },
      "next": "end"
    }
  },
  {
    "secondStep": {
      "call": "http.get",
      "args": {
        "url": "https://www.somewhere.com/callC"
      },
      "next": "thirdStep"
    }
  }
]

For more information about using next to control step order, see controlling the order of execution in a workflow.

Conditional jump

There are cases when you may want a workflow to jump to specific steps when a condition is met. This sample jumps to steps small, medium or large depending on the value returned by the first step of the workflow.

YAML

- firstStep:
    call: http.get
    args:
      url: https://www.example.com/callA
    result: firstResult
- whereToJump:
    switch:
      - condition: ${firstResult.body.SomeField < 10}
        next: small
      - condition: ${firstResult.body.SomeField < 100}
        next: medium
    next: large
- small:
    call: http.get
    args:
      url: https://www.example.com/SmallFunc
    next: end
- medium:
    call: http.get
    args:
      url: https://www.example.com/MediumFunc
    next: end
- large:
    call: http.get
    args:
      url: https://www.example.com/LargeFunc
    next: end

JSON

[
  {
    "firstStep": {
      "call": "http.get",
      "args": {
        "url": "https://www.example.com/callA"
      },
      "result": "firstResult"
    }
  },
  {
    "whereToJump": {
      "switch": [
        {
          "condition": "${firstResult.body.SomeField < 10}",
          "next": "small"
        },
        {
          "condition": "${firstResult.body.SomeField < 100}",
          "next": "medium"
        }
      ],
      "next": "large"
    }
  },
  {
    "small": {
      "call": "http.get",
      "args": {
        "url": "https://www.example.com/SmallFunc"
      },
      "next": "end"
    }
  },
  {
    "medium": {
      "call": "http.get",
      "args": {
        "url": "https://www.example.com/MediumFunc"
      },
      "next": "end"
    }
  },
  {
    "large": {
      "call": "http.get",
      "args": {
        "url": "https://www.example.com/LargeFunc"
      },
      "next": "end"
    }
  }
]

For more information about using switches, see conditional jumps.

Switch structure with embedded steps

A switch structure can also be used to support direct execution of steps when a condition is met, without jumping to other steps. This improves the readability of a workflow by reducing the number of steps in the workflow definition.

YAML

- step1:
    assign:
      - a: 1
- step2:
    switch:
      - condition: ${a==1}
        steps:
          - stepA:
              assign:
                - a: ${a+7}
          - stepB:
              return: ${"increase a to:"+string(a)}
- step3:
    return: ${"default a="+string(a)}

JSON

[
  {
    "step1": {
      "assign": [
        {
          "a": 1
        }
      ]
    }
  },
  {
    "step2": {
      "switch": [
        {
          "condition": "${a==1}",
          "steps": [
            {
              "stepA": {
                "assign": [
                  {
                    "a": "${a+7}"
                  }
                ]
              }
            },
            {
              "stepB": {
                "return": "${\"increase a to:\"+string(a)}"
              }
            }
          ]
        }
      ]
    }
  },
  {
    "step3": {
      "return": "${\"default a=\"+string(a)}"
    }
  }
]

For more information about using switches, see conditional jumps.

Simple subworkflow

This sample implements a simple subworkflow. When a workflow has a subworkflow, the main workflow must be placed in a main block. Subworkflows are always defined after the main body of the workflow definition.

YAML

main:
  steps:
    - first:
        call: hello
        args:
          input: "Kristof"
        result: someOutput
    - second:
        return: ${someOutput}

hello:
  params: [input]
  steps:
    - first:
        return: ${"Hello "+input}

JSON

{
  "main": {
    "steps": [
      {
        "first": {
          "call": "hello",
          "args": {
            "input": "Kristof"
          },
          "result": "someOutput"
        }
      },
      {
        "second": {
          "return": "${someOutput}"
        }
      }
    ]
  },
  "hello": {
    "params": [
      "input"
    ],
    "steps": [
      {
        "first": {
          "return": "${\"Hello \"+input}"
        }
      }
    ]
  }
}

For more information about using subworkflows, see creating and using a subworkflow.

Error handling

These samples show you how to catch exceptions and retry steps. See the error handling section of the syntax reference page for more details.

Catching and handling HTTP request errors

This sample implements a custom exception handler based on the HTTP status code returned by the GET request. The workflow catches a potential exception and returns a predefined error message. If an exception is not recognized, the workflow execution fails and throws the exception as returned by the GET request.

The same pattern could be used to catch exceptions raised by Cloud Run or Cloud Functions workloads.

YAML

- readItem:
    try:
      call: http.get
      args:
        url: https://example.com/someapi
        auth:
          type: OIDC
      result: APIResponse
    except:
      as: e
      steps:
        - knownErrors:
            switch:
              - condition: ${not("HttpError" in e.tags)}
                next: connectionProblem
              - condition: ${e.code == 404}
                next: urlNotFound
              - condition: ${e.code == 403}
                next: authProblem
        - UnhandledException:
            raise: ${e}
- urlFound:
    return: ${APIResponse.body}
- connectionProblem:
    return: "Connection problem; check URL"
- urlNotFound:
    return: "Sorry, URL wasn't found"
- authProblem:
    return: "Authentication error"

JSON

[
  {
    "readItem": {
      "try": {
        "call": "http.get",
        "args": {
          "url": "https://example.com/someapi",
          "auth": {
            "type": "OIDC"
          }
        },
        "result": "APIResponse"
      },
      "except": {
        "as": "e",
        "steps": [
          {
            "knownErrors": {
              "switch": [
                {
                  "condition": "${not(\"HttpError\" in e.tags)}",
                  "next": "connectionProblem"
                },
                {
                  "condition": "${e.code == 404}",
                  "next": "urlNotFound"
                },
                {
                  "condition": "${e.code == 403}",
                  "next": "authProblem"
                }
              ]
            }
          },
          {
            "UnhandledException": {
              "raise": "${e}"
            }
          }
        ]
      }
    }
  },
  {
    "urlFound": {
      "return": "${APIResponse.body}"
    }
  },
  {
    "connectionProblem": {
      "return": "Connection problem; check URL"
    }
  },
  {
    "urlNotFound": {
      "return": "Sorry, URL wasn't found"
    }
  },
  {
    "authProblem": {
      "return": "Authentication error"
    }
  }
]

Retrying steps using a default retry policy

Workflows comes with built-in retry policies. This sample uses a built-in retry policy for HTTP requests.

Retrying steps with custom configuration

This sample makes an HTTP request using a custom retry configuration. This example uses a standard retry predicate, determining when to perform a retry, and a custom maximum number of retries and backoff parameters.

YAML

- readItem:
    try:
      call: http.get
      args:
        url: https://example.com/someapi
      result: apiResponse
    retry:
      predicate: ${http.default_retry_predicate}
      max_retries: 5
      backoff:
        initial_delay: 2
        max_delay: 60
        multiplier: 2

JSON

[
  {
    "readItem": {
      "try": {
        "call": "http.get",
        "args": {
          "url": "https://example.com/someapi"
        },
        "result": "apiResponse"
      },
      "retry": {
        "predicate": "${http.default_retry_predicate}",
        "max_retries": 5,
        "backoff": {
          "initial_delay": 2,
          "max_delay": 60,
          "multiplier": 2
        }
      }
    }
  }
]

Error handling with custom predicate

This sample defines a custom error handler, including a custom predicate and custom backoff parameters. A predicate is defined as a subworkflow that accepts a single parameter as a dictionary, which is used to hold the exception definition.

YAML

main:
  steps:
    - readItem:
        try:
          call: http.get
          args:
            url: https://example.com/someapi
          result: apiResponse
        retry:
          predicate: ${myOwnPredicate}
          max_retries: 5
          backoff:
            initial_delay: 2
            max_delay: 60
            multiplier: 2
    - LastStep:
        return: "OK"

myOwnPredicate:
  params: [e]
  steps:
    - whatToRepeat:
        switch:
          - condition: "df"
            return: True
    - otherwise:
        return: False

JSON

{
  "main": {
    "steps": [
      {
        "readItem": {
          "try": {
            "call": "http.get",
            "args": {
              "url": "https://example.com/someapi"
            },
            "result": "apiResponse"
          },
          "retry": {
            "predicate": "${myOwnPredicate}",
            "max_retries": 5,
            "backoff": {
              "initial_delay": 2,
              "max_delay": 60,
              "multiplier": 2
            }
          }
        }
      },
      {
        "LastStep": {
          "return": "OK"
        }
      }
    ]
  },
  "myOwnPredicate": {
    "params": [
      "e"
    ],
    "steps": [
      {
        "whatToRepeat": {
          "switch": [
            {
              "condition": "df",
              "return": true
            }
          ]
        }
      },
      {
        "otherwise": {
          "return": false
        }
      }
    ]
  }
}

Connecting with other Google Cloud services

These samples demonstrate how Workflows can interact with other Google Cloud services.

POST request to a Cloud Functions with authentication

This sample makes a POST request to a Cloud Functions function that accepts only authenticated calls.

YAML

- callMyFunction:
    call: http.post
    args:
      url: https://us-central1-myproject123.cloudfunctions.net/myfunc1
      auth:
        type: OIDC
      body:
        someVal: "Hello World"
        anotherVal: 123
    result: theMessage
- returnValue:
    return: ${theMessage.body}

JSON

[
  {
    "callMyFunction": {
      "call": "http.post",
      "args": {
        "url": "https://us-central1-myproject123.cloudfunctions.net/myfunc1",
        "auth": {
          "type": "OIDC"
        },
        "body": {
          "someVal": "Hello World",
          "anotherVal": 123
        }
      },
      "result": "theMessage"
    }
  },
  {
    "returnValue": {
      "return": "${theMessage.body}"
    }
  }
]

For more information about authenticating to a resource from within a workflow, see making authenticated requests from within a workflow.

GET request to Cloud Run with authentication

This sample invokes a Cloud Run workload that requires authentication.

YAML

- callMyFunction:
    call: http.get
    args:
      url: https://example-12345-ew.a.run.app
      auth:
        type: OIDC
      query:
        someVal: "Hello World"
        anotherVal: 123
    result: theMessage
- returnValue:
    return: ${theMessage.body}

JSON

[
  {
    "callMyFunction": {
      "call": "http.get",
      "args": {
        "url": "https://example-12345-ew.a.run.app",
        "auth": {
          "type": "OIDC"
        },
        "query": {
          "someVal": "Hello World",
          "anotherVal": 123
        }
      },
      "result": "theMessage"
    }
  },
  {
    "returnValue": {
      "return": "${theMessage.body}"
    }
  }
]

For more information about authenticating to a resource from within a workflow, see making authenticated requests from within a workflow.

Stopping a Compute Engine virtual machine

This sample makes a call to the Compute Engine API to stop a virtual machine. The ID of a project is captured from a built-in environment variable, pointing to the same project as the workflow to help with source code portability.

The workflow must be associated with a service account that has sufficient privileges to stop a virtual machine, such as the roles/compute.instanceAdmin.v1 role. To learn more about granting roles to service accounts, see granting, changing, and revoking access to resources.

YAML

- initialize:
    assign:
    - project: ${sys.get_env("GOOGLE_CLOUD_PROJECT_NUMBER")}
    - zone: "us-central1-a"
    - vmToStop: "examplevm"
- stopInstance:
    call: http.post
    args:
      url: ${"https://compute.googleapis.com/compute/v1/projects/"+project+"/zones/"+zone+"/instances/"+vmToStop+"/stop"}
      auth:
        type: OAuth2
    result: stopResult

JSON

[
  {
    "initialize": {
      "assign": [
        {
          "project": "${sys.get_env(\"GOOGLE_CLOUD_PROJECT_NUMBER\")}"
        },
        {
          "zone": "us-central1-a"
        },
        {
          "vmToStop": "examplevm"
        }
      ]
    }
  },
  {
    "stopInstance": {
      "call": "http.post",
      "args": {
        "url": "${\"https://compute.googleapis.com/compute/v1/projects/\"+project+\"/zones/\"+zone+\"/instances/\"+vmToStop+\"/stop\"}",
        "auth": {
          "type": "OAuth2"
        }
      },
      "result": "stopResult"
    }
  }
]

For more information about authenticating to a resource from within a workflow, see making authenticated requests from within a workflow.

Reading from Firestore

This sample shows how to make a request to Firestore API to read an entry. The workflow initializes variables to set the ID of the project, name of the collection, and document to retrieve in the initialize step.

The workflow must be associated with a service account that has sufficient privileges to read from Firestore, such as the roles/datastore.viewer role. To learn more about granting roles to service accounts, see granting, changing, and revoking access to resources.

YAML

- initialize:
    assign:
    - project: "myproject123"
    - collection: "myEntries"
    - document: "Report"
- readItem:
    try:
      call: http.get
      args:
        url: ${"https://firestore.googleapis.com/v1/projects/"+project+"/databases/(default)/documents/"+collection+"/"+document}
        auth:
          type: OAuth2
      result: documentValue
    except:
      as: e
      steps:
      - isTheKeyFound:
          switch:
          - condition: ${e.code == 404}
            next: documentNotFound
          - condition: ${e.code == 403}
            next: authError
    next: documentFound
- documentNotFound:
    return: "Document not found."
- authError:
    return: "Authentication error."
- documentFound:
    return: ${documentValue.body.fields.LastName.stringValue}

JSON

[
  {
    "initialize": {
      "assign": [
        {
          "project": "myproject123"
        },
        {
          "collection": "myEntries"
        },
        {
          "document": "Report"
        }
      ]
    }
  },
  {
    "readItem": {
      "try": {
        "call": "http.get",
        "args": {
          "url": "${\"https://firestore.googleapis.com/v1/projects/\"+project+\"/databases/(default)/documents/\"+collection+\"/\"+document}",
          "auth": {
            "type": "OAuth2"
          }
        },
        "result": "documentValue"
      },
      "except": {
        "as": "e",
        "steps": [
          {
            "isTheKeyFound": {
              "switch": [
                {
                  "condition": "${e.code == 404}",
                  "next": "documentNotFound"
                },
                {
                  "condition": "${e.code == 403}",
                  "next": "authError"
                }
              ]
            }
          }
        ]
      },
      "next": "documentFound"
    }
  },
  {
    "documentNotFound": {
      "return": "Document not found."
    }
  },
  {
    "authError": {
      "return": "Authentication error."
    }
  },
  {
    "documentFound": {
      "return": "${documentValue.body.fields.LastName.stringValue}"
    }
  }
]

For more information about authenticating to a resource from within a workflow, see making authenticated requests from within a workflow.

Writing to Firestore

This sample makes a request to the Firestore API to write an entry. The workflow initializes variables to set the ID of the project, name of the collection, and document to retrieve in the initialize step.

The workflow must be associated with a service account that has sufficient privileges to read from Firestore, such as the roles/datastore.user role. To learn more about granting roles to service accounts, see granting, changing, and revoking access to resources.

YAML

- initialize:
    assign:
    - project: "myproject123"
    - collection: "myEntries"
    - document: "Visits"
- writeItem:
    call: http.request
    args:
      url: ${"https://firestore.googleapis.com/v1/projects/"+project+"/databases/(default)/documents/"+collection+"/"+document}
      auth:
        type: OAuth2
      method: PATCH
      body:
        name: ${"projects/"+project+"/databases/(default)/documents/"+collection+"/"+document}
        fields:
          Counter:
            integerValue: 7

JSON

[
  {
    "initialize": {
      "assign": [
        {
          "project": "myproject123"
        },
        {
          "collection": "myEntries"
        },
        {
          "document": "Visits"
        }
      ]
    }
  },
  {
    "writeItem": {
      "call": "http.request",
      "args": {
        "url": "${\"https://firestore.googleapis.com/v1/projects/\"+project+\"/databases/(default)/documents/\"+collection+\"/\"+document}",
        "auth": {
          "type": "OAuth2"
        },
        "method": "PATCH",
        "body": {
          "name": "${\"projects/\"+project+\"/databases/(default)/documents/\"+collection+\"/\"+document}",
          "fields": {
            "Counter": {
              "integerValue": 7
            }
          }
        }
      }
    }
  }
]

For more information about authenticating to another resource from within a workflow, see making authenticated requests from within a workflow.

Translate from English to Russian with Cloud Translation API

This sample makes a request to the Cloud Translation API to translate a runtime argument string from English to Russian.

The workflow must be associated with a service account that has sufficient privileges to send requests to the Cloud Translation API, such as the roles/cloudtranslate.user role. To learn more about granting roles to service accounts, see granting, changing, and revoking access to resources.

When running this workflow, pass a runtime argument in the following format:

{"textToTranslate":"Hello world!"}

YAML

main:
  params: [args]
  steps:
    - newTranslation:
        call: http.post
        args:
          url: ${"https://translation.googleapis.com/v3/projects/"+sys.get_env("GOOGLE_CLOUD_PROJECT_NUMBER")+":translateText"}
          auth:
            type: OAuth2
          body:
            contents: ${args.textToTranslate}
            sourceLanguageCode: "en-US"
            targetLanguageCode: "ru-RU"
        result: translateResponse
    - assignTranslation:
        assign:
          - translationResult: ${translateResponse.body.translations[0].translatedText}
    - returnResult:
        return: ${translationResult}

JSON

{
  "main": {
    "params": [
      "args"
    ],
    "steps": [
      {
        "newTranslation": {
          "call": "http.post",
          "args": {
            "url": "${\"https://translation.googleapis.com/v3/projects/\"+sys.get_env(\"GOOGLE_CLOUD_PROJECT_NUMBER\")+\":translateText\"}",
            "auth": {
              "type": "OAuth2"
            },
            "body": {
              "contents": "${args.textToTranslate}",
              "sourceLanguageCode": "en-US",
              "targetLanguageCode": "ru-RU"
            }
          },
          "result": "translateResponse"
        }
      },
      {
        "assignTranslation": {
          "assign": [
            {
              "translationResult": "${translateResponse.body.translations[0].translatedText}"
            }
          ]
        }
      },
      {
        "returnResult": {
          "return": "${translationResult}"
        }
      }
    ]
  }
}

What's next