Automation
Список проектов автоматизации
http://127.0.0.1:40325/automation/projectsКаждый проект, сохраненный в лаунчере, со своими блоками и настройками запуска. Это те же проекты, которые редактирует десктопный раздел Automation.
Постоянный JWT из Settings → Automation API.
200Список проектов.application/json
blocksobject · AutomationBlock[]optionalShow propertiesHide properties
Встроенный тип палитры (goto, click, type, profile.create, var.set, ...) или module:<module id>:<block>.
В мобильном профиле обычные действия используют сенсорный ввод: click выполняет касание, rightClick - долгое нажатие, а scroll и swipe - жесты. hover недоступен, поскольку на мобильном устройстве нет указателя. Следующие шаги доступны только на мобильных профилях и отклоняются на компьютерах:
| Тип | Параметры | Действие |
| --- | --- | --- |
| touch.tap | selector или x+y, tapCount (1-3), timeout | Коснуться цели. |
| touch.longPress | selector или x+y, timeout | Нажать и удерживать. |
| touch.swipe | selector или x+y, dx, dy, timeout | Провести пальцем. |
| touch.drag | selector, to, holdMs, timeout | Перетащить элемент. |
| touch.pinch | scale, selector или x+y | Масштабировать двумя пальцами. Значение выше 1 уменьшает масштаб. |
| screen.rotate | angle (0/90/180/270), turnMs, into | Повернуть устройство. into сохраняет новый screen.orientation.type. |
Собственные поля шага, как их определяет палитра.
Положение на холсте. Только для макета, выполнение идет по веткам.
Ветка после выполнения шага. В простых случаях используется строка, при передаче значения - объект.
По умолчанию stop. Если продолжить после неудачного шага, действия могут выполняться не на той странице.
Имена параметров очищаются при экспорте.
runobject · AutomationRunSettingsoptionalShow propertiesHide properties
Максимальное число одновременно работающих браузеров: от 1 до 64.
Число проходов по блокам. 0 означает запуск до истечения hours.
Используется только при loops: 0.
Идентификатор блока, с которого нужно начать; пустой означает первый.
Для совместимости с проектами, сохраненными до появления профилей-блоков. При задании каждый профиль запускается в отдельном потоке.
Unix-секунды.
Unix-секунды.
401Отсутствующий или недействительный Bearer-токен.
/automation/projectsGET /automation/projects HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X GET 'http://127.0.0.1:40325/automation/projects' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/projects"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/projects";
const response = await fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/projects"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.get("http://127.0.0.1:40325/automation/projects")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Get, "http://127.0.0.1:40325/automation/projects");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/projects");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}[
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
}
]Создать проект
http://127.0.0.1:40325/automation/projectsПостоянный JWT из Settings → Automation API.
Когда пусто, используется Untitled.
200Созданный проект.application/json
blocksobject · AutomationBlock[]optionalShow propertiesHide properties
Встроенный тип палитры (goto, click, type, profile.create, var.set, ...) или module:<module id>:<block>.
В мобильном профиле обычные действия используют сенсорный ввод: click выполняет касание, rightClick - долгое нажатие, а scroll и swipe - жесты. hover недоступен, поскольку на мобильном устройстве нет указателя. Следующие шаги доступны только на мобильных профилях и отклоняются на компьютерах:
| Тип | Параметры | Действие |
| --- | --- | --- |
| touch.tap | selector или x+y, tapCount (1-3), timeout | Коснуться цели. |
| touch.longPress | selector или x+y, timeout | Нажать и удерживать. |
| touch.swipe | selector или x+y, dx, dy, timeout | Провести пальцем. |
| touch.drag | selector, to, holdMs, timeout | Перетащить элемент. |
| touch.pinch | scale, selector или x+y | Масштабировать двумя пальцами. Значение выше 1 уменьшает масштаб. |
| screen.rotate | angle (0/90/180/270), turnMs, into | Повернуть устройство. into сохраняет новый screen.orientation.type. |
Собственные поля шага, как их определяет палитра.
Положение на холсте. Только для макета, выполнение идет по веткам.
Ветка после выполнения шага. В простых случаях используется строка, при передаче значения - объект.
По умолчанию stop. Если продолжить после неудачного шага, действия могут выполняться не на той странице.
Имена параметров очищаются при экспорте.
runobject · AutomationRunSettingsoptionalShow propertiesHide properties
Максимальное число одновременно работающих браузеров: от 1 до 64.
Число проходов по блокам. 0 означает запуск до истечения hours.
Используется только при loops: 0.
Идентификатор блока, с которого нужно начать; пустой означает первый.
Для совместимости с проектами, сохраненными до появления профилей-блоков. При задании каждый профиль запускается в отдельном потоке.
Unix-секунды.
Unix-секунды.
401Отсутствующий или недействительный Bearer-токен.
/automation/projectsPOST /automation/projects HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
{
"name": "text"
}curl -X POST 'http://127.0.0.1:40325/automation/projects' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"text"}'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/projects"
headers = {
"Authorization": f"Bearer {token}",
}
payload = {
"name": "text",
}
response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/projects";
const payload = {
"name": "text"
};
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
console.log(response.status);
console.log(await response.text());package main
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/projects"
body := bytes.NewBufferString(`{
"name": "text"
}`)
req, err := http.NewRequest("POST", url, body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }, serde_json = "1"
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.post("http://127.0.0.1:40325/automation/projects")
.header("Authorization", format!("Bearer {token}"))
.json(&serde_json::json!({
"name": "text"
}))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:40325/automation/projects");
request.Content = new StringContent("""
{
"name": "text"
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
headers = curl_slist_append(headers, "Content-Type: application/json");
const std::string body = R"json({
"name": "text"
})json";
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/projects");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
}Получить проект
http://127.0.0.1:40325/automation/projects/{id}Постоянный JWT из Settings → Automation API.
200Детали проекта.application/json
blocksobject · AutomationBlock[]optionalShow propertiesHide properties
Встроенный тип палитры (goto, click, type, profile.create, var.set, ...) или module:<module id>:<block>.
В мобильном профиле обычные действия используют сенсорный ввод: click выполняет касание, rightClick - долгое нажатие, а scroll и swipe - жесты. hover недоступен, поскольку на мобильном устройстве нет указателя. Следующие шаги доступны только на мобильных профилях и отклоняются на компьютерах:
| Тип | Параметры | Действие |
| --- | --- | --- |
| touch.tap | selector или x+y, tapCount (1-3), timeout | Коснуться цели. |
| touch.longPress | selector или x+y, timeout | Нажать и удерживать. |
| touch.swipe | selector или x+y, dx, dy, timeout | Провести пальцем. |
| touch.drag | selector, to, holdMs, timeout | Перетащить элемент. |
| touch.pinch | scale, selector или x+y | Масштабировать двумя пальцами. Значение выше 1 уменьшает масштаб. |
| screen.rotate | angle (0/90/180/270), turnMs, into | Повернуть устройство. into сохраняет новый screen.orientation.type. |
Собственные поля шага, как их определяет палитра.
Положение на холсте. Только для макета, выполнение идет по веткам.
Ветка после выполнения шага. В простых случаях используется строка, при передаче значения - объект.
По умолчанию stop. Если продолжить после неудачного шага, действия могут выполняться не на той странице.
Имена параметров очищаются при экспорте.
runobject · AutomationRunSettingsoptionalShow propertiesHide properties
Максимальное число одновременно работающих браузеров: от 1 до 64.
Число проходов по блокам. 0 означает запуск до истечения hours.
Используется только при loops: 0.
Идентификатор блока, с которого нужно начать; пустой означает первый.
Для совместимости с проектами, сохраненными до появления профилей-блоков. При задании каждый профиль запускается в отдельном потоке.
Unix-секунды.
Unix-секунды.
401Отсутствующий или недействительный Bearer-токен.
404Проект не найден.application/json
/automation/projects/123e4567-e89b-12d3-a456-426614174000GET /automation/projects/123e4567-e89b-12d3-a456-426614174000 HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X GET 'http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000";
const response = await fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.get("http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Get, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
}{
"error": "text"
}Заменить проект
http://127.0.0.1:40325/automation/projects/{id}Заменяет весь проект. Отправьте объект, возвращенный GET. Идентификатор пути имеет приоритет над идентификатором тела. Отсутствующий проект возвращает 404; используйте POST /automation/projects, чтобы создать его.
Постоянный JWT из Settings → Automation API.
blocksobject · AutomationBlock[]optionalShow propertiesHide properties
Встроенный тип палитры (goto, click, type, profile.create, var.set, ...) или module:<module id>:<block>.
В мобильном профиле обычные действия используют сенсорный ввод: click выполняет касание, rightClick - долгое нажатие, а scroll и swipe - жесты. hover недоступен, поскольку на мобильном устройстве нет указателя. Следующие шаги доступны только на мобильных профилях и отклоняются на компьютерах:
| Тип | Параметры | Действие |
| --- | --- | --- |
| touch.tap | selector или x+y, tapCount (1-3), timeout | Коснуться цели. |
| touch.longPress | selector или x+y, timeout | Нажать и удерживать. |
| touch.swipe | selector или x+y, dx, dy, timeout | Провести пальцем. |
| touch.drag | selector, to, holdMs, timeout | Перетащить элемент. |
| touch.pinch | scale, selector или x+y | Масштабировать двумя пальцами. Значение выше 1 уменьшает масштаб. |
| screen.rotate | angle (0/90/180/270), turnMs, into | Повернуть устройство. into сохраняет новый screen.orientation.type. |
Собственные поля шага, как их определяет палитра.
Положение на холсте. Только для макета, выполнение идет по веткам.
Ветка после выполнения шага. В простых случаях используется строка, при передаче значения - объект.
По умолчанию stop. Если продолжить после неудачного шага, действия могут выполняться не на той странице.
Имена параметров очищаются при экспорте.
runobject · AutomationRunSettingsoptionalShow propertiesHide properties
Максимальное число одновременно работающих браузеров: от 1 до 64.
Число проходов по блокам. 0 означает запуск до истечения hours.
Используется только при loops: 0.
Идентификатор блока, с которого нужно начать; пустой означает первый.
Для совместимости с проектами, сохраненными до появления профилей-блоков. При задании каждый профиль запускается в отдельном потоке.
Unix-секунды.
Unix-секунды.
200Сохраненный проект.application/json
blocksobject · AutomationBlock[]optionalShow propertiesHide properties
Встроенный тип палитры (goto, click, type, profile.create, var.set, ...) или module:<module id>:<block>.
В мобильном профиле обычные действия используют сенсорный ввод: click выполняет касание, rightClick - долгое нажатие, а scroll и swipe - жесты. hover недоступен, поскольку на мобильном устройстве нет указателя. Следующие шаги доступны только на мобильных профилях и отклоняются на компьютерах:
| Тип | Параметры | Действие |
| --- | --- | --- |
| touch.tap | selector или x+y, tapCount (1-3), timeout | Коснуться цели. |
| touch.longPress | selector или x+y, timeout | Нажать и удерживать. |
| touch.swipe | selector или x+y, dx, dy, timeout | Провести пальцем. |
| touch.drag | selector, to, holdMs, timeout | Перетащить элемент. |
| touch.pinch | scale, selector или x+y | Масштабировать двумя пальцами. Значение выше 1 уменьшает масштаб. |
| screen.rotate | angle (0/90/180/270), turnMs, into | Повернуть устройство. into сохраняет новый screen.orientation.type. |
Собственные поля шага, как их определяет палитра.
Положение на холсте. Только для макета, выполнение идет по веткам.
Ветка после выполнения шага. В простых случаях используется строка, при передаче значения - объект.
По умолчанию stop. Если продолжить после неудачного шага, действия могут выполняться не на той странице.
Имена параметров очищаются при экспорте.
runobject · AutomationRunSettingsoptionalShow propertiesHide properties
Максимальное число одновременно работающих браузеров: от 1 до 64.
Число проходов по блокам. 0 означает запуск до истечения hours.
Используется только при loops: 0.
Идентификатор блока, с которого нужно начать; пустой означает первый.
Для совместимости с проектами, сохраненными до появления профилей-блоков. При задании каждый профиль запускается в отдельном потоке.
Unix-секунды.
Unix-секунды.
400Неверный объект проекта.application/json
401Отсутствующий или недействительный Bearer-токен.
404Проект не найден.application/json
/automation/projects/123e4567-e89b-12d3-a456-426614174000PUT /automation/projects/123e4567-e89b-12d3-a456-426614174000 HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
}curl -X PUT 'http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"id":"123e4567-e89b-12d3-a456-426614174000","name":"text","notes":"text","blocks":[{"id":"text","kind":"click","label":"text","params":{},"enabled":true,"x":1,"y":1,"on_done":"next","on_fail":null,"secrets":["text"]}],"run":{"threads":1,"loops":1,"hours":1,"start":"text","profiles":["text"]},"created_at":1,"updated_at":1}'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000"
headers = {
"Authorization": f"Bearer {token}",
}
payload = {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": True,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": None,
"secrets": [
"text",
],
},
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text",
],
},
"created_at": 1,
"updated_at": 1,
}
response = requests.put(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000";
const payload = {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
};
const response = await fetch(url, {
method: "PUT",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
console.log(response.status);
console.log(await response.text());package main
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000"
body := bytes.NewBufferString(`{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
}`)
req, err := http.NewRequest("PUT", url, body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }, serde_json = "1"
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.put("http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000")
.header("Authorization", format!("Bearer {token}"))
.json(&serde_json::json!({
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
}))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Put, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000");
request.Content = new StringContent("""
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
headers = curl_slist_append(headers, "Content-Type: application/json");
const std::string body = R"json({
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
})json";
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
}{
"error": "text"
}{
"error": "text"
}Удалить проект
http://127.0.0.1:40325/automation/projects/{id}Постоянный JWT из Settings → Automation API.
200Удален.application/json
401Отсутствующий или недействительный Bearer-токен.
404Проект не найден.application/json
/automation/projects/123e4567-e89b-12d3-a456-426614174000DELETE /automation/projects/123e4567-e89b-12d3-a456-426614174000 HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X DELETE 'http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.delete(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000";
const response = await fetch(url, {
method: "DELETE",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000"
req, err := http.NewRequest("DELETE", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.delete("http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Delete, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"deleted": true,
"id": "123e4567-e89b-12d3-a456-426614174000"
}{
"error": "text"
}Дублировать проект
http://127.0.0.1:40325/automation/projects/{id}/duplicateПостоянный JWT из Settings → Automation API.
200Дублированный проект.application/json
blocksobject · AutomationBlock[]optionalShow propertiesHide properties
Встроенный тип палитры (goto, click, type, profile.create, var.set, ...) или module:<module id>:<block>.
В мобильном профиле обычные действия используют сенсорный ввод: click выполняет касание, rightClick - долгое нажатие, а scroll и swipe - жесты. hover недоступен, поскольку на мобильном устройстве нет указателя. Следующие шаги доступны только на мобильных профилях и отклоняются на компьютерах:
| Тип | Параметры | Действие |
| --- | --- | --- |
| touch.tap | selector или x+y, tapCount (1-3), timeout | Коснуться цели. |
| touch.longPress | selector или x+y, timeout | Нажать и удерживать. |
| touch.swipe | selector или x+y, dx, dy, timeout | Провести пальцем. |
| touch.drag | selector, to, holdMs, timeout | Перетащить элемент. |
| touch.pinch | scale, selector или x+y | Масштабировать двумя пальцами. Значение выше 1 уменьшает масштаб. |
| screen.rotate | angle (0/90/180/270), turnMs, into | Повернуть устройство. into сохраняет новый screen.orientation.type. |
Собственные поля шага, как их определяет палитра.
Положение на холсте. Только для макета, выполнение идет по веткам.
Ветка после выполнения шага. В простых случаях используется строка, при передаче значения - объект.
По умолчанию stop. Если продолжить после неудачного шага, действия могут выполняться не на той странице.
Имена параметров очищаются при экспорте.
runobject · AutomationRunSettingsoptionalShow propertiesHide properties
Максимальное число одновременно работающих браузеров: от 1 до 64.
Число проходов по блокам. 0 означает запуск до истечения hours.
Используется только при loops: 0.
Идентификатор блока, с которого нужно начать; пустой означает первый.
Для совместимости с проектами, сохраненными до появления профилей-блоков. При задании каждый профиль запускается в отдельном потоке.
Unix-секунды.
Unix-секунды.
401Отсутствующий или недействительный Bearer-токен.
404Проект не найден.application/json
/automation/projects/123e4567-e89b-12d3-a456-426614174000/duplicatePOST /automation/projects/123e4567-e89b-12d3-a456-426614174000/duplicate HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X POST 'http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/duplicate' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/duplicate"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.post(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/duplicate";
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/duplicate"
req, err := http.NewRequest("POST", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.post("http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/duplicate")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/duplicate");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/duplicate");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
}{
"error": "text"
}Экспортировать пакет проектов
http://127.0.0.1:40325/automation/projects/{id}/exportПараметры проекта, помеченные как секретные, при выходе очищаются, поэтому пакет можно передать, не взяв с собой пароль. Импортирующая сторона снова их запрашивает.
Постоянный JWT из Settings → Automation API.
200Экспортный пакет.application/json
Пакет проекта для переноса на другую машину.
Импорт отклоняет неизвестную версию формата.
Unix-секунды.
projectobject · AutomationProjectoptionalShow propertiesHide properties
blocksobject · AutomationBlock[]optionalShow propertiesHide properties
Встроенный тип палитры (goto, click, type, profile.create, var.set, ...) или module:<module id>:<block>.
В мобильном профиле обычные действия используют сенсорный ввод: click выполняет касание, rightClick - долгое нажатие, а scroll и swipe - жесты. hover недоступен, поскольку на мобильном устройстве нет указателя. Следующие шаги доступны только на мобильных профилях и отклоняются на компьютерах:
| Тип | Параметры | Действие |
| --- | --- | --- |
| touch.tap | selector или x+y, tapCount (1-3), timeout | Коснуться цели. |
| touch.longPress | selector или x+y, timeout | Нажать и удерживать. |
| touch.swipe | selector или x+y, dx, dy, timeout | Провести пальцем. |
| touch.drag | selector, to, holdMs, timeout | Перетащить элемент. |
| touch.pinch | scale, selector или x+y | Масштабировать двумя пальцами. Значение выше 1 уменьшает масштаб. |
| screen.rotate | angle (0/90/180/270), turnMs, into | Повернуть устройство. into сохраняет новый screen.orientation.type. |
Собственные поля шага, как их определяет палитра.
Положение на холсте. Только для макета, выполнение идет по веткам.
Ветка после выполнения шага. В простых случаях используется строка, при передаче значения - объект.
По умолчанию stop. Если продолжить после неудачного шага, действия могут выполняться не на той странице.
Имена параметров очищаются при экспорте.
runobject · AutomationRunSettingsoptionalShow propertiesHide properties
Максимальное число одновременно работающих браузеров: от 1 до 64.
Число проходов по блокам. 0 означает запуск до истечения hours.
Используется только при loops: 0.
Идентификатор блока, с которого нужно начать; пустой означает первый.
Для совместимости с проектами, сохраненными до появления профилей-блоков. При задании каждый профиль запускается в отдельном потоке.
Unix-секунды.
Unix-секунды.
Идентификаторы модулей, необходимых проекту.
module_filesobject[]optionalФайлы этих модулей переносятся внутри пакета, чтобы импортированный проект мог работать там, где он находится. Модуль, отсутствующий на диске во время экспорта, здесь не указан, но все равно назван в modules. При импорте модуль, уже установленный под тем же идентификатором, сохраняется как есть, а не перезаписывается.
Show propertiesHide properties
Файлы этих модулей переносятся внутри пакета, чтобы импортированный проект мог работать там, где он находится. Модуль, отсутствующий на диске во время экспорта, здесь не указан, но все равно назван в modules. При импорте модуль, уже установленный под тем же идентификатором, сохраняется как есть, а не перезаписывается.
Файл .wasm, заархивированный gzip, а затем base64.
needsobject[]optionalПоля, очищенные при экспорте и запрашиваемые снова при импорте.
Show propertiesHide properties
Поля, очищенные при экспорте и запрашиваемые снова при импорте.
401Отсутствующий или недействительный Bearer-токен.
404Проект не найден.application/json
/automation/projects/123e4567-e89b-12d3-a456-426614174000/exportGET /automation/projects/123e4567-e89b-12d3-a456-426614174000/export HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X GET 'http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/export' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/export"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/export";
const response = await fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/export"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.get("http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/export")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Get, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/export");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/export");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"format": 1,
"exported_at": 1,
"project": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
},
"modules": [
"text"
],
"module_files": [
{
"id": "text",
"wasm": "text"
}
],
"needs": [
{
"block_id": "text",
"label": "text",
"params": [
"text"
]
}
]
}{
"error": "text"
}Импортировать пакет проектов
http://127.0.0.1:40325/automation/importПакет поставляется как новый проект с новым идентификатором.
Постоянный JWT из Settings → Automation API.
Импорт отклоняет неизвестную версию формата.
Unix-секунды.
projectobject · AutomationProjectoptionalShow propertiesHide properties
blocksobject · AutomationBlock[]optionalShow propertiesHide properties
Встроенный тип палитры (goto, click, type, profile.create, var.set, ...) или module:<module id>:<block>.
В мобильном профиле обычные действия используют сенсорный ввод: click выполняет касание, rightClick - долгое нажатие, а scroll и swipe - жесты. hover недоступен, поскольку на мобильном устройстве нет указателя. Следующие шаги доступны только на мобильных профилях и отклоняются на компьютерах:
| Тип | Параметры | Действие |
| --- | --- | --- |
| touch.tap | selector или x+y, tapCount (1-3), timeout | Коснуться цели. |
| touch.longPress | selector или x+y, timeout | Нажать и удерживать. |
| touch.swipe | selector или x+y, dx, dy, timeout | Провести пальцем. |
| touch.drag | selector, to, holdMs, timeout | Перетащить элемент. |
| touch.pinch | scale, selector или x+y | Масштабировать двумя пальцами. Значение выше 1 уменьшает масштаб. |
| screen.rotate | angle (0/90/180/270), turnMs, into | Повернуть устройство. into сохраняет новый screen.orientation.type. |
Собственные поля шага, как их определяет палитра.
Положение на холсте. Только для макета, выполнение идет по веткам.
Ветка после выполнения шага. В простых случаях используется строка, при передаче значения - объект.
По умолчанию stop. Если продолжить после неудачного шага, действия могут выполняться не на той странице.
Имена параметров очищаются при экспорте.
runobject · AutomationRunSettingsoptionalShow propertiesHide properties
Максимальное число одновременно работающих браузеров: от 1 до 64.
Число проходов по блокам. 0 означает запуск до истечения hours.
Используется только при loops: 0.
Идентификатор блока, с которого нужно начать; пустой означает первый.
Для совместимости с проектами, сохраненными до появления профилей-блоков. При задании каждый профиль запускается в отдельном потоке.
Unix-секунды.
Unix-секунды.
Идентификаторы модулей, необходимых проекту.
module_filesobject[]optionalФайлы этих модулей переносятся внутри пакета, чтобы импортированный проект мог работать там, где он находится. Модуль, отсутствующий на диске во время экспорта, здесь не указан, но все равно назван в modules. При импорте модуль, уже установленный под тем же идентификатором, сохраняется как есть, а не перезаписывается.
Show propertiesHide properties
Файлы этих модулей переносятся внутри пакета, чтобы импортированный проект мог работать там, где он находится. Модуль, отсутствующий на диске во время экспорта, здесь не указан, но все равно назван в modules. При импорте модуль, уже установленный под тем же идентификатором, сохраняется как есть, а не перезаписывается.
Файл .wasm, заархивированный gzip, а затем base64.
needsobject[]optionalПоля, очищенные при экспорте и запрашиваемые снова при импорте.
Show propertiesHide properties
Поля, очищенные при экспорте и запрашиваемые снова при импорте.
200Импортированный проект.application/json
blocksobject · AutomationBlock[]optionalShow propertiesHide properties
Встроенный тип палитры (goto, click, type, profile.create, var.set, ...) или module:<module id>:<block>.
В мобильном профиле обычные действия используют сенсорный ввод: click выполняет касание, rightClick - долгое нажатие, а scroll и swipe - жесты. hover недоступен, поскольку на мобильном устройстве нет указателя. Следующие шаги доступны только на мобильных профилях и отклоняются на компьютерах:
| Тип | Параметры | Действие |
| --- | --- | --- |
| touch.tap | selector или x+y, tapCount (1-3), timeout | Коснуться цели. |
| touch.longPress | selector или x+y, timeout | Нажать и удерживать. |
| touch.swipe | selector или x+y, dx, dy, timeout | Провести пальцем. |
| touch.drag | selector, to, holdMs, timeout | Перетащить элемент. |
| touch.pinch | scale, selector или x+y | Масштабировать двумя пальцами. Значение выше 1 уменьшает масштаб. |
| screen.rotate | angle (0/90/180/270), turnMs, into | Повернуть устройство. into сохраняет новый screen.orientation.type. |
Собственные поля шага, как их определяет палитра.
Положение на холсте. Только для макета, выполнение идет по веткам.
Ветка после выполнения шага. В простых случаях используется строка, при передаче значения - объект.
По умолчанию stop. Если продолжить после неудачного шага, действия могут выполняться не на той странице.
Имена параметров очищаются при экспорте.
runobject · AutomationRunSettingsoptionalShow propertiesHide properties
Максимальное число одновременно работающих браузеров: от 1 до 64.
Число проходов по блокам. 0 означает запуск до истечения hours.
Используется только при loops: 0.
Идентификатор блока, с которого нужно начать; пустой означает первый.
Для совместимости с проектами, сохраненными до появления профилей-блоков. При задании каждый профиль запускается в отдельном потоке.
Unix-секунды.
Unix-секунды.
400Неверный пакет или неподдерживаемая версия формата.application/json
401Отсутствующий или недействительный Bearer-токен.
/automation/importPOST /automation/import HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
{
"format": 1,
"exported_at": 1,
"project": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
},
"modules": [
"text"
],
"module_files": [
{
"id": "text",
"wasm": "text"
}
],
"needs": [
{
"block_id": "text",
"label": "text",
"params": [
"text"
]
}
]
}curl -X POST 'http://127.0.0.1:40325/automation/import' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"format":1,"exported_at":1,"project":{"id":"123e4567-e89b-12d3-a456-426614174000","name":"text","notes":"text","blocks":[{"id":"text","kind":"click","label":"text","params":{},"enabled":true,"x":1,"y":1,"on_done":"next","on_fail":null,"secrets":["text"]}],"run":{"threads":1,"loops":1,"hours":1,"start":"text","profiles":["text"]},"created_at":1,"updated_at":1},"modules":["text"],"module_files":[{"id":"text","wasm":"text"}],"needs":[{"block_id":"text","label":"text","params":["text"]}]}'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/import"
headers = {
"Authorization": f"Bearer {token}",
}
payload = {
"format": 1,
"exported_at": 1,
"project": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": True,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": None,
"secrets": [
"text",
],
},
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text",
],
},
"created_at": 1,
"updated_at": 1,
},
"modules": [
"text",
],
"module_files": [
{
"id": "text",
"wasm": "text",
},
],
"needs": [
{
"block_id": "text",
"label": "text",
"params": [
"text",
],
},
],
}
response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/import";
const payload = {
"format": 1,
"exported_at": 1,
"project": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
},
"modules": [
"text"
],
"module_files": [
{
"id": "text",
"wasm": "text"
}
],
"needs": [
{
"block_id": "text",
"label": "text",
"params": [
"text"
]
}
]
};
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
console.log(response.status);
console.log(await response.text());package main
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/import"
body := bytes.NewBufferString(`{
"format": 1,
"exported_at": 1,
"project": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
},
"modules": [
"text"
],
"module_files": [
{
"id": "text",
"wasm": "text"
}
],
"needs": [
{
"block_id": "text",
"label": "text",
"params": [
"text"
]
}
]
}`)
req, err := http.NewRequest("POST", url, body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }, serde_json = "1"
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.post("http://127.0.0.1:40325/automation/import")
.header("Authorization", format!("Bearer {token}"))
.json(&serde_json::json!({
"format": 1,
"exported_at": 1,
"project": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
},
"modules": [
"text"
],
"module_files": [
{
"id": "text",
"wasm": "text"
}
],
"needs": [
{
"block_id": "text",
"label": "text",
"params": [
"text"
]
}
]
}))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:40325/automation/import");
request.Content = new StringContent("""
{
"format": 1,
"exported_at": 1,
"project": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
},
"modules": [
"text"
],
"module_files": [
{
"id": "text",
"wasm": "text"
}
],
"needs": [
{
"block_id": "text",
"label": "text",
"params": [
"text"
]
}
]
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
headers = curl_slist_append(headers, "Content-Type: application/json");
const std::string body = R"json({
"format": 1,
"exported_at": 1,
"project": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
},
"modules": [
"text"
],
"module_files": [
{
"id": "text",
"wasm": "text"
}
],
"needs": [
{
"block_id": "text",
"label": "text",
"params": [
"text"
]
}
]
})json";
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/import");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"blocks": [
{
"id": "text",
"kind": "click",
"label": "text",
"params": {},
"enabled": true,
"x": 1,
"y": 1,
"on_done": "next",
"on_fail": null,
"secrets": [
"text"
]
}
],
"run": {
"threads": 1,
"loops": 1,
"hours": 1,
"start": "text",
"profiles": [
"text"
]
},
"created_at": 1,
"updated_at": 1
}{
"error": "text"
}Начать проект
http://127.0.0.1:40325/automation/projects/{id}/runЗапускает проект и немедленно возвращается. Блоки проекта запускают необходимые браузеры. Используйте /status для отслеживания прогресса.
Возвращает 400, если проект уже запущен или не имеет включенных шагов.
Постоянный JWT из Settings → Automation API.
200Проект стартовал.application/json
400Проект уже запущен или не имеет включенных шагов.application/json
401Отсутствующий или недействительный Bearer-токен.
404Проект не найден.application/json
501Эта сборка не поддерживает автоматизацию.application/json
/automation/projects/123e4567-e89b-12d3-a456-426614174000/runPOST /automation/projects/123e4567-e89b-12d3-a456-426614174000/run HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X POST 'http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/run' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/run"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.post(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/run";
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/run"
req, err := http.NewRequest("POST", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.post("http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/run")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/run");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/run");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"project_id": "123e4567-e89b-12d3-a456-426614174000",
"running": true
}{
"error": "text"
}{
"error": "text"
}{
"error": "text"
}Остановить проект
http://127.0.0.1:40325/automation/projects/{id}/stopЗапрашивает остановку запуска. Каждый браузер завершает текущий шаг перед закрытием. Используйте /status для отслеживания поля running.
Постоянный JWT из Settings → Automation API.
200Стоп просили.application/json
401Отсутствующий или недействительный Bearer-токен.
501Эта сборка не поддерживает автоматизацию.application/json
/automation/projects/123e4567-e89b-12d3-a456-426614174000/stopPOST /automation/projects/123e4567-e89b-12d3-a456-426614174000/stop HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X POST 'http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/stop' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/stop"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.post(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/stop";
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/stop"
req, err := http.NewRequest("POST", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.post("http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/stop")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/stop");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/stop");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"project_id": "123e4567-e89b-12d3-a456-426614174000",
"stopping": true
}{
"error": "text"
}Получить статус запуска проекта
http://127.0.0.1:40325/automation/projects/{id}/statusВозвращает null, если проект не запущен и не запускался с момента запуска лаунчера. log содержит последние записи, показанные в окне запусков. Полный журнал хранится в automation-runs/.
Постоянный JWT из Settings → Automation API.
200Статус выполнения или `null`.application/json
401Отсутствующий или недействительный Bearer-токен.
501Эта сборка не поддерживает автоматизацию.application/json
/automation/projects/123e4567-e89b-12d3-a456-426614174000/statusGET /automation/projects/123e4567-e89b-12d3-a456-426614174000/status HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X GET 'http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/status' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/status"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/status";
const response = await fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/status"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.get("http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/status")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Get, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/status");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/projects/123e4567-e89b-12d3-a456-426614174000/status");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"project_id": "123e4567-e89b-12d3-a456-426614174000",
"project_name": "text",
"started_at": 1,
"running": true,
"workers": [
{
"profile_id": "text",
"profile_name": "text",
"pass": 1,
"step": 1,
"steps_total": 1,
"status": "queued",
"note": "text"
}
],
"log": [
"text"
]
}{
"error": "text"
}Список активных запусков
http://127.0.0.1:40325/automation/runsПостоянный JWT из Settings → Automation API.
200Активный список запусков.application/json
Unix-секунды.
workersobject · AutomationWorker[]optionalShow propertiesHide properties
Нумерация с 1; значение 0 означает, что первый проход еще не начался.
queuedstartingrunningdonefailedstoppedПоследние записи, показанные в окне запусков. Полный журнал хранится в automation-runs/.
401Отсутствующий или недействительный Bearer-токен.
501Эта сборка не поддерживает автоматизацию.application/json
/automation/runsGET /automation/runs HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X GET 'http://127.0.0.1:40325/automation/runs' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/runs"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/runs";
const response = await fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/runs"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.get("http://127.0.0.1:40325/automation/runs")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Get, "http://127.0.0.1:40325/automation/runs");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/runs");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}[
{
"project_id": "123e4567-e89b-12d3-a456-426614174000",
"project_name": "text",
"started_at": 1,
"running": true,
"workers": [
{
"profile_id": "text",
"profile_name": "text",
"pass": 1,
"step": 1,
"steps_total": 1,
"status": "queued",
"note": "text"
}
],
"log": [
"text"
]
}
]{
"error": "text"
}Список установленных модулей
http://127.0.0.1:40325/automation/modulesВозвращает установленные оператором модули WebAssembly. Каждый модуль добавляет блоки вида module:<module id>:<block>. Модули передают действия исполнителю и не обращаются к странице напрямую.
Постоянный JWT из Settings → Automation API.
200Список модулей.application/json
Имя файла без расширения и префикс для типов блоков модуля.
Дескрипторы блоков имеют ту же форму, что и встроенная палитра.
Пусто при успешной загрузке модуля, иначе содержит причину ошибки.
401Отсутствующий или недействительный Bearer-токен.
501Эта сборка не поддерживает автоматизацию.application/json
/automation/modulesGET /automation/modules HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X GET 'http://127.0.0.1:40325/automation/modules' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/modules"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/modules";
const response = await fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/modules"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.get("http://127.0.0.1:40325/automation/modules")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Get, "http://127.0.0.1:40325/automation/modules");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/modules");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}[
{
"id": "text",
"name": "text",
"path": "text",
"blocks": [
{}
],
"error": "text"
}
]{
"error": "text"
}Установить модуль
http://127.0.0.1:40325/automation/modulespath должен указывать на локальный файл .wasm на хосте средства запуска. Модули содержат собственный код, созданный оператором.
Постоянный JWT из Settings → Automation API.
200Установленный модуль.application/json
Имя файла без расширения и префикс для типов блоков модуля.
Дескрипторы блоков имеют ту же форму, что и встроенная палитра.
Пусто при успешной загрузке модуля, иначе содержит причину ошибки.
400Отсутствует путь или неподдерживаемый файл модуля.application/json
401Отсутствующий или недействительный Bearer-токен.
501Эта сборка не поддерживает автоматизацию.application/json
/automation/modulesPOST /automation/modules HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
{
"path": "/home/me/module.wasm"
}curl -X POST 'http://127.0.0.1:40325/automation/modules' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"path":"/home/me/module.wasm"}'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/modules"
headers = {
"Authorization": f"Bearer {token}",
}
payload = {
"path": "/home/me/module.wasm",
}
response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/modules";
const payload = {
"path": "/home/me/module.wasm"
};
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
console.log(response.status);
console.log(await response.text());package main
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/modules"
body := bytes.NewBufferString(`{
"path": "/home/me/module.wasm"
}`)
req, err := http.NewRequest("POST", url, body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }, serde_json = "1"
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.post("http://127.0.0.1:40325/automation/modules")
.header("Authorization", format!("Bearer {token}"))
.json(&serde_json::json!({
"path": "/home/me/module.wasm"
}))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:40325/automation/modules");
request.Content = new StringContent("""
{
"path": "/home/me/module.wasm"
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
headers = curl_slist_append(headers, "Content-Type: application/json");
const std::string body = R"json({
"path": "/home/me/module.wasm"
})json";
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/modules");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"id": "text",
"name": "text",
"path": "text",
"blocks": [
{}
],
"error": "text"
}{
"error": "text"
}{
"error": "text"
}Удалить модуль
http://127.0.0.1:40325/automation/modules/{id}Проекты, использующие модуль, перестают работать. Существующие определения проекта не изменяются.
Постоянный JWT из Settings → Automation API.
200Удаленный.application/json
401Отсутствующий или недействительный Bearer-токен.
404Модуль не найден.application/json
501Эта сборка не поддерживает автоматизацию.application/json
/automation/modules/textDELETE /automation/modules/text HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X DELETE 'http://127.0.0.1:40325/automation/modules/text' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# Постоянный JWT из Settings → Automation API.
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/automation/modules/text"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.delete(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// Постоянный JWT из Settings → Automation API.
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/automation/modules/text";
const response = await fetch(url, {
method: "DELETE",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// Постоянный JWT из Settings → Automation API.
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/automation/modules/text"
req, err := http.NewRequest("DELETE", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Постоянный JWT из Settings → Automation API.
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.delete("http://127.0.0.1:40325/automation/modules/text")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// Постоянный JWT из Settings → Automation API.
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Delete, "http://127.0.0.1:40325/automation/modules/text");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// Постоянный JWT из Settings → Automation API.
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/automation/modules/text");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"deleted": true,
"id": "text"
}{
"error": "text"
}{
"error": "text"
}Обновлено