Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var ContactGetUser = common.Shortcut{ Service: "contact", Command: "+get-user", Description: "Get user info (omit user_id for self; provide user_id for specific user)", Risk: "read", UserScopes: []string{"contact:user.basic_profile:readonly"}, BotScopes: []string{"contact:user.base:readonly", "contact:contact.base:readonly"}, AuthTypes: []string{"user", "bot"}, HasFormat: true, Flags: []common.Flag{ {Name: "user-id", Desc: "user ID (omit to get current user)"}, {Name: "user-id-type", Default: "open_id", Desc: "user ID type: open_id | union_id | user_id"}, }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { if runtime.Str("user-id") == "" && runtime.IsBot() { return common.FlagErrorf("bot identity cannot get current user info, specify --user-id") } return nil }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { userId := runtime.Str("user-id") if userId == "" { return common.NewDryRunAPI(). GET("/open-apis/authen/v1/user_info"). Desc("(when --user-id omitted) Get current authenticated user info"). Set("mode", "current_user") } userIdType := runtime.Str("user-id-type") if userIdType == "" { userIdType = "open_id" } if runtime.IsBot() { return common.NewDryRunAPI(). GET("/open-apis/contact/v3/users/:user_id"). Desc("(bot) Get user info by user ID"). Params(map[string]interface{}{"user_id_type": userIdType}). Set("user_id", userId).Set("user_id_type", userIdType) } return common.NewDryRunAPI(). POST("/open-apis/contact/v3/users/basic_batch"). Desc("(user) Get user basic info by user ID"). Params(map[string]interface{}{"user_id_type": userIdType}). Body(map[string]interface{}{"user_ids": []string{userId}}) }, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { userId := runtime.Str("user-id") userIdType := runtime.Str("user-id-type") if userId == "" { data, err := runtime.CallAPI("GET", "/open-apis/authen/v1/user_info", nil, nil) if err != nil { return err } user := data if user == nil { user = make(map[string]interface{}) } userData := map[string]interface{}{"user": user} runtime.OutFormat(userData, nil, func(w io.Writer) { output.PrintTable(w, []map[string]interface{}{{ "name": pickUserName(user), "open_id": user["open_id"], "union_id": user["union_id"], "email": firstNonEmpty(user, "email", "mail"), "mobile": firstNonEmpty(user, "mobile", "phone"), "enterprise_email": firstNonEmpty(user, "enterprise_email"), }}) }) return nil } if runtime.IsBot() { data, err := runtime.CallAPI("GET", "/open-apis/contact/v3/users/"+url.PathEscape(userId), map[string]interface{}{"user_id_type": userIdType}, nil) if err != nil { return err } user, _ := data["user"].(map[string]interface{}) if user == nil { user = data } userData := map[string]interface{}{"user": user} runtime.OutFormat(userData, nil, func(w io.Writer) { output.PrintTable(w, []map[string]interface{}{{ "name": pickUserName(user), "open_id": firstNonEmpty(user, "open_id", "user_id"), "email": firstNonEmpty(user, "email", "enterprise_email"), "mobile": firstNonEmpty(user, "mobile", "mobile_phone"), "department": firstNonEmpty(user, "department_name"), }}) }) return nil } data, err := runtime.CallAPI("POST", "/open-apis/contact/v3/users/basic_batch", map[string]interface{}{"user_id_type": userIdType}, map[string]interface{}{"user_ids": []string{userId}}) if err != nil { return err } users, _ := data["users"].([]interface{}) var user map[string]interface{} if len(users) > 0 { user, _ = users[0].(map[string]interface{}) } if user == nil { user = make(map[string]interface{}) } userData := map[string]interface{}{"user": user} runtime.OutFormat(userData, nil, func(w io.Writer) { output.PrintTable(w, []map[string]interface{}{{ "name": pickUserName(user), "user_id": user["user_id"], }}) }) return nil }, }
View Source
var ContactSearchUser = common.Shortcut{ Service: "contact", Command: "+search-user", Description: "Search Lark/Feishu users by keyword, open_id list, or filter (requires --as user)", Risk: "read", Scopes: []string{"contact:user:search"}, AuthTypes: []string{"user"}, HasFormat: true, Flags: []common.Flag{ {Name: "query", Desc: "search keyword (≤ 50 characters)"}, {Name: "user-ids", Desc: "open_ids to look up or restrict --query against (CSV; me = caller; ≤ 100)"}, {Name: "has-chatted", Type: "bool", Desc: "restrict to users you've chatted with (omit to disable; =false rejected)"}, {Name: "has-enterprise-email", Type: "bool", Desc: "restrict to users with enterprise email (omit to disable; =false rejected)"}, {Name: "exclude-external-users", Type: "bool", Desc: "exclude external (cross-tenant) users; default includes them (omit to disable; =false rejected)"}, {Name: "left-organization", Type: "bool", Desc: "restrict to users who have left the organization (omit to disable; =false rejected)"}, {Name: "lang", Desc: "override locale for localized_name (e.g. zh_cn, en_us)"}, {Name: "page-size", Type: "int", Default: "20", Desc: "rows per request, 1-30"}, {Name: "queries", Desc: "comma-separated keywords searched in parallel; output is a flat users[] with matched_query plus a queries[] sidecar"}, }, Tips: []string{ "Keyword search: lark-cli contact +search-user --query 'alice'", "Look up by ID (or 'me' for self): lark-cli contact +search-user --user-ids 'ou_xxx,me'", "Filter-only enumeration — users you've chatted with: lark-cli contact +search-user --has-chatted", "Refine same-name hits: lark-cli contact +search-user --query '张三' --has-chatted --exclude-external-users", "Multi-name fanout: lark-cli contact +search-user --queries 'alice,bob,张三'", "open_id is the stable identifier for follow-up commands; on has_more=true add filters or tighten --query — there is no auto-pagination.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateSearchUser(runtime) }, DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI { if raw := strings.TrimSpace(runtime.Str("queries")); raw != "" { queries := parseAndDedupQueries(raw) filter, err := buildFanoutFilter(runtime) if err != nil { return common.NewDryRunAPI().Set("error", err.Error()) } api := common.NewDryRunAPI() for _, q := range queries { body := &searchUserAPIRequest{Query: q} if filter != nil { body.Filter = filter } api.POST(searchUserURL). Params(map[string]interface{}{"page_size": runtime.Int("page-size")}). Body(body) } return api } body, err := buildSearchUserBody(runtime) if err != nil { return common.NewDryRunAPI().Set("error", err.Error()) } return common.NewDryRunAPI(). POST(searchUserURL). Params(map[string]interface{}{"page_size": runtime.Int("page-size")}). Body(body) }, Execute: executeSearchUser, }
Functions ¶
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.