diff --git a/internal/util/proxy.go b/internal/util/proxy.go index d9e251859..eeba34db2 100644 --- a/internal/util/proxy.go +++ b/internal/util/proxy.go @@ -16,6 +16,9 @@ import ( const ( // EnvNoProxy disables automatic proxy support when set to any non-empty value. EnvNoProxy = "LARK_CLI_NO_PROXY" + // EnvNoProxyWarning suppresses the one-time proxy warning when set to any non-empty value. + // The proxy itself is still used; only the stderr warning is silenced. + EnvNoProxyWarning = "LARK_CLI_NO_PROXY_WARNING" ) // proxyEnvKeys lists environment variables that Go's ProxyFromEnvironment reads. @@ -60,7 +63,7 @@ func redactProxyURL(raw string) string { // are redacted. Safe to call multiple times; only the first call prints. func WarnIfProxied(w io.Writer) { proxyWarningOnce.Do(func() { - if os.Getenv(EnvNoProxy) != "" { + if os.Getenv(EnvNoProxy) != "" || os.Getenv(EnvNoProxyWarning) != "" { return } key, val := DetectProxyEnv() diff --git a/shortcuts/im/im_messages_reply.go b/shortcuts/im/im_messages_reply.go index 806ee739c..33c36ca55 100644 --- a/shortcuts/im/im_messages_reply.go +++ b/shortcuts/im/im_messages_reply.go @@ -29,11 +29,11 @@ var ImMessagesReply = common.Shortcut{ {Name: "content", Desc: "(one of --content/--text/--markdown/--image/--file/--video/--audio required) message content JSON"}, {Name: "text", Desc: "plain text message (auto-wrapped as JSON)"}, {Name: "markdown", Desc: "markdown text (auto-wrapped as post format with style optimization; image URLs auto-resolved)"}, - {Name: "image", Desc: "image_key, local file path"}, - {Name: "file", Desc: "file_key, local file path"}, - {Name: "video", Desc: "video file_key, local file path; must be used together with --video-cover"}, - {Name: "video-cover", Desc: "video cover image_key, local file path; required when using --video"}, - {Name: "audio", Desc: "audio file_key, local file path"}, + {Name: "image", Desc: "image_key or relative path to file"}, + {Name: "file", Desc: "file_key or relative path to file"}, + {Name: "video", Desc: "video file_key or relative path to file; must be used together with --video-cover"}, + {Name: "video-cover", Desc: "video cover image_key or relative path to file; required when using --video"}, + {Name: "audio", Desc: "audio file_key or relative path to file"}, {Name: "reply-in-thread", Type: "bool", Desc: "reply in thread (message appears in thread stream instead of main chat)"}, {Name: "idempotency-key", Desc: "idempotency key (prevents duplicate sends)"}, }, diff --git a/shortcuts/im/im_messages_send.go b/shortcuts/im/im_messages_send.go index efaa54852..fb7a94451 100644 --- a/shortcuts/im/im_messages_send.go +++ b/shortcuts/im/im_messages_send.go @@ -33,11 +33,11 @@ var ImMessagesSend = common.Shortcut{ {Name: "text", Desc: "plain text message (auto-wrapped as JSON)"}, {Name: "markdown", Desc: "markdown text (auto-wrapped as post format with style optimization; image URLs auto-resolved)"}, {Name: "idempotency-key", Desc: "idempotency key (prevents duplicate sends)"}, - {Name: "image", Desc: "image_key, local file path"}, - {Name: "file", Desc: "file_key, local file path"}, - {Name: "video", Desc: "video file_key, local file path; must be used together with --video-cover"}, - {Name: "video-cover", Desc: "video cover image_key, local file path; required when using --video"}, - {Name: "audio", Desc: "audio file_key, local file path"}, + {Name: "image", Desc: "image_key or relative path to file"}, + {Name: "file", Desc: "file_key or relative path to file"}, + {Name: "video", Desc: "video file_key or relative path to file; must be used together with --video-cover"}, + {Name: "video-cover", Desc: "video cover image_key or relative path to file; required when using --video"}, + {Name: "audio", Desc: "audio file_key or relative path to file"}, }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { chatFlag := runtime.Str("chat-id") @@ -81,10 +81,16 @@ var ImMessagesSend = common.Shortcut{ if desc != "" { d.Desc(desc) } - return d. + d = d. POST("/open-apis/im/v1/messages"). Params(map[string]interface{}{"receive_id_type": receiveIdType}). Body(body) + + if chatFlag != "" { + d.Desc("dry-run validates request shape only — it does not verify that the selected identity is a member of the target chat; a real send can still fail with \"Bot/User can NOT be out of the chat\"") + } + + return d }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { chatFlag := runtime.Str("chat-id")