Yandex Cloud
Search
Contact UsGet started
  • Blog
  • Pricing
  • Documentation
  • All Services
  • System Status
    • Featured
    • Infrastructure & Network
    • Data Platform
    • Containers
    • Developer tools
    • Serverless
    • Security
    • Monitoring & Resources
    • ML & AI
    • Business tools
  • All Solutions
    • By industry
    • By use case
    • Economics and Pricing
    • Security
    • Technical Support
    • Customer Stories
    • Cloud credits to scale your IT product
    • Gateway to Russia
    • Cloud for Startups
    • Education and Science
    • Yandex Cloud Partner program
  • Blog
  • Pricing
  • Documentation
© 2025 Direct Cursus Technology L.L.C.
Tutorials
    • All tutorials
    • URL shortener
    • Entering data into storage systems
    • Storing application runtime logs
    • Deploying a web application using the Java Servlet API
    • Developing a Slack bot
    • Developing a Telegram bot
    • Developing a custom integration in API Gateway
    • Developing CRUD APIs for movie services
    • Building a CI/CD pipeline in GitLab
    • Working with an API gateway via WebSocket
    • Creating an interactive serverless application using WebSocket
    • Automatically copying objects from one Object Storage bucket to another
    • Visualizing logs in Grafana using the Cloud Logging plugin
    • Canary release of a Cloud Functions function
    • Interactive debugging of Cloud Functions functions
    • Creating a Node.js function using TypeScript
    • Running a containerized app in Serverless Containers
    • Streaming Yandex Cloud Postbox events to Data Streams and analyzing them using DataLens
    • Using API Gateway to set up speech synthesis in SpeechKit
    • Connecting to YDB from a Cloud Functions function in Python
    • Connecting to a YDB database from a Cloud Functions function in Node.js
    • API Gateway protection with Smart Web Security
    • Deploying a web app with JWT authorization in API Gateway and authentication in Firebase
    • Automatic data upload to Yandex SpeechSense using Yandex Workflows
    • Configuring responses in Cloud Logging and Yandex Cloud Functions
    • Setting up Workflows integration with Tracker, YandexGPT, and Yandex Cloud Postbox
    • Developing functions in Functions Framework and deploying them to Yandex Serverless Containers

In this article:

  • Getting started
  • Required paid resources
  • Create a service account
  • Prepare your queue and issues in Tracker
  • Configure access for workflow authentication in Tracker
  • Create an OAuth application in Yandex ID
  • Get the application's OAuth token
  • Create a Yandex Lockbox secret
  • Create an address and pass a domain rights check in Yandex Cloud Postbox
  • Create a Yandex Cloud Postbox address
  • Pass a domain rights check
  • Create a Workflows workflow
  • Test your workflow
  • How to delete the resources you created
  1. Serverless technologies
  2. Setting up Workflows integration with Tracker, YandexGPT, and Yandex Cloud Postbox

Configuring a Workflows workflow integrated with Yandex Tracker, Yandex Foundation Models, and Yandex Cloud Postbox

Written by
Yandex Cloud
Updated at April 9, 2025
  • Getting started
    • Required paid resources
  • Create a service account
  • Prepare your queue and issues in Tracker
  • Configure access for workflow authentication in Tracker
    • Create an OAuth application in Yandex ID
    • Get the application's OAuth token
    • Create a Yandex Lockbox secret
  • Create an address and pass a domain rights check in Yandex Cloud Postbox
    • Create a Yandex Cloud Postbox address
    • Pass a domain rights check
  • Create a Workflows workflow
  • Test your workflow
  • How to delete the resources you created

Note

Workflows is at the Preview stage. To gain access, submit a request in the management console.

In this tutorial, you will create Yandex Workflows workflows and configure their integration with Yandex Tracker, Yandex Foundation Models, and Yandex Cloud Postbox.

Your workflows will receive information about the issues in a given Tracker queue and use YandexGPT Pro to analyze the workcompleted within these issues, their statuses, and evaluation. The results of the analysis and a brief progress report will be saved in a comment to one of the Tracker issues and also sent to the specified email address via Yandex Cloud Postbox.

To configure a Workflows workflow:

  1. Get your cloud ready.
  2. Create a service account.
  3. Prepare Tracker.
  4. Configure workflow access in Tracker.
  5. Create an address and pass a domain rights check in Yandex Cloud Postbox.
  6. Create a Workflows workflow.
  7. Test the workflow.

If you no longer need the resources you created, delete them.

Getting startedGetting started

  1. Log in to your Yandex account. If you do not have an account, create one.

  2. Sign up in Yandex Cloud and create a billing account:

    1. Navigate to the management console and log in to Yandex Cloud or register a new account.
    2. On the Yandex Cloud Billing page, make sure you have a billing account linked and it has the ACTIVE or TRIAL_ACTIVE status. If you do not have a billing account, create one and link a cloud to it.

    If you have an active billing account, you can navigate to the cloud page to create or select a folder for your infrastructure to operate in.

    Learn more about clouds and folders.

  3. Install cURL: you will need it to send a request for an OAuth token for the Yandex ID application.

Required paid resourcesRequired paid resources

The cost of the web service infrastructure support includes:

  • Fee for storing the secret and requests to the secret (see Yandex Lockbox pricing).
  • Fee for using Yandex Foundation Models (see Yandex Foundation Models pricing).
  • Fee for using Yandex Tracker (see Tracker pricing).
  • Fee for using Yandex Cloud Postbox (see Yandex Cloud Postbox pricing).

Create a service accountCreate a service account

Management console
  1. In the management console, select the folder you will be creating your workflows in.
  2. From the list of services, select Identity and Access Management.
  3. Click Create service account, and in the window that opens:
    1. Enter a name for the service account: workflow-sa.
    2. Click Add role and select the serverless.workflows.executor role.
    3. Repeat the previous step to add the postbox.sender and ai.languageModels.user roles.
    4. Click Create.

Prepare your queue and issues in TrackerPrepare your queue and issues in Tracker

For the workflows you are creating in this tutorial to work correctly, configure your queue in Yandex Tracker.

Tracker interface
  1. If your organization does not have Yandex Tracker connected, connect it.

  2. If you do not have a queue in Tracker yet, create one.

  3. Create 5-10 test issues in your queue meeting the following requirements:

    • The test issues must be created in one queue.
    • All test issues must have the product tag set in the Tags field.
    • All test issues must be evaluated in Story Points in the Story Points field.
    • Some of the test issues should be in Closed status, and some in Open status.
    • Comments about your progress on closed test issues must be added to these issues.

Configure access for workflow authentication in TrackerConfigure access for workflow authentication in Tracker

To authenticate your workflow in Yandex Tracker, get a token of an OAuth application with read and write permissions for Tracker.

Create an OAuth application in Yandex IDCreate an OAuth application in Yandex ID

To create an OAuth application with read and write access rights to Tracker:

  1. In your browser, go to the OAuth application creation page. On the page that opens:
    1. In the Service name field, enter the name of the OAuth application you are creating: My Tracker Workflow.

    2. Under Application platforms, select the Web services option and specify Redirect URI in the field that appears: https://oauth.yandex.com/verification_code.

    3. Under Data access, in the Access name field, enter tracker:read and select the Read from tracker access.

      The Read from tracker access will appear below in the list of application accesses.

      Similarly, add the tracker:write access (Write to tracker).

    4. Under Email for communication, specify your email address to send notifications about the new application.

    5. Click Create app.

On the new application's page, copy the ClientID and Client secret field values. You will need them in the next step to get an OAuth token.

Get the application's OAuth tokenGet the application's OAuth token

  1. Get the confirmation code. To do this, paste the following address into your browser address bar with the value you copied in the previous step as client_id:

    https://oauth.yandex.ru/authorize?response_type=code&client_id=<ClientID_value>
    

    Confirm granting your OAuth application access to Tracker.

    In the window that opens, copy and save the confirmation code you get. You will need this code to get an OAuth token.

  2. Get the application's OAuth token by running this command in the terminal:

    curl \
      --request POST \
      --header "Content-type: application/x-www-form-urlencoded" \
      --data "grant_type=authorization_code&code=<confirmation_code>&client_id=<ClientID_value>&client_secret=<Client_secret_value>" \
      https://oauth.yandex.ru/token
    

    Where:

    • code: Confirmation code you got in the previous step.
    • client_id: Your OAuth application's ClientID value you got earlier.
    • client_secret: Your OAuth application's Client secret value you got earlier.

    Result:

    {"access_token": "y0__wgBhMmiugUY4b40IJCda4YSeAfV5tAoPqy2tttkQsy********", "expires_in": 31536000, "refresh_token": "1:7WGrfpErRSTlkTJI:NGU-BJxhvhUdwDxDuez5ana4Befm63bXXhNpJFnbWDX1XJ_rJ3qh6DH_AItBhFJk********:ZZP-Pf0nxo4nil********", "token_type": "bearer"}%
    

    Save the resulting access_token field value. This is the application's OAuth token the workflow will need to access Tracker.

Create a Yandex Lockbox secretCreate a Yandex Lockbox secret

Create a Yandex Lockbox secret to store your OAuth token and assign access permissions for the new secret to the service account .

Management console
  1. In the management console, select the folder you created the service account in earlier.

  2. From the list of services, select Lockbox.

  3. Click Create secret, and in the window that opens:

    1. In the Name field, specify the secret name: tracker-oauth-token.
    2. In the Secret type field, select Custom.
    3. Under Version:
      • In the Key field, enter the secret key: oauth.
      • In the Value field, specify the application OAuth token you got in the previous step.
    4. Click Create.
  4. Click the line with the new secret (tracker-oauth-token) and do the following in the window that opens:

    1. Copy and save the ID field value. You will need it later when creating the workflow specification.
    2. Go to the Access bindings tab and click Assign roles.
    3. In the search bar, enter the name of the service account created earlier (workflow-sa) and select the service account you found.
    4. Click Add role and select the lockbox.payloadViewer role.
    5. Click Save.

Create an address and pass a domain rights check in Yandex Cloud PostboxCreate an address and pass a domain rights check in Yandex Cloud Postbox

For the workflow to be able to send emails, create a Yandex Cloud Postbox address and confirm the ownership of the domain the emails will be sent from.

Create a Yandex Cloud Postbox addressCreate a Yandex Cloud Postbox address

  1. Generate a key to create a DKIM signature by running this command in the terminal:

    openssl genrsa -out privatekey.pem 2048
    

    The new key will be saved in the privatekey.pem file in the current directory.

  2. Create an address:

    Management console
    1. In the management console, select the folder you used to create the service account and secret in.

    2. From the list of services, select Cloud Postbox.

    3. Click Create address.

    4. In the Domain field, specify the domain to send emails from. e.g., example.com.

      The domain can be of any level. You must have permissions to add resource records to the public DNS zone of the specified domain. This is required to confirm your right to use it.

    5. In the Selector field, specify a selector, e.g., tracker_workflow.

      The name of the selector will be used to create a TXT resource record, so each selector you create must be unique within your domain.

    6. In the Private key field, copy the contents of the privatekey.pem private key file you created earlier.

    7. Click Create address.

    8. In the list of addresses that appears, select the created address and, under Signature verification on the page that opens, copy and save the values ​​of the Name and Value fields. You will need these to create a TXT resource record.

Pass a domain rights checkPass a domain rights check

  1. In the public DNS zone of your domain, create a TXT resource record using the following values:

    • Record name: Name field value you copied in the previous step.

      In Yandex Cloud DNS, specify the name portion generated when creating the address (without specifying the domain) in <selector>._domainkey format, e.g., tracker_workflow._domainkey.

      For other DNS services, you may need to copy the entire record. The final record must look like this: <selector>._domainkey.<domain>., e.g., tracker_workflow._domainkey.example.com..

    • Record type: TXT.

    • Record value: Value field value you copied in the previous step.

      Note that the record value must be enclosed in quotes, for example:

      "v=DKIM1;h=sha256;k=rsa;p=M1B...aCA8"
      

    Note

    If your domain is delegated to Yandex Cloud DNS, use this guide to create a resource record. In other cases, use your domain name registrar's personal account page. If you have any questions, refer to the relevant documentation or contact the registrar's support service.

  2. Run a domain rights check.

    Management console
    1. In the management console, select the folder the new address is in.

    2. In the list of services, select Cloud Postbox and select the required address.

    3. Click Verify address. If the TXT record is created correctly, the verification status on the address page will change to Success.

      DNS server responses are cached, so delays may occur when updating a resource record.

Create a Workflows workflowCreate a Workflows workflow

  1. Select the specification you will use to create your workflow. Both the above specifications use integrations with Yandex Tracker, Yandex Foundation Models, and Yandex Cloud Postbox; however, they analyze the input data differently.

    Option 1
    Option 2

    The suggested workflow will analyze the Tracker issues in the specified queue, generate and publish a progress report for these issues:

    1. Analyzing issues with specified tag in a given Tracker queue:
      • Total number of issues.
      • Total sum of Story Points awarded to issues.
      • Number of closed issues.
      • Percentage ratio of the number of closed issues to the total number of issues.
      • Sum of Story Points awarded to closed issues.
      • Percentage ratio of the sum of Story Points awarded to closed issues to the total sum of Story Points awarded to all issues.
    2. Generating a report with the results of the analysis.
    3. Publishing a report in a comment to a specified Tracker issue, sending the report to a specified email address.

    Specification code:

    yawl: "0.1"
    start: fetch_tickets
    steps:
      fetch_tickets:
        tracker:
          organization:
            cloudOrganizationId: <organization_ID>
          oauthToken: '\(lockboxPayload("<secret_ID>"; "oauth"))'
          listIssues:
            filter:
              issueProperties:
                queue: <queue_key_in_Tracker>
                tags: "product"
          output: |-
            \({
              "sp_sum": [.[].storyPoints] | add,
              "closed_sp_sum": . | map(select(.status.key == "closed")) | map(.storyPoints) | add,
              "ticket_count": . | length,
              "closed_ticket_count": . | map(select(.status.key == "closed")) | length,
              "non_closed_ticket_texts": . | map(select(.status.key != "closed")) | map({
                "key": .key,
                "summary": .summary,
                "description": .description            
              })
            })
          next: summarize_texts
      summarize_texts:
        foundationModelsCall:
          next: create_report
          modelUrl: gpt://<folder_ID>/yandexgpt
          generate:
            maxTokens: 500
            temperature: 0.5
            messages:
              messages:
                - role: system
                  text: "Next you will get names of unfinished Tracker issues and their descriptions. State as briefly as possible (no more than three sentences) what remains to be done"
                - role: user
                  text: |-
                    \("
                      \(.non_closed_ticket_texts | map(.summary + ": " + .description) | join(". "))
                    ")
          output: |-
            \({
              "summary": .alternatives.[0].message.text
            })
      create_report:
        noOp:
          output: |-
            \({
            "report_text": "**Total amount of work:** \(.ticket_count) issue(s), \(.sp_sum) sp
            **Work completed:** \(.closed_ticket_count) (\(100 * .closed_ticket_count / .ticket_count | round)%) issue(s), \(.closed_sp_sum) (\(100 * .closed_sp_sum / .sp_sum | round)%) sp
    
            **Unfinished issues:**
              \(.non_closed_ticket_texts | map(.key) | join("\n"))
    
            **Summary of what remains:**
              \(.summary)
            ",
            "report_text_html": "<b>Total amount of work:</b> \(.ticket_count) issue(s), \(.sp_sum) sp<br>
            <b>Work completed:</b> \(.closed_ticket_count) (\(100 * .closed_ticket_count / .ticket_count | round)%) issue(s), \(.closed_sp_sum) (\(100 * .closed_sp_sum / .sp_sum | round)%) sp<br>
            <br>
            <b>Unfinished issues:</b><br>
              \(.non_closed_ticket_texts | map("<a href=https://tracker.yandex.ru/" + .key + ">" + .key + "</a>") | join("<br>"))<br>
            <br>
            <b>Summary of what remains:</b><br>
              \(.summary | gsub("\\n"; "<br>"))
            "})
          next: deliver_report
      deliver_report:
        parallel:
          branches:
            tracker:
              start: write_report_to_tracker
              steps:
                write_report_to_tracker:
                  tracker:
                    organization:
                      cloudOrganizationId: <organization_ID>
                    oauthToken: '\(lockboxPayload("<secret_ID>"; "oauth"))'
                    createComment:
                      key: <issue_key_with_report>
                      text: \(.report_text)
            postbox:
              start: send_report_via_postbox
              steps:
                send_report_via_postbox:
                  postbox:
                    simple:
                      subject:
                        data: "Dev progress report"
                        charset: UTF_8
                      body:
                        text:
                          data: \(.report_text)
                          charset: UTF_8
                        html:
                          data: \("<p>\(.report_text_html)</p>")
                          charset: UTF_8
                    fromAddress: tracker-robot@<your_domain>
                    destination:
                      toAddresses: <recipient_address>
    

    Where:

    • <organization_ID>: ID of your Yandex Cloud Organization.
    • <secret_ID>: Previously saved secret ID with the application's OAuth token.
    • <queue_key_in_Tracker>: Key of the Tracker queue you created the test issues in.
    • <folder_ID>: ID of the folder you are creating a workflow in.
    • <issue_key_with_report>: Key of the Tracker issue in the comment to which the summary of the analyzed test issues will be uploaded.
    • <your_domain>: Domain you specified when creating the Yandex Cloud Postbox address. For the sender address (fromAddress) you can specify any address on this domain. Example: tracker-robot@example.com or noreply@example.com.
    • <recipient_address>: Email address the workflow will send an email to with a summary of the analyzed Tracker test issues.

    A workflow comprises the following steps: fetch_tickets, summarize_texts, send_report_via_postbox, and write_report_to_tracker.

    The suggested workflow will analyze closed Tracker issues for the last week, generate and publish a progress report for these issues:

    1. Analysis of issues closed over the past week:
      • Uploading comments to issues.
      • Analysis and summation of comments for each closed issue.
    2. Generating a report summarizing the work done for each closed issue.
    3. Publishing the report in a comment to a specified Tracker issue, sending the report to a specified email address.

    Specification code:

    yawl: "0.1"
    start: fetch_tickets
    steps:
      fetch_tickets:
        tracker:
          organization:
            cloudOrganizationId: <organization_ID>
          oauthToken: '\(lockboxPayload("<secret_ID>"; "oauth"))'
          listIssues:
            query: 'Status: changed(to: Closed date: >now()-2w)'
          output: |-
            \({
              "closed_tickets": . | map({"ticket_key": .key})
            })
          next: fetch_comments_fe
      fetch_comments_fe:
        foreach:
          input: \(.closed_tickets)
          do:
            start: fetch_comments
            steps:
              fetch_comments:
                tracker:
                  organization:
                    cloudOrganizationId: <organization_ID>
                  oauthToken: '\(lockboxPayload("<secret_ID>"; "oauth"))'
                  listComments:
                    key: \(.ticket_key)
                  output: |-
                    \({
                      "comments": .
                    })
          output: |-
            \({
              "comment_text": map(.comments[].text) | join("\n")
            })
          next: summarize_texts
      summarize_texts:
        foundationModelsCall:
          modelUrl: gpt://<folder_ID>/yandexgpt
          generate:
            maxTokens: 500
            temperature: 0.5
            messages:
              messages:
                - role: system
                  text: "Next you will be given comments of completed issues in Tracker. State as briefly as possible (no more than three sentences) what work has been done."
                - role: user
                  text: \(.comment_text)
          output: |-
            \({
              "summary": .alternatives.[0].message.text
            })
          next: create_report
      create_report:
        noOp:
          output: |-
            \({
              "report_text": "
                Completed issues:
                  \(.closed_tickets | map(.ticket_key) | join("\n"))
                Summary of closed issues:
                  \(.summary)
              ",
              "report_text_html": "
                Completed issues:<br>
                  \(.closed_tickets | map("<a href=https://tracker.yandex.ru/" + .ticket_key + ">" + .ticket_key + "</a>") | join("<br>"))<br>
    
                <br>
                Summary of closed issues:<br>
                  \(.summary | gsub("\\n"; "<br>")))
              "
            })
          next: deliver_report
      deliver_report:
        parallel:
          branches:
            tracker:
              start: write_report_to_tracker
              steps:
                write_report_to_tracker:
                  tracker:
                    organization:
                      cloudOrganizationId: <organization_ID>
                    oauthToken: '\(lockboxPayload("<secret_ID>"; "oauth"))'
                    createComment:
                      key: <issue_key_with_report>
                      text: \(.report_text)
            postbox:
              start: send_report_via_postbox
              steps:
                send_report_via_postbox:
                  postbox:
                    simple:
                      subject:
                        data: "Dev progress report (closed issues)"
                        charset: UTF_8
                      body:
                        text:
                          data: \(.report_text)
                          charset: UTF_8
                        html:
                          data: \("<p>\(.report_text_html)</p>")
                          charset: UTF_8
                    fromAddress: tracker-robot@<your_domain>
                    destination:
                      toAddresses: <recipient_address>
    

    Where:

    • <organization_ID>: ID of your Yandex Cloud Organization.
    • <secret_ID>: Previously saved secret ID with the application's OAuth token.
    • <folder_ID>: ID of the folder you are creating a workflow in.
    • <issue_key_with_report>: Key of the Tracker issue in the comment to which the summary of the analyzed test issues will be uploaded.
    • <your_domain>: Domain you specified when creating the Yandex Cloud Postbox address. For the sender address (fromAddress) you can specify any address on this domain. Example: tracker-robot@example.com or noreply@example.com.
    • <recipient_address>: Email address to which the workflow will send a summary of the analyzed Tracker test issues.

    A workflow comprises the following steps: fetch_tickets, fetch_comments, summarize_texts, send_report_via_postbox, and write_report_to_tracker.

  2. Create a Workflows workflow using the selected specification:

    Management console
    1. In the management console, select the folder containing the previously created resources: service account, secret, and Yandex Cloud Postbox address.

    2. From the list of services, select Serverless Integrations.

    3. In the left-hand panel, select Workflows.

    4. In the top-right corner, click Create workflow and do the following in the window that opens:

      1. In the YaML specification field, add the previously selected specification.
      2. Expand the Additional parameters section.
      3. In the Name field, enter the workflow name: my-tracker-workflow.
      4. In the Service account field, select the previously created service account named workflow-sa.
    5. Click Create.

Test your workflowTest your workflow

Make sure the Workflows workflow is being executed.

Management console
  1. In the management console, select the folder the new Workflows workflow is in.

  2. From the list of services, select Serverless Integrations.

  3. In the left-hand panel, select Workflows.

  4. Click next to my-tracker-workflow and select Execute.

  5. In the window that opens, click Start. The previously created workflow will be executed; it may take a few minutes to complete.

  6. Navigate to the Timeline tab.

    Make sure all workflow steps are completed successfully. Each successful step will be marked by a green box with the icon in the relevant line of the time scale.

    If there is an error at any of the steps, a red box with the icon will be displayed in the relevant line of the time scale. Click this box to view the details about the error.

As a result of the workflow, a comment with a summary of the analyzed test issues will be added to the Tracker issue named in the specification. This summary will also be backed up with an email to the address given in the specification.

How to delete the resources you createdHow to delete the resources you created

To stop paying for the resources you created:

  1. Delete your workflow:

    Management console
    1. In the management console, select the folder the created resources are located in.
    2. From the list of services, select Serverless Integrations.
    3. In the left-hand panel, select Workflows.
    4. Click next to my-tracker-workflow and select Delete.
    5. Confirm the deletion.
  2. Delete the secret.

  3. Delete the Tracker issues and the queue.

  4. Delete the Yandex Cloud Postbox address if you need to:

    Management console
    1. In the management console, select the folder the Yandex Cloud Postbox address is in.
    2. From the list of services, select Cloud Postbox.
    3. In the row with the Yandex Cloud Postbox address, click and select Delete.
    4. Confirm the deletion.

Was the article helpful?

Previous
Configuring responses in Cloud Logging and Yandex Cloud Functions
Next
Developing functions in Functions Framework and deploying them to Yandex Serverless Containers
© 2025 Direct Cursus Technology L.L.C.