140 lines
4.9 KiB
Markdown
140 lines
4.9 KiB
Markdown
---
|
||
name: itfx-prefix-script
|
||
description: >-
|
||
Generates InterfaceForward (接口通/itfx) PrefixScript C# snippets for InterfaceMap
|
||
that compute API signatures (MD5/SHA/HMAC) and write to Header/Query/Body.
|
||
Use when the user asks for 前置脚本, 签名脚本, PrefixScript, InterfaceMap script,
|
||
itfx signature, or Natasha forward script.
|
||
---
|
||
|
||
# itfx 接口映射前置脚本生成
|
||
|
||
为 **InterfaceForward / 接口通** 的 **InterfaceMap → PrefixScript** 生成可在 Natasha 运行时直接执行的 C# 脚本。
|
||
|
||
## 何时使用
|
||
|
||
- 用户要生成/修改 **前置脚本**(非后置 PostfixScript)
|
||
- 第三方 API 需要 **签名、鉴权头、动态 token**
|
||
- 在 OMS「接口映射」页面保存 `prefixScript` 字段
|
||
|
||
## 执行时机(必须遵守)
|
||
|
||
单次转发流水线:
|
||
|
||
```
|
||
InParamRestructure(参数树映射)
|
||
→ ReplacePlaceholder($TimeStamp / $FromAccount / $token 等)
|
||
→ PrefixScript 执行 ← 本 Skill 产出代码在此运行
|
||
→ SerializationBody → HTTP 请求
|
||
→ PostfixScript
|
||
```
|
||
|
||
**结论:**
|
||
|
||
| 可用 | 不可用 |
|
||
|------|--------|
|
||
| `obj.OriginalInterfaceMappedInput`(映射后 JToken) | `obj.TargetInterfaceInput`(尚未序列化) |
|
||
| `obj.FixedFieldList` / `obj.FormFieldList` | `obj.TargetInterfaceOutput` |
|
||
| `obj.GetAccountFieldValueOrNull(...)` | 改映射树配置本身 |
|
||
|
||
## 脚本技术约束
|
||
|
||
- 语言:**C#**,由 **DotNetCore.Natasha** 动态编译
|
||
- 参数名固定:**`obj`**(`Action<ForwardCoreContext>` 的 Natasha 模板入参,不是 `context`)
|
||
- 写法:仅方法体语句(不要 `class`、不要 `namespace`、不要 `void Main`)
|
||
- 同步:默认;含 `await` 或首行 `//async` 时走异步委托
|
||
|
||
### 命名空间(必做,否则 CS0246)
|
||
|
||
Natasha 的 `NDelegate.Action<T>()` **只接收方法体**,不能写 `using System;` 这类文件级指令(写了会报 **`Identifier expected`**)。
|
||
|
||
类型必须使用 **全限定名**:`System.Text.Encoding.UTF8`、`Newtonsoft.Json.JsonConvert`
|
||
|
||
### 参数名(必做,否则 CS0246)
|
||
|
||
`Action<ForwardCoreContext>` 对应系统委托 `Action<T>(T obj)`,Natasha 模板参数名是 **`obj`**,不是 `context`、不是 `arg1`。
|
||
|
||
```csharp
|
||
// ✅ 正确
|
||
string secret = obj.GetAccountFieldValueOrNull("appSecret");
|
||
|
||
// ❌ 错误 → Identifier expected(using)或 CS0103(context)
|
||
using System;
|
||
var secret = context.GetAccountFieldValueOrNull("appSecret");
|
||
```
|
||
|
||
## context API 速查
|
||
|
||
| 成员 | 用途 |
|
||
|------|------|
|
||
| `OriginalInterfaceMappedInput` | 映射后请求体 `JToken`,改 body 内字段用 |
|
||
| `FixedFieldList` | 固定参数(Header/Query/Url/Body) |
|
||
| `FormFieldList` | `application/x-www-form-urlencoded` 表单键值 |
|
||
| `AccountFieldList` | 服务商账户字段(密钥、客户号等) |
|
||
| `GetAccountFieldValueOrNull(name)` | 按字段名取账户值(忽略大小写) |
|
||
| `GetFixedFieldValueOrNull(name)` | 取固定参数当前值 |
|
||
| `AddHeader(key, value)` | 新增 Header(已存在同名 Header 则失败) |
|
||
| `TargetInterface` | 下游接口 URL、Method、ContentType 等 |
|
||
|
||
**FieldPosition:** `Header=1`, `Body`, `Query`, `Url`
|
||
|
||
**占位符(在固定参数配置,脚本执行前已替换):** `$TimeStamp`, `$DateTime`, `$FromAccount`, `$FromBody`, `$Url`, `$token`
|
||
|
||
## 签名写入方式(按目标位置选)
|
||
|
||
### 1. Header 签名(最常见)
|
||
|
||
先在接口固定参数里配置 Header 字段名(如 `sign`),脚本里赋值:
|
||
|
||
```csharp
|
||
string sign = "...";
|
||
for (int i = 0; i < obj.FixedFieldList.Count; i++) {
|
||
if (obj.FixedFieldList[i].FieldPosition == 1 && obj.FixedFieldList[i].FieldName == "sign") {
|
||
obj.FixedFieldList[i].FieldValue = sign;
|
||
break;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. Query 签名
|
||
|
||
遍历 `obj.FixedFieldList` 找到 Query 位置字段并赋值。
|
||
|
||
### 3. Body JSON 字段
|
||
|
||
```csharp
|
||
obj.OriginalInterfaceMappedInput["sign"] = sign;
|
||
```
|
||
|
||
### 4. FormUrlEncoded
|
||
|
||
```csharp
|
||
for (int i = 0; i < obj.FormFieldList.Count; i++) {
|
||
if (obj.FormFieldList[i].Name == "sign") {
|
||
obj.FormFieldList[i].Value = sign;
|
||
break;
|
||
}
|
||
}
|
||
```
|
||
|
||
## 生成工作流
|
||
|
||
1. **收集需求**:签名算法、参与字段及排序、密钥来源、输出位置、编码规则
|
||
2. **对照 InterfaceMap 配置**:固定参数、账户字段名、ContentType
|
||
3. **生成脚本** → 仅输出 C# 方法体
|
||
4. **自检**:仅用 `obj`、无 `using`、全限定名、无 class/namespace
|
||
|
||
## 输出要求
|
||
|
||
只输出一个 ```csharp 代码块,内容为可直接粘贴到编辑器的 Natasha 脚本方法体,不要额外解释。
|
||
|
||
## 禁止事项
|
||
|
||
- 不要用 `HttpClient` 在脚本里再发请求
|
||
- 不要修改 `InParamTreeList` / `OutParamTreeList`
|
||
- 不要用 `TargetInterfaceInput` 做签名字符串
|
||
- 不要输出 Python/JavaScript
|
||
- 不要在脚本里写 `using` 指令
|
||
- 不要用 `context` 作参数名,要用 `obj`
|
||
- FormUrlEncoded 时签名字符串用 `JsonConvert.SerializeObject(obj.OriginalInterfaceMappedInput)`
|