156 lines
5.6 KiB
Markdown
156 lines
5.6 KiB
Markdown
|
|
# OpenAPI Documentation Navigation
|
||
|
|
|
||
|
|
Use this reference to inspect E10 OpenAPI documentation pages.
|
||
|
|
|
||
|
|
## Documentation homepage
|
||
|
|
|
||
|
|
Navigate to:
|
||
|
|
|
||
|
|
```text
|
||
|
|
https://<E10_BASE>/sp/openapi/base/doc/index
|
||
|
|
```
|
||
|
|
|
||
|
|
E10 documentation pages are React SPA pages. Plain `curl` usually retrieves only a shell page. Use a rendered browser session and wait for JavaScript content.
|
||
|
|
|
||
|
|
```python
|
||
|
|
new_tab("https://<E10_BASE>/sp/openapi/base/doc/index")
|
||
|
|
wait(8)
|
||
|
|
wait_for_load()
|
||
|
|
wait(3)
|
||
|
|
capture_screenshot("/tmp/e10_api_doc_home.png")
|
||
|
|
```
|
||
|
|
|
||
|
|
## Extract category links
|
||
|
|
|
||
|
|
The documentation homepage exposes categories through `<a>` tags. Extract link text and href values, then navigate directly to the target href instead of clicking.
|
||
|
|
|
||
|
|
```python
|
||
|
|
import json
|
||
|
|
links = json.loads(js('''
|
||
|
|
var all = document.querySelectorAll("a");
|
||
|
|
var result = [];
|
||
|
|
for (var i = 0; i < all.length; i++) {
|
||
|
|
var a = all[i];
|
||
|
|
var txt = a.textContent.trim();
|
||
|
|
if (txt.length > 0 && txt.length < 50 && a.href) {
|
||
|
|
result.push({text: txt, href: a.href});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return JSON.stringify(result);
|
||
|
|
'''))
|
||
|
|
for l in links:
|
||
|
|
print(l["text"], "->", l["href"])
|
||
|
|
```
|
||
|
|
|
||
|
|
**Pitfall**: The href values extracted from the doc index page (e.g. `https://<E10_BASE>/sp/opendoc/freepass/.../zh_cn/840714220321120257`) may return 404 when navigated to directly. These URLs appear to be for a separate doc viewer that is not directly accessible from the OpenAPI docs SPA. Instead, always navigate through the SPA sidebar — first load the auth/page page (`/sp/opendoc/freepass/.../zh_cn/840673181800431617` which is the "认证" page), then use sidebar JS clicks to reach other API docs. Do NOT attempt to construct doc page URLs from the index page links.
|
||
|
|
|
||
|
|
## Read rendered page text
|
||
|
|
|
||
|
|
After navigating to a category or API page, extract `document.body.innerText`. Long pages may need scrolling and repeated extraction.
|
||
|
|
|
||
|
|
```python
|
||
|
|
content = js("document.body.innerText")
|
||
|
|
print(content[:15000])
|
||
|
|
```
|
||
|
|
|
||
|
|
If content appears incomplete:
|
||
|
|
|
||
|
|
```python
|
||
|
|
js("window.scrollBy(0, 800)")
|
||
|
|
wait(2)
|
||
|
|
print(js("document.body.innerText")[8000:15000])
|
||
|
|
```
|
||
|
|
|
||
|
|
## Sidebar navigation (SPA — JS click required)
|
||
|
|
|
||
|
|
The documentation page is a React SPA. Sidebar tree items use class `.ui-tree-bar` and do not respond reliably to ref-based `browser_click`. Use JavaScript to expand categories and navigate to sub-items.
|
||
|
|
|
||
|
|
### Expand a category
|
||
|
|
|
||
|
|
```python
|
||
|
|
# Expand "工作流程" category
|
||
|
|
js('''
|
||
|
|
(function() {
|
||
|
|
var items = document.querySelectorAll(".ui-tree-bar");
|
||
|
|
for (var i = 0; i < items.length; i++) {
|
||
|
|
if (items[i].textContent.trim() === "工作流程") {
|
||
|
|
items[i].click();
|
||
|
|
return "expanded";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return "not found";
|
||
|
|
})();
|
||
|
|
''')
|
||
|
|
```
|
||
|
|
|
||
|
|
### Navigate to a sub-item
|
||
|
|
|
||
|
|
After expanding the parent category, navigate by clicking on the sub-item text element (class `.ui-tree-node`):
|
||
|
|
|
||
|
|
```python
|
||
|
|
# Click "创建流程实例" sub-item
|
||
|
|
js('''
|
||
|
|
(function() {
|
||
|
|
var items = document.querySelectorAll(".ui-tree-bar");
|
||
|
|
for (var i = 0; i < items.length; i++) {
|
||
|
|
if (items[i].textContent.trim() === "创建流程实例") {
|
||
|
|
items[i].click();
|
||
|
|
return "clicked";
|
||
|
|
}
|
||
|
|
// Also try clicking the .ui-tree-node child
|
||
|
|
var node = items[i].querySelector(".ui-tree-node");
|
||
|
|
if (node && node.textContent.trim() === "创建流程实例") {
|
||
|
|
node.click();
|
||
|
|
return "clicked node";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return "not found";
|
||
|
|
})();
|
||
|
|
''')
|
||
|
|
```
|
||
|
|
|
||
|
|
The sub-items appear as `<li>` elements with class `.ui-tree-bar` at `level=2` inside the parent category's `<ul>`. Ref-based clicking (`browser_click` on `@eNNN`) is unreliable for these SPA elements — prefer JS `.click()` through `browser_console`.
|
||
|
|
|
||
|
|
### Content extraction after navigation
|
||
|
|
|
||
|
|
After clicking a sidebar item, verify the main content updated by checking `document.body.innerText.length` — it should grow significantly. Then extract the API documentation from the second occurrence of the item name (the first is the sidebar label itself).
|
||
|
|
|
||
|
|
```python
|
||
|
|
# Find the second occurrence (main content, not sidebar)
|
||
|
|
idx = js('document.body.innerText.indexOf("创建流程实例", document.body.innerText.indexOf("创建流程实例") + 6)')
|
||
|
|
content = js('document.body.innerText.substring(' + str(idx) + ')')
|
||
|
|
```
|
||
|
|
|
||
|
|
## Avoid confusing API names
|
||
|
|
|
||
|
|
Workflow-related documentation commonly contains similar names:
|
||
|
|
|
||
|
|
- `新增流程`: creates a workflow definition or template. This is an administrator operation and is not the external integration target.
|
||
|
|
- `创建流程实例` or APIs under `工作流程`: creates workflow instances. Use this for external system integration.
|
||
|
|
|
||
|
|
Note: the OpenAPI doc endpoint for creating workflow instances is `doCreateRequest` (`/papi/openapi/api/workflow/core/paService/v2/doCreateRequest`). The sidebar label is "创建流程实例" but the page title may show "新增流程" — they refer to the same API. Do not confuse with the "新增流程" sidebar item under "业务表单" which is for form template creation.
|
||
|
|
|
||
|
|
## OAuth2 documentation
|
||
|
|
|
||
|
|
E10 OpenAPI authentication is OAuth2 code-to-token flow. It is not a Bearer-token-header pattern.
|
||
|
|
|
||
|
|
Document these endpoints when relevant:
|
||
|
|
|
||
|
|
```text
|
||
|
|
POST /papi/openapi/oauth2/authorize
|
||
|
|
POST /papi/openapi/oauth2/access_token
|
||
|
|
```
|
||
|
|
|
||
|
|
The `access_token` is passed as a request-body parameter in business API calls.
|
||
|
|
|
||
|
|
## File upload documentation
|
||
|
|
|
||
|
|
If a workflow contains attachment or file fields, inspect file upload documentation. It is typically under a knowledge-documentation or file-upload category, not necessarily a top-level homepage item.
|
||
|
|
|
||
|
|
The usual pattern is:
|
||
|
|
|
||
|
|
1. Call file upload API to obtain a file identifier.
|
||
|
|
2. Reference the file identifier in business API payload fields through `dataOptions`, including file-specific metadata.
|
||
|
|
|
||
|
|
Only include file upload prerequisites when the target API or workflow fields require attachments.
|