diff --git a/shortcuts/slides/slides_create.go b/shortcuts/slides/slides_create.go index 115f04cd1..b03fea491 100644 --- a/shortcuts/slides/slides_create.go +++ b/shortcuts/slides/slides_create.go @@ -204,13 +204,11 @@ var SlidesCreate = common.Shortcut{ } } - // Build the presentation URL locally from the token. The brand-standard - // host transparently redirects to the tenant domain (same fallback used by - // drive +upload / wiki +node-create). This avoids the prior best-effort - // drive metas/batch_query call, which needed an extra drive scope and 403'd - // for users who only authorized slides scopes — without ever blocking an - // otherwise-successful creation. - if url := common.BuildResourceURL(runtime.Config.Brand, "slides", presentationID); url != "" { + // Prefer the URL returned by presentation.create. Fall back to a local + // brand-standard URL only when the API omits it. + if url := common.GetString(data, "url"); url != "" { + result["url"] = url + } else if url := common.BuildResourceURL(runtime.Config.Brand, "slides", presentationID); url != "" { result["url"] = url } diff --git a/shortcuts/slides/slides_create_test.go b/shortcuts/slides/slides_create_test.go index 36b964a07..a5ba64cdf 100644 --- a/shortcuts/slides/slides_create_test.go +++ b/shortcuts/slides/slides_create_test.go @@ -34,6 +34,7 @@ func TestSlidesCreateBasic(t *testing.T) { "data": map[string]interface{}{ "xml_presentation_id": "pres_abc123", "revision_id": 1, + "url": "https://tenant.example.com/slides/pres_abc123", }, }, }) @@ -54,10 +55,8 @@ func TestSlidesCreateBasic(t *testing.T) { if data["title"] != "项目汇报" { t.Fatalf("title = %v, want 项目汇报", data["title"]) } - // URL is built locally from the token (brand-standard host), not fetched from - // drive metas, so it is deterministic and needs no drive scope. - if data["url"] != "https://www.feishu.cn/slides/pres_abc123" { - t.Fatalf("url = %v, want https://www.feishu.cn/slides/pres_abc123", data["url"]) + if data["url"] != "https://tenant.example.com/slides/pres_abc123" { + t.Fatalf("url = %v, want https://tenant.example.com/slides/pres_abc123", data["url"]) } if _, ok := data["permission_grant"]; ok { t.Fatalf("did not expect permission_grant in user mode") @@ -647,12 +646,12 @@ func TestSlidesCreateWithoutSlidesUnchanged(t *testing.T) { } } -// TestSlidesCreateURLBuiltLocally verifies the presentation URL is constructed -// locally from the token — no drive metas/batch_query call is made, so creation -// works for users who only authorized slides scopes. The httpmock registry has no -// batch_query stub registered; if the shortcut tried to call it, the request would -// fail the test (unregistered stub), proving the URL is built without a drive call. -func TestSlidesCreateURLBuiltLocally(t *testing.T) { +// TestSlidesCreateURLFallsBackToLocalBuild verifies the presentation URL is +// constructed locally from the token when presentation.create omits url — no +// drive metas/batch_query call is made, so creation works for users who only +// authorized slides scopes. The httpmock registry has no batch_query stub +// registered; if the shortcut tried to call it, the request would fail the test. +func TestSlidesCreateURLFallsBackToLocalBuild(t *testing.T) { t.Parallel() f, stdout, _, reg := cmdutil.TestFactory(t, slidesTestConfig(t, "")) @@ -665,6 +664,7 @@ func TestSlidesCreateURLBuiltLocally(t *testing.T) { "data": map[string]interface{}{ "xml_presentation_id": "pres_local_url", "revision_id": 1, + "url": "", }, }, })