关于 platform-trial-org-create
通过向 Salesforce 主机组织插入 SignupRequest 来创建试用组织的技能,并在创建异步完成后读取组织 ID。适用于已授权创建试用组织的主机组织,流程要求明确指定目标组织并收集必要输入。
主要功能
- 01插入 SignupRequest
- 02异步读取新组织 ID
- 03指定并确认主机组织
- 04支持模板或版本选项
- 05处理创建错误
适用场景
- 01从 Trialforce 主机组织创建试用组织
- 02为试用组织选择模板或版本
- 03读取新组织分配的 ID
- 04排查 SignupRequest 创建失败
MCP 相关
输入说明未提及 MCP。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill platform-trial-org-create安装后在 Claude Code 中输入/platform-trial-org-create确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/create_request.jsonerror_response.jsonsuccess_response.jsonreferences/error_codes.mdsignup_request_fields.mdscripts/create_signup_request.shget_signup_request.sh详细介绍
此技能的作用
通过 sf CLI 插入 SignupRequest sObject,创建 Salesforce 试用组织——这与 Trialforce/开发者网页注册表单在幕后发出的请求相同。没有专门的注册端点:注册 = 在经过身份验证的宿主组织(有资格创建试用组织的 Trialforce Source Org / Env Hub / 合作伙伴组织)中插入 SignupRequest(键前缀 0SR)。
此流程包含 两次 CLI 调用:(1)创建 SignupRequest;(2)读回该记录,以获取分配的组织 ID(创建是异步的——插入后不久才会显示组织 ID)。
前提条件 — 执行前确认
-
始终明确确认经过身份验证的宿主组织。 你是从一个经过身份验证的宿主组织发起注册,而不是匿名注册。
sfCLI 操作的是你曾登录过的组织(使用sf org login web或sf org login)。每条命令都必须明确传入
--target-org(-o),并使用宿主组织的别名或用户名;创建前还必须与用户确认目标——即使已配置默认组织也不例外。创建SignupRequest是实际的配置操作;不要让命令针对碰巧成为默认值的组织运行。- 不要依赖默认组织回退。 如果没有
-o,CLI 会依次从--target-org→SF_TARGET_ORG环境变量 → 本地和全局target-org配置解析目标;如果均未设置,则会报错(NoDefaultEnvError)——它绝不会在已连接的组织中自动选择。默认组织可能是无关的开发或临时组织,因此省略-o要么会针对错误的组织操作,要么直接失败。绝不能省略。 - 用户可能有多个经过身份验证的组织。 运行
sf org list;如果无法确定哪个是目标宿主组织,或用户未提供目标组织,请询问用户要使用哪个别名或用户名。不要猜测。 - 创建前,先在
sf org list中确认所选组织的状态为Connected(过期的刷新令牌或证书会显示为错误状态,而不是Connected)。 - 绝不要编造凭据。
- 不要依赖默认组织回退。 如果没有
-
宿主组织必须有创建试用组织的资格,且发起操作的用户必须拥有足够的访问权限。此技能不会单独检查权限——
sf data create record调用(步骤 1)是最终判定依据,权限检查也会依赖相同的 API 强制机制。如果组织没有此资格,系统不会公开SignupRequest实体,创建操作会失败并返回非零status,且name/code为NOT_FOUND(“The requested resource does not exist”)或INVALID_TYPE(“sObject type 'SignupRequest' is not supported”)。步骤 1 的错误表中会处理此情况。如果发生这种情况,请停止(无法通过 CLI 重试),并向用户报告:(a)原样提供 CLI 原始错误——逐字提供 CLI 返回的确切
name/errorCode和message;(b)说明他们应联系 Salesforce 支持,以启用该组织创建试用组织的功能,然后再试。不要推断或指出缺少哪项权限——只需提供原始错误并建议联系支持。
必需输入项 — 创建之前,请先向发起请求的用户收集
请向用户询问以下信息,在全部提供之前不要继续。不要编造值。逐项询问;如果用户不确定某个字段,请先根据“用户不确定时”一栏引导他们,再继续。
始终必需(5 项) — 这些字段在 SignupRequest 实体上设置了 required="true"(为方便提示,FirstName 列于此处,但它是可选的):
| 输入项 | 说明 | 用户不确定时 |
|---|---|---|
LastName | 管理员用户的姓氏。最多 80 个字符。 | 可以使用新组织管理员的任意姓氏;这只是管理员的联系人姓名,填写用户自己的即可。 |
FirstName | **可选。**管理员用户的名字。请询问;如果用户未提供,则不填写也可以继续。 | 可选 — 不确定时留空;管理员用户只需提供 LastName。 |
Username | 管理员登录用户名。必须符合电子邮件格式,并且在所有 Salesforce 组织中全局唯一。最多 80 个字符。保存时会转换为小写。 | 不必是真实邮箱 — 只需看起来像电子邮件地址且具有唯一性。建议使用类似 admin@<company>-<something-unique>.com 的格式。如果发生冲突,创建时会出现用户名重复错误;请换一个。 |
SignupEmail | 管理员用户的真实电子邮件地址(欢迎邮件/登录邮件将发送到此地址)。 | 这必须是他们可以访问的有效邮箱 — 与 Username 不同,它应该是真实地址。 |
Company | 公司/组织名称。最多 80 个字符。 | 在试用组织中显示的组织名称;任意描述性名称均可。 |
Country | ISO 国家/地区代码,最多 3 个字符,例如 US、GB、IN、DE。运行时会根据允许的代码进行验证(受禁运/无效代码会被拒绝)。 | 使用所在国家/地区的 2 位 ISO 代码(例如,美国用 US,英国用 GB)。不能填写自由文本形式的国家/地区名称。 |
以下两项中必须且只能选择一项:
| 输入项 | 说明 | 用户不确定时 |
|---|---|---|
TemplateId | Trialforce 模板 ID(键前缀为 0TT,共 15 个字符)— 用于定义试用组织的产品/内容。 | 如果用户需要特定的预构建产品/内容集,请使用模板。如需查找可用模板,请查询主机组织:sf data query -o <HOST_ORG> -q "SELECT Id, TemplateName FROM TrialforceTemplate" --json。如果他们只想要一个普通的试用组织,请改用 Edition。 |
Edition | 通用(非模板)试用组织的版本。通用取值:Developer、Group、Professional、Enterprise(也包括 ServiceProfessional、SalesEnterprise)。合作伙伴/Trialforce 版本受权限控制。 | 如果他们只想要“一个用来试试的开发组织”,请使用 Developer。合作伙伴版本(PARTNER_*、TRIALFORCE_*)仅在主机组织具有合作伙伴/TMC 权限时有效 — 在没有相应权限的情况下使用会返回 noPartnerAccess 错误。 |
请用户在 TemplateId 和 Edition 中任选一项,不要同时提供两项:
- 两项都未提供 → 停止并询问。既不提供模板也不提供版本的创建请求将因验证失败而返回
missingEdition(ApiErrorCodes.INVALID_SIGNUP_OPTION)。 - 两项都已提供 → 请用户选择一项;只发送所选字段。组合使用会导致
redundantTemplateId错误。两者均不得与克隆/源组织字段组合使用。
此技能有意将用户收集的输入限制在上述字段范围内(5 项始终必需字段加可选的 FirstName)。不要询问或展示其他字段。SignupRequest 实体还支持其他可选字段和受权限控制的字段(TrialDays、Subdomain、PreferredLanguage、SignupSource、OAuth 返回参数等);这些不在此范围内,交由服务器默认处理。相关说明仅供参考,见 references/signup_request_fields.md — 请勿通过此技能发送这些字段。
第 1 步 — 创建 SignupRequest
使用收集到的输入调用 create 脚本。该脚本会强制执行“TemplateId/Edition 必须且只能设置一个”的规则,组装并引用 --values 负载,执行插入操作,并在成功时打印分配的 0SR… ID。请使用相对于技能目录的绝对路径引用脚本(<skill_dir>/scripts/…)——切勿使用 ./scripts/,因为它会相对于用户的工作目录解析。
使用模板时:
SR_ID=$(bash "<skill_dir>/scripts/create_signup_request.sh" \
--target-org <HOST_ORG> \
--last-name <LAST_NAME> --email <EMAIL> --username <UNIQUE_USERNAME> \
--company "<COMPANY>" --country <ISO> --template-id 0TT... \
--output-dir force-app/main/adk-eval-output)
**使用版本时(通用试用版,不使用模板):**将 --template-id 0TT... 替换为 --edition Developer(或 Enterprise 等)。只有在用户提供了名字时才添加 --first-name <NAME>——此技能不会发送其他可选字段。脚本会拒绝同时提供 --template-id 和 --edition,或两者都不提供的情况。
传入 --output-dir(如果 force-app/main/adk-eval-output 存在,则使用该路径),这样即使创建被拒绝,脚本仍会写入 <output-dir>/signup-request-result.json,记录创建被拒绝的结果和原始错误文本——即使未创建任何组织,该文件也是此次运行的输出产物。创建成功时,则由步骤 2 的回读操作写入该文件。
成功时,脚本会打印 0SR… SignupRequest ID(将其保存为 SR_ID)。也可改为传入 --json,以获取原始的 sf 创建响应,其中封装的是一个句柄,而不是组织:
{ "status": 0, "result": { "id": "0SRxx0000000000", "success": true, "errors": [] } }
处理创建错误(同步字段验证)。创建被拒绝时,脚本会以非零状态退出,并将原始 CLI 错误(name/code + message)打印到 stderr——请原样呈现,并根据下表采取行动。提供了 --output-dir 时,脚本还会将创建被拒绝的产物({ "outcome": "create-rejected", "error": {…}, "CreatedOrgId": null, "Status": null })写入 <output-dir>/signup-request-result.json;请勿手动编写此文件。这是字段验证错误,会立即返回——与步骤 2 中的异步 ErrorCode 不同。这些是服务端拒绝(记录已到达组织,平台在插入时拒绝了它)——请勿向用户描述为“客户端”错误;CLI 不会在本地验证电子邮件/国家或地区格式、选项列表值或字段长度。创建失败后,请勿轮询,也不要继续执行步骤 2。
| 失败 | 含义 → 应告知用户的内容 |
|---|---|
missingEdition / INVALID_SIGNUP_OPTION | 未发送 TemplateId 或 Edition — 请用户提供其中一个,然后重试。 |
redundantTemplateId | 同时发送了 TemplateId 和 Edition — 删除其中一个,然后重试。 |
noPartnerAccess / NO_PARTNER_PERMISSION | 请求了合作伙伴/TSO 版本,但主机组织缺少相应权限 — 使用通用版本(Developer 等),或获取相应权限。 |
重复或无效的 Username(INVALID_EMAIL_ADDRESS) | Username 不符合电子邮件格式,或不是全局唯一的 — 请用户换一个,然后重试。 |
INVALID_SIGNUP_COUNTRY | Country 不是有效/允许使用的 ISO 代码 — 修正后重试。 |
INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST | Edition 不是主机组织受限选项列表接受的值(例如 Ultimate)— 选择有效的通用版本,然后重试。 |
STRING_TOO_LONG | 某个字段值超过最大长度(消息会指出字段和 max length,例如 LastName 超过 80)— 缩短后重试。 |
subdomainInUse / 无效子域名 | 所选 Subdomain 已被占用或无效 — 换一个。 |
NOT_FOUND("The requested resource does not exist")或 INVALID_TYPE("sObject type 'SignupRequest' is not supported") | 未公开 SignupRequest 实体 → 该组织无权创建试用组织。不可重试。停止操作,并按原样显示原始 CLI 错误(name/errorCode + message),然后告知用户联系 Salesforce 支持以启用该组织。不要提及或诊断缺失的权限。 |
INSUFFICIENT_ACCESS_OR_READONLY | 已公开该实体,但用户缺少创建记录的访问权限 — 这是用户权限问题,与上述组织授权失败不同。修正用户权限后重试。 |
完整目录和前缀 → references/error_codes.md。
- 完整的必填/可选字段列表、类型和受权限控制的字段 → 加载
references/signup_request_fields.md。 - 不要同时发送
TemplateId和克隆/源组织字段(会报redundantTemplateId错误)。不要在主机组织没有合作伙伴/TMC 权限时请求合作伙伴/Trialforce 版本。
步骤 2 — 获取组织 ID 后读取请求(创建是异步的)
插入记录后会异步预配,因此请重新读取记录以获取已分配的组织 ID。调用读取脚本 — 脚本会在内部应用固定且有限的回读策略(一旦 CreatedOrgId 有值或状态进入终态,就会立即停止,绝不会无限轮询),以 JSON 格式打印记录,并在提供 --output-dir 时写入输出产物。然后根据脚本的退出代码采取操作(如下)— 重试次数和延迟由脚本按确定性逻辑自行处理;请勿在说明中重新实现或重新计数。如果组织 ID 尚不可用,脚本会以 3 退出,以便你将请求 ID 返回给用户:
bash "<skill_dir>/scripts/get_signup_request.sh" \
--target-org <HOST_ORG> --id "$SR_ID" [--output-dir <DIR>]
脚本会以 JSON 格式打印 SignupRequest 记录(即 sf 信封的 result)。读取其中的以下字段:
CreatedOrgId— 新试用组织的 ID(00D…,15 个字符)。组织一经分配,该字段就会有值(此时Status通常仍为InProgress);这是脚本的停止信号。CreatedOrgInstance— 托管新组织的实例(后续调用应发往此实例)。Username— 记录中的管理员登录用户名。请报告从记录回读的值,而非原始输入 — 保存时用户名会转换为小写,因此存储的值才是应提供给用户的准确值。Status— 生命周期状态:New→InProgress→Success|Error(比较时不区分大小写)。LoginUrl— 仅当创建时设置了IsSyncLogin才会出现(受权限控制)。AuthCode— 仅当设置了ConnectedAppConsumerKey+ConnectedAppCallbackUrl才会出现。ErrorCode— 仅当Status = Error时才会有值。这是异步预配错误(不同于步骤 1 中创建时的同步验证错误),错误码前缀如下:C-组织创建错误 ·S-注册数据错误 ·T-模板错误(例如,T-0002= 未找到模板)·SH-组织形态错误 ·VR-版本选择错误 ·X-0001/X-0002致命错误/不应发生的情况。
根据脚本的退出代码采取操作。**首先查询组织 ID — 脚本返回之前,请勿向用户报告任何内容。**仅报告记录中的实际内容;切勿臆造或重新标注 Status:
0—CreatedOrgId已有值。继续执行步骤 3,并报告组织 ID、记录中的实际Status和Username。- **
3— 尚无可用的组织 ID(不是错误)。**组织尚未分配。脚本已完成有限次数的回读 — **请勿循环重新调用脚本以继续轮询。报告 SignupRequest ID(0SR…)、记录中原样返回的Status**和Username;告知用户组织 ID 尚不可用,并请其稍后重新检查(见步骤 3)。 1—Status = Error(停止,并通过references/error_codes.md报告ErrorCode及其前缀含义;组织未创建),或者读取本身失败(身份验证已过期、未找到0SRID)— 显示原始 CLI 错误并停止。
第 3 步 — 报告详情并说明如何重新检查状态
在第 2 步的查询返回之后再报告,而不是之前。用户要求创建(或重新检查)组织时,先执行回读并等待结果,然后一次性向用户报告所有可用详情。只报告记录中的内容;绝不编造或重新标注任何值——尤其是 Status,必须与响应对象携带的字符串完全一致:
- SignupRequest id —
0SR…请求 ID(来自第 1 步)。始终报告此 ID——用户(或之后的状态检查)会用它再次查找请求;如果组织 ID 尚不可用,这是必须提供的主要信息。 - CreatedOrgId — 新试用组织 ID(
00D…),如果已填写。如果回读返回退出码3(组织 ID 尚不可用),请明确说明:请求已被接受,组织仍在配置中;目前还没有可提供的组织 ID。 - CreatedOrgInstance — 托管该组织的实例(如果存在)。
- Username — 按记录中存储的内容报告管理员登录用户名(保存时会转换为小写)。始终报告此用户名——组织就绪后,用户将使用它登录。
- Status — 与记录中显示的内容完全一致的
Status值。原样复述响应携带的字符串;不要映射、翻译、推断,也不要从固定列表中选择。此时状态仍为待处理是正常的——配置会在后台完成。 - LoginUrl / AuthCode — 仅在存在时报告。
还要告知用户,新组织的登录详情会通过电子邮件发送——配置完成后,系统会向 SignupEmail 地址发送欢迎/登录邮件,用户应留意该收件箱,以完成登录。(因此,SignupEmail 必须是一个真实且可访问的地址。)
然后用简单明了的语言建议用户之后如何重新检查状态——配置可能仍在进行中。告知他们只需提出请求即可(该技能会重新读取记录),例如:
- “检查我的试用组织
00D…的状态”(通过组织 ID),或 - “检查注册请求
0SR…的状态”(通过 SignupRequest ID)。
两种方式都会针对同一条 SignupRequest 记录重新运行第 2 步读取脚本(组织 ID 会从该记录中查找)。之后的检查应完全按记录返回的内容报告当前 Status。如果记录返回错误状态,还要通过 references/error_codes.md 报告 ErrorCode 及其前缀含义。
输出产物。 通过向第 2 步读取脚本传入 --output-dir,将当前 SignupRequest 记录写入本次运行的输出产物——脚本会写入 <output-dir>/signup-request-result.json(如有需要会创建目录)。如果 force-app/main/adk-eval-output 存在,请将其用作输出目录:
bash "<skill_dir>/scripts/get_signup_request.sh" \
--target-org <HOST_ORG> --id "$SR_ID" \
--output-dir force-app/main/adk-eval-output
这是本次运行定义的输出——写入前不要征求许可。
参考文件索引
| 文件 | 何时阅读 |
|---|---|
references/signup_request_fields.md | 完整字段参考——必填/可选字段、类型、默认值、受权限控制的字段和版本 |
references/error_codes.md | 解读 ErrorCode 前缀及常见验证失败 |
示例文件
仅在需要查看负载或响应的具体格式时加载这些文件——它们是带有占位 ID(0SRxx…、00Dxx…)的示例,不是要发送的值。
| 文件 | 何时阅读 |
|---|---|
examples/create_request.json | 组装创建请求时——用于确认 SignupRequest 创建负载的字段名称/格式 |
examples/success_response.json | 解读成功创建并回读的结果时——展示已填写 CreatedOrgId 的记录 |
examples/error_response.json | 解读被拒绝的创建请求时——展示常见验证/错误响应的格式 |