APIShardX Launcher APIAutomation

Automation

列出自动化项目

GEThttp://127.0.0.1:40325/automation/projects

保存在启动器中的每个项目及其块和运行设置。这些与桌面 Automation 部分编辑的项目相同。

Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Responses
200项目清单。application/json
idstring · uuidoptional
namestringoptional
notesstringoptional
blocksobject · AutomationBlock[]optional
Show propertiesHide properties
idstringoptional
kindstringoptional

内置调色板类型(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。 |

labelstringoptional
paramsobjectoptional

步骤自己的字段,如调色板定义的那样。

enabledboolean· default: trueoptional
xnumberoptional

画布位置。仅用于布局,执行顺序由分支决定。

ynumberoptional
on_donestring · enum | objectoptional

步骤执行后的分支目标。简单情况使用字符串,需要传值时使用对象。

on_failany · AutomationBranchoptional

默认为 stop;单击后什么也没找到,这就是运行输入错误页面的原因。

secretsstring[]optional

导出时参数名称被清空。

runobject · AutomationRunSettingsoptional
Show propertiesHide properties
threadsinteger· default: 1optional

浏览器同时运行;限制为 1-64。

loopsinteger· default: 1optional

越过街区。 0 表示运行直到 hours 启动。

hoursnumberoptional

仅当 loops 为 0 时才有意义。

startstringoptional

块 ID 开始;空的意思是第一个。

profilesstring[]optional

保留在配置文件成为块之前保存的项目;设置时各一根线。

created_atintegeroptional

Unix 秒。

updated_atintegeroptional

Unix 秒。

401缺失或无效的 Bearer 令牌。
GET/automation/projects
GET /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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;
}
200项目清单。
[
  {
    "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
  }
]

创建项目

POSThttp://127.0.0.1:40325/automation/projects
Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Body
application/json
namestringoptional

空时使用 Untitled。

Responses
200创建项目。application/json
idstring · uuidoptional
namestringoptional
notesstringoptional
blocksobject · AutomationBlock[]optional
Show propertiesHide properties
idstringoptional
kindstringoptional

内置调色板类型(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。 |

labelstringoptional
paramsobjectoptional

步骤自己的字段,如调色板定义的那样。

enabledboolean· default: trueoptional
xnumberoptional

画布位置。仅用于布局,执行顺序由分支决定。

ynumberoptional
on_donestring · enum | objectoptional

步骤执行后的分支目标。简单情况使用字符串,需要传值时使用对象。

on_failany · AutomationBranchoptional

默认为 stop;单击后什么也没找到,这就是运行输入错误页面的原因。

secretsstring[]optional

导出时参数名称被清空。

runobject · AutomationRunSettingsoptional
Show propertiesHide properties
threadsinteger· default: 1optional

浏览器同时运行;限制为 1-64。

loopsinteger· default: 1optional

越过街区。 0 表示运行直到 hours 启动。

hoursnumberoptional

仅当 loops 为 0 时才有意义。

startstringoptional

块 ID 开始;空的意思是第一个。

profilesstring[]optional

保留在配置文件成为块之前保存的项目;设置时各一根线。

created_atintegeroptional

Unix 秒。

updated_atintegeroptional

Unix 秒。

401缺失或无效的 Bearer 令牌。
POST/automation/projects
POST /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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;
}
200创建项目。
{
  "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
}

获取项目

GEThttp://127.0.0.1:40325/automation/projects/{id}
Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Path parameters
idstring · uuidrequired
Responses
200项目详情。application/json
idstring · uuidoptional
namestringoptional
notesstringoptional
blocksobject · AutomationBlock[]optional
Show propertiesHide properties
idstringoptional
kindstringoptional

内置调色板类型(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。 |

labelstringoptional
paramsobjectoptional

步骤自己的字段,如调色板定义的那样。

enabledboolean· default: trueoptional
xnumberoptional

画布位置。仅用于布局,执行顺序由分支决定。

ynumberoptional
on_donestring · enum | objectoptional

步骤执行后的分支目标。简单情况使用字符串,需要传值时使用对象。

on_failany · AutomationBranchoptional

默认为 stop;单击后什么也没找到,这就是运行输入错误页面的原因。

secretsstring[]optional

导出时参数名称被清空。

runobject · AutomationRunSettingsoptional
Show propertiesHide properties
threadsinteger· default: 1optional

浏览器同时运行;限制为 1-64。

loopsinteger· default: 1optional

越过街区。 0 表示运行直到 hours 启动。

hoursnumberoptional

仅当 loops 为 0 时才有意义。

startstringoptional

块 ID 开始;空的意思是第一个。

profilesstring[]optional

保留在配置文件成为块之前保存的项目;设置时各一根线。

created_atintegeroptional

Unix 秒。

updated_atintegeroptional

Unix 秒。

401缺失或无效的 Bearer 令牌。
404未找到项目。application/json
errorstringrequired
GET/automation/projects/123e4567-e89b-12d3-a456-426614174000
GET /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

替换项目

PUThttp://127.0.0.1:40325/automation/projects/{id}

完全替换项目。请发送 GET 返回的对象。路径中的 ID 优先于请求体中的 ID。项目不存在时返回 404;如需创建项目,请使用 POST /automation/projects。

Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Path parameters
idstring · uuidrequired
Body
application/json
idstring · uuidoptional
namestringoptional
notesstringoptional
blocksobject · AutomationBlock[]optional
Show propertiesHide properties
idstringoptional
kindstringoptional

内置调色板类型(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。 |

labelstringoptional
paramsobjectoptional

步骤自己的字段,如调色板定义的那样。

enabledboolean· default: trueoptional
xnumberoptional

画布位置。仅用于布局,执行顺序由分支决定。

ynumberoptional
on_donestring · enum | objectoptional

步骤执行后的分支目标。简单情况使用字符串,需要传值时使用对象。

on_failany · AutomationBranchoptional

默认为 stop;单击后什么也没找到,这就是运行输入错误页面的原因。

secretsstring[]optional

导出时参数名称被清空。

runobject · AutomationRunSettingsoptional
Show propertiesHide properties
threadsinteger· default: 1optional

浏览器同时运行;限制为 1-64。

loopsinteger· default: 1optional

越过街区。 0 表示运行直到 hours 启动。

hoursnumberoptional

仅当 loops 为 0 时才有意义。

startstringoptional

块 ID 开始;空的意思是第一个。

profilesstring[]optional

保留在配置文件成为块之前保存的项目;设置时各一根线。

created_atintegeroptional

Unix 秒。

updated_atintegeroptional

Unix 秒。

Responses
200已保存的项目。application/json
idstring · uuidoptional
namestringoptional
notesstringoptional
blocksobject · AutomationBlock[]optional
Show propertiesHide properties
idstringoptional
kindstringoptional

内置调色板类型(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。 |

labelstringoptional
paramsobjectoptional

步骤自己的字段,如调色板定义的那样。

enabledboolean· default: trueoptional
xnumberoptional

画布位置。仅用于布局,执行顺序由分支决定。

ynumberoptional
on_donestring · enum | objectoptional

步骤执行后的分支目标。简单情况使用字符串,需要传值时使用对象。

on_failany · AutomationBranchoptional

默认为 stop;单击后什么也没找到,这就是运行输入错误页面的原因。

secretsstring[]optional

导出时参数名称被清空。

runobject · AutomationRunSettingsoptional
Show propertiesHide properties
threadsinteger· default: 1optional

浏览器同时运行;限制为 1-64。

loopsinteger· default: 1optional

越过街区。 0 表示运行直到 hours 启动。

hoursnumberoptional

仅当 loops 为 0 时才有意义。

startstringoptional

块 ID 开始;空的意思是第一个。

profilesstring[]optional

保留在配置文件成为块之前保存的项目;设置时各一根线。

created_atintegeroptional

Unix 秒。

updated_atintegeroptional

Unix 秒。

400项目对象无效。application/json
errorstringrequired
401缺失或无效的 Bearer 令牌。
404未找到项目。application/json
errorstringrequired
PUT/automation/projects/123e4567-e89b-12d3-a456-426614174000
PUT /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

删除项目

DELhttp://127.0.0.1:40325/automation/projects/{id}
Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Path parameters
idstring · uuidrequired
Responses
200已删除。application/json
deletedbooleanoptional
idstring · uuidoptional
401缺失或无效的 Bearer 令牌。
404未找到项目。application/json
errorstringrequired
DEL/automation/projects/123e4567-e89b-12d3-a456-426614174000
DELETE /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

重复项目

POSThttp://127.0.0.1:40325/automation/projects/{id}/duplicate
Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Path parameters
idstring · uuidrequired
Responses
200重复的项目。application/json
idstring · uuidoptional
namestringoptional
notesstringoptional
blocksobject · AutomationBlock[]optional
Show propertiesHide properties
idstringoptional
kindstringoptional

内置调色板类型(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。 |

labelstringoptional
paramsobjectoptional

步骤自己的字段,如调色板定义的那样。

enabledboolean· default: trueoptional
xnumberoptional

画布位置。仅用于布局,执行顺序由分支决定。

ynumberoptional
on_donestring · enum | objectoptional

步骤执行后的分支目标。简单情况使用字符串,需要传值时使用对象。

on_failany · AutomationBranchoptional

默认为 stop;单击后什么也没找到,这就是运行输入错误页面的原因。

secretsstring[]optional

导出时参数名称被清空。

runobject · AutomationRunSettingsoptional
Show propertiesHide properties
threadsinteger· default: 1optional

浏览器同时运行;限制为 1-64。

loopsinteger· default: 1optional

越过街区。 0 表示运行直到 hours 启动。

hoursnumberoptional

仅当 loops 为 0 时才有意义。

startstringoptional

块 ID 开始;空的意思是第一个。

profilesstring[]optional

保留在配置文件成为块之前保存的项目;设置时各一根线。

created_atintegeroptional

Unix 秒。

updated_atintegeroptional

Unix 秒。

401缺失或无效的 Bearer 令牌。
404未找到项目。application/json
errorstringrequired
POST/automation/projects/123e4567-e89b-12d3-a456-426614174000/duplicate
POST /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

导出项目包

GEThttp://127.0.0.1:40325/automation/projects/{id}/export

标记为秘密的项目的参数在退出时被清空,因此可以在不带密码的情况下传递包。进口方再次索要。

Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Path parameters
idstring · uuidrequired
Responses
200导出捆绑。application/json

一个项目正在转移到另一台机器上。

formatintegeroptional

导入拒绝它不知道的号码。

exported_atintegeroptional

Unix 秒。

projectobject · AutomationProjectoptional
Show propertiesHide properties
idstring · uuidoptional
namestringoptional
notesstringoptional
blocksobject · AutomationBlock[]optional
Show propertiesHide properties
idstringoptional
kindstringoptional

内置调色板类型(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。 |

labelstringoptional
paramsobjectoptional

步骤自己的字段,如调色板定义的那样。

enabledboolean· default: trueoptional
xnumberoptional

画布位置。仅用于布局,执行顺序由分支决定。

ynumberoptional
on_donestring · enum | objectoptional

步骤执行后的分支目标。简单情况使用字符串,需要传值时使用对象。

on_failany · AutomationBranchoptional

默认为 stop;单击后什么也没找到,这就是运行输入错误页面的原因。

secretsstring[]optional

导出时参数名称被清空。

runobject · AutomationRunSettingsoptional
Show propertiesHide properties
threadsinteger· default: 1optional

浏览器同时运行;限制为 1-64。

loopsinteger· default: 1optional

越过街区。 0 表示运行直到 hours 启动。

hoursnumberoptional

仅当 loops 为 0 时才有意义。

startstringoptional

块 ID 开始;空的意思是第一个。

profilesstring[]optional

保留在配置文件成为块之前保存的项目;设置时各一根线。

created_atintegeroptional

Unix 秒。

updated_atintegeroptional

Unix 秒。

modulesstring[]optional

模块 ID 需要的步骤。

module_filesobject[]optional

这些模块的文件位于捆绑包内,以便导入的项目可以在其所在的位置运行。导出时磁盘中丢失的模块在此处被忽略,但仍以 modules 命名。导入时,已安装在同一 ID 下的模块将保持原样,而不是被覆盖。

Show propertiesHide properties
idstringoptional
wasmstringoptional

.wasm 经过 gzip 压缩,然后进行 Base64 处理。

needsobject[]optional

导出的内容被清空,因此导入可以准确地要求该内容。

Show propertiesHide properties
block_idstringoptional
labelstringoptional
paramsstring[]optional
401缺失或无效的 Bearer 令牌。
404未找到项目。application/json
errorstringrequired
GET/automation/projects/123e4567-e89b-12d3-a456-426614174000/export
GET /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

导入项目包

POSThttp://127.0.0.1:40325/automation/import

该捆绑包作为具有新 ID 的新项目到达。

Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Body
application/json
formatintegeroptional

导入拒绝它不知道的号码。

exported_atintegeroptional

Unix 秒。

projectobject · AutomationProjectoptional
Show propertiesHide properties
idstring · uuidoptional
namestringoptional
notesstringoptional
blocksobject · AutomationBlock[]optional
Show propertiesHide properties
idstringoptional
kindstringoptional

内置调色板类型(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。 |

labelstringoptional
paramsobjectoptional

步骤自己的字段,如调色板定义的那样。

enabledboolean· default: trueoptional
xnumberoptional

画布位置。仅用于布局,执行顺序由分支决定。

ynumberoptional
on_donestring · enum | objectoptional

步骤执行后的分支目标。简单情况使用字符串,需要传值时使用对象。

on_failany · AutomationBranchoptional

默认为 stop;单击后什么也没找到,这就是运行输入错误页面的原因。

secretsstring[]optional

导出时参数名称被清空。

runobject · AutomationRunSettingsoptional
Show propertiesHide properties
threadsinteger· default: 1optional

浏览器同时运行;限制为 1-64。

loopsinteger· default: 1optional

越过街区。 0 表示运行直到 hours 启动。

hoursnumberoptional

仅当 loops 为 0 时才有意义。

startstringoptional

块 ID 开始;空的意思是第一个。

profilesstring[]optional

保留在配置文件成为块之前保存的项目;设置时各一根线。

created_atintegeroptional

Unix 秒。

updated_atintegeroptional

Unix 秒。

modulesstring[]optional

模块 ID 需要的步骤。

module_filesobject[]optional

这些模块的文件位于捆绑包内,以便导入的项目可以在其所在的位置运行。导出时磁盘中丢失的模块在此处被忽略,但仍以 modules 命名。导入时,已安装在同一 ID 下的模块将保持原样,而不是被覆盖。

Show propertiesHide properties
idstringoptional
wasmstringoptional

.wasm 经过 gzip 压缩,然后进行 Base64 处理。

needsobject[]optional

导出的内容被清空,因此导入可以准确地要求该内容。

Show propertiesHide properties
block_idstringoptional
labelstringoptional
paramsstring[]optional
Responses
200导入的项目。application/json
idstring · uuidoptional
namestringoptional
notesstringoptional
blocksobject · AutomationBlock[]optional
Show propertiesHide properties
idstringoptional
kindstringoptional

内置调色板类型(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。 |

labelstringoptional
paramsobjectoptional

步骤自己的字段,如调色板定义的那样。

enabledboolean· default: trueoptional
xnumberoptional

画布位置。仅用于布局,执行顺序由分支决定。

ynumberoptional
on_donestring · enum | objectoptional

步骤执行后的分支目标。简单情况使用字符串,需要传值时使用对象。

on_failany · AutomationBranchoptional

默认为 stop;单击后什么也没找到,这就是运行输入错误页面的原因。

secretsstring[]optional

导出时参数名称被清空。

runobject · AutomationRunSettingsoptional
Show propertiesHide properties
threadsinteger· default: 1optional

浏览器同时运行;限制为 1-64。

loopsinteger· default: 1optional

越过街区。 0 表示运行直到 hours 启动。

hoursnumberoptional

仅当 loops 为 0 时才有意义。

startstringoptional

块 ID 开始;空的意思是第一个。

profilesstring[]optional

保留在配置文件成为块之前保存的项目;设置时各一根线。

created_atintegeroptional

Unix 秒。

updated_atintegeroptional

Unix 秒。

400捆绑包无效或格式版本不受支持。application/json
errorstringrequired
401缺失或无效的 Bearer 令牌。
POST/automation/import
POST /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

启动项目

POSThttp://127.0.0.1:40325/automation/projects/{id}/run

启动项目并立即返回。项目中的模块会启动所需的浏览器。使用 /status 查看进度。

项目已在运行或没有启用的步骤时,返回 400。

Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Path parameters
idstring · uuidrequired
Responses
200项目开始了。application/json
project_idstring · uuidoptional
runningbooleanoptional
400项目已在运行或没有启用的步骤。application/json
errorstringrequired
401缺失或无效的 Bearer 令牌。
404未找到项目。application/json
errorstringrequired
501此版本不支持自动化。application/json
errorstringrequired
POST/automation/projects/123e4567-e89b-12d3-a456-426614174000/run
POST /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

停止项目

POSThttp://127.0.0.1:40325/automation/projects/{id}/stop

请求停止运行。每个浏览器会先完成当前步骤再关闭,因此接口返回后运行不会立即消失。请通过 /status 查看 running 字段。

Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Path parameters
idstring · uuidrequired
Responses
200要求停止。application/json
project_idstring · uuidoptional
stoppingbooleanoptional
401缺失或无效的 Bearer 令牌。
501此版本不支持自动化。application/json
errorstringrequired
POST/automation/projects/123e4567-e89b-12d3-a456-426614174000/stop
POST /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

获取项目运行状态

GEThttp://127.0.0.1:40325/automation/projects/{id}/status

如果项目未运行且自启动程序启动后未运行,则返回 null。 log 包含队列窗口中显示的最近条目。完整日志存储在 automation-runs/ 下。

Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Path parameters
idstring · uuidrequired
Responses
200运行状态或 `null`。application/json
401缺失或无效的 Bearer 令牌。
501此版本不支持自动化。application/json
errorstringrequired
GET/automation/projects/123e4567-e89b-12d3-a456-426614174000/status
GET /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

列出活动运行

GEThttp://127.0.0.1:40325/automation/runs
Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Responses
200活动运行列表。application/json
project_idstring · uuidoptional
project_namestringoptional
started_atintegeroptional

Unix 秒。

runningbooleanoptional
workersobject · AutomationWorker[]optional
Show propertiesHide properties
profile_idstringoptional
profile_namestringoptional
passintegeroptional

1 为基础; 0 在第一遍开始之前。

stepintegeroptional
steps_totalintegeroptional
statusstring · enumoptional
Possible values:queuedstartingrunningdonefailedstopped
notestringoptional
logstring[]optional

机队窗口显示的尾部;整个日志位于磁盘上的 automation-runs/ 下。

401缺失或无效的 Bearer 令牌。
501此版本不支持自动化。application/json
errorstringrequired
GET/automation/runs
GET /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

列出已安装的模块

GEThttp://127.0.0.1:40325/automation/modules

返回操作者安装的 WebAssembly 模块。每个模块都会添加类型为 module:<module id>:<block> 的模块。模块返回由执行器执行的动作,不会直接访问页面。

Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Responses
200模块列表。application/json
idstringoptional

文件茎;还有其每个块类型所携带的前缀。

namestringoptional
pathstringoptional
blocksobject[]optional

块描述符,形状与内置调色板相同。

errorstringoptional

模块加载成功时为空,否则为错误原因。

401缺失或无效的 Bearer 令牌。
501此版本不支持自动化。application/json
errorstringrequired
GET/automation/modules
GET /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

安装模块

POSThttp://127.0.0.1:40325/automation/modules

path 必须指向启动器所在机器上的本地 .wasm 文件。模块包含由操作者构建的原生代码。

Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Body
application/json
pathstringrequired
Responses
200安装的模块。application/json
idstringoptional

文件茎;还有其每个块类型所携带的前缀。

namestringoptional
pathstringoptional
blocksobject[]optional

块描述符,形状与内置调色板相同。

errorstringoptional

模块加载成功时为空,否则为错误原因。

400缺少路径或不受支持的模块文件。application/json
errorstringrequired
401缺失或无效的 Bearer 令牌。
501此版本不支持自动化。application/json
errorstringrequired
POST/automation/modules
POST /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

移除模块

DELhttp://127.0.0.1:40325/automation/modules/{id}

使用该模块的项目停止工作。现有项目定义不会被修改。

Authorizations
bearerAuth
Authorizationstringrequired

来自 Settings → Automation API 的永久 JWT。

Path parameters
idstringrequired
Responses
200已删除。application/json
deletedbooleanoptional
idstringoptional
401缺失或无效的 Bearer 令牌。
404未找到模块。application/json
errorstringrequired
501此版本不支持自动化。application/json
errorstringrequired
DEL/automation/modules/text
DELETE /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

# 来自 Settings → Automation API 的永久 JWT。
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)
// 来自 Settings → Automation API 的永久 JWT。
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() {
	// 来自 Settings → Automation API 的永久 JWT。
	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>> {
    // 来自 Settings → Automation API 的永久 JWT。
    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()
    {
        // 来自 Settings → Automation API 的永久 JWT。
        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() {
    // 来自 Settings → Automation API 的永久 JWT。
    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"
}

最后更新

本页内容