mirror of
https://github.com/larksuite/cli.git
synced 2026-07-07 17:45:15 +08:00
fix(vc): rename meeting events participants field
This commit is contained in:
@@ -103,15 +103,15 @@ var VCMeetingEvents = common.Shortcut{
|
||||
}
|
||||
events = compactMeetingEvents(events)
|
||||
identity, identityWarning := meetingEventsCurrentIdentity(runtime)
|
||||
currentRoster, rosterWarning := fetchMeetingEventsCurrentRoster(runtime)
|
||||
outData := buildMeetingEventsOutput(data, events, currentRoster, identity, identityWarning, rosterWarning)
|
||||
currentParticipants, participantsWarning := fetchMeetingEventsCurrentParticipants(runtime)
|
||||
outData := buildMeetingEventsOutput(data, events, currentParticipants, identity, identityWarning, participantsWarning)
|
||||
metadata := map[string]interface{}{
|
||||
"row_type": "metadata",
|
||||
"meeting": outData.Meeting,
|
||||
"identity": outData.Identity,
|
||||
"current_roster": outData.CurrentRoster,
|
||||
"has_more": outData.HasMore,
|
||||
"page_token": outData.PageToken,
|
||||
"row_type": "metadata",
|
||||
"meeting": outData.Meeting,
|
||||
"identity": outData.Identity,
|
||||
"current_participants": outData.CurrentParticipants,
|
||||
"has_more": outData.HasMore,
|
||||
"page_token": outData.PageToken,
|
||||
}
|
||||
if len(outData.Warnings) > 0 {
|
||||
metadata["warnings"] = outData.Warnings
|
||||
@@ -137,13 +137,13 @@ var VCMeetingEvents = common.Shortcut{
|
||||
}
|
||||
|
||||
type meetingEventsOutput struct {
|
||||
Meeting meetingEventsMeeting `json:"meeting"`
|
||||
Identity meetingEventsIdentity `json:"identity"`
|
||||
CurrentRoster []meetingEventsIdentity `json:"current_roster"`
|
||||
Events []meetingEventsEvent `json:"events"`
|
||||
Warnings []string `json:"warnings,omitempty"`
|
||||
HasMore bool `json:"has_more"`
|
||||
PageToken string `json:"page_token,omitempty"`
|
||||
Meeting meetingEventsMeeting `json:"meeting"`
|
||||
Identity meetingEventsIdentity `json:"identity"`
|
||||
CurrentParticipants []meetingEventsIdentity `json:"current_participants"`
|
||||
Events []meetingEventsEvent `json:"events"`
|
||||
Warnings []string `json:"warnings,omitempty"`
|
||||
HasMore bool `json:"has_more"`
|
||||
PageToken string `json:"page_token,omitempty"`
|
||||
}
|
||||
|
||||
type meetingEventsMeeting struct {
|
||||
@@ -172,7 +172,7 @@ type meetingEventsEvent struct {
|
||||
Payload map[string]interface{} `json:"payload,omitempty"`
|
||||
}
|
||||
|
||||
func buildMeetingEventsOutput(data map[string]interface{}, events []interface{}, currentRoster []interface{}, identity meetingEventsIdentity, warnings ...string) meetingEventsOutput {
|
||||
func buildMeetingEventsOutput(data map[string]interface{}, events []interface{}, currentParticipants []interface{}, identity meetingEventsIdentity, warnings ...string) meetingEventsOutput {
|
||||
output := meetingEventsOutput{
|
||||
Meeting: meetingEventsMeetingFromPayload(nil),
|
||||
Identity: identity,
|
||||
@@ -195,7 +195,7 @@ func buildMeetingEventsOutput(data map[string]interface{}, events []interface{},
|
||||
}
|
||||
output.Events = append(output.Events, meetingEventsEventFromPayload(event, output.Identity))
|
||||
}
|
||||
output.CurrentRoster = enrichMeetingEventsCurrentRoster(meetingEventsCurrentRoster(currentRoster, output.Identity), output.Events)
|
||||
output.CurrentParticipants = enrichMeetingEventsCurrentParticipants(meetingEventsCurrentParticipants(currentParticipants, output.Identity), output.Events)
|
||||
return output
|
||||
}
|
||||
|
||||
@@ -222,12 +222,12 @@ func meetingEventsCurrentIdentity(runtime *common.RuntimeContext) (meetingEvents
|
||||
return identity, ""
|
||||
}
|
||||
|
||||
func fetchMeetingEventsCurrentRoster(runtime *common.RuntimeContext) ([]interface{}, string) {
|
||||
func fetchMeetingEventsCurrentParticipants(runtime *common.RuntimeContext) ([]interface{}, string) {
|
||||
meetingID := strings.TrimSpace(runtime.Str("meeting-id"))
|
||||
data, err := runtime.CallAPITyped(http.MethodGet, fmt.Sprintf("/open-apis/vc/v1/meetings/%s", validate.EncodePathSegment(meetingID)),
|
||||
map[string]interface{}{"with_participants": "true", "query_mode": "0", "user_id_type": "open_id"}, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Sprintf("current_roster unavailable: %v", err)
|
||||
return nil, fmt.Sprintf("current_participants unavailable: %v", err)
|
||||
}
|
||||
if meeting := common.GetMap(data, "meeting"); meeting != nil {
|
||||
return common.GetSlice(meeting, "participants"), ""
|
||||
@@ -284,9 +284,9 @@ func meetingEventsEventFromPayload(event map[string]interface{}, selfIdentity me
|
||||
return out
|
||||
}
|
||||
|
||||
func meetingEventsCurrentRoster(rawRoster []interface{}, selfIdentity meetingEventsIdentity) []meetingEventsIdentity {
|
||||
roster := make([]meetingEventsIdentity, 0, len(rawRoster))
|
||||
for _, raw := range rawRoster {
|
||||
func meetingEventsCurrentParticipants(rawParticipants []interface{}, selfIdentity meetingEventsIdentity) []meetingEventsIdentity {
|
||||
participants := make([]meetingEventsIdentity, 0, len(rawParticipants))
|
||||
for _, raw := range rawParticipants {
|
||||
item, _ := raw.(map[string]interface{})
|
||||
if item == nil {
|
||||
continue
|
||||
@@ -295,12 +295,12 @@ func meetingEventsCurrentRoster(rawRoster []interface{}, selfIdentity meetingEve
|
||||
if nested := common.GetMap(item, "participant"); nested != nil {
|
||||
participant = nested
|
||||
}
|
||||
roster = append(roster, meetingEventsIdentityFromParticipant(participant, selfIdentity))
|
||||
participants = append(participants, meetingEventsIdentityFromParticipant(participant, selfIdentity))
|
||||
}
|
||||
return roster
|
||||
return participants
|
||||
}
|
||||
|
||||
func enrichMeetingEventsCurrentRoster(roster []meetingEventsIdentity, events []meetingEventsEvent) []meetingEventsIdentity {
|
||||
func enrichMeetingEventsCurrentParticipants(participants []meetingEventsIdentity, events []meetingEventsEvent) []meetingEventsIdentity {
|
||||
typeByID := make(map[string]string)
|
||||
nameByID := make(map[string]string)
|
||||
for _, event := range events {
|
||||
@@ -320,25 +320,25 @@ func enrichMeetingEventsCurrentRoster(roster []meetingEventsIdentity, events []m
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range roster {
|
||||
for i := range participants {
|
||||
changed := false
|
||||
if roster[i].Name == "" {
|
||||
if name := nameByID[roster[i].ID]; name != "" {
|
||||
roster[i].Name = name
|
||||
if participants[i].Name == "" {
|
||||
if name := nameByID[participants[i].ID]; name != "" {
|
||||
participants[i].Name = name
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
if isUnknownParticipantType(roster[i].ParticipantType) {
|
||||
if participantType := typeByID[roster[i].ID]; participantType != "" {
|
||||
roster[i].ParticipantType = participantType
|
||||
if isUnknownParticipantType(participants[i].ParticipantType) {
|
||||
if participantType := typeByID[participants[i].ID]; participantType != "" {
|
||||
participants[i].ParticipantType = participantType
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
roster[i].Label = identityLabel(roster[i])
|
||||
participants[i].Label = identityLabel(participants[i])
|
||||
}
|
||||
}
|
||||
return roster
|
||||
return participants
|
||||
}
|
||||
|
||||
func eventActors(eventType string, payload map[string]interface{}, selfIdentity meetingEventsIdentity) []meetingEventsIdentity {
|
||||
@@ -419,7 +419,7 @@ func meetingEventsParticipantTypeFromParticipantType(raw string) string {
|
||||
}
|
||||
|
||||
func meetingEventsParticipantRole(participant map[string]interface{}) string {
|
||||
if raw := meetingEventsRoleFromRosterRole(fieldValueString(participant, "role")); raw != "" {
|
||||
if raw := meetingEventsRoleFromParticipantRole(fieldValueString(participant, "role")); raw != "" {
|
||||
return raw
|
||||
}
|
||||
return meetingEventsRoleFromEventUserRole(fieldValueString(participant, "user_role"))
|
||||
@@ -452,7 +452,7 @@ func isUnknownParticipantType(participantType string) bool {
|
||||
return participantType == "" || participantType == "unknown"
|
||||
}
|
||||
|
||||
func meetingEventsRoleFromRosterRole(raw string) string {
|
||||
func meetingEventsRoleFromParticipantRole(raw string) string {
|
||||
raw = strings.ToLower(strings.TrimSpace(raw))
|
||||
switch raw {
|
||||
case "1", "host":
|
||||
@@ -580,9 +580,9 @@ func renderMeetingEventsCompactPretty(w io.Writer, data meetingEventsOutput, tim
|
||||
if data.Identity.Label != "" {
|
||||
fmt.Fprintf(w, "当前身份:%s\n", escapePrettyText(data.Identity.Label))
|
||||
}
|
||||
if len(data.CurrentRoster) > 0 {
|
||||
if len(data.CurrentParticipants) > 0 {
|
||||
fmt.Fprintln(w, "当前名单:")
|
||||
for _, participant := range data.CurrentRoster {
|
||||
for _, participant := range data.CurrentParticipants {
|
||||
fmt.Fprintf(w, "- %s\n", escapePrettyText(participant.Label))
|
||||
}
|
||||
fmt.Fprintln(w)
|
||||
|
||||
@@ -82,7 +82,7 @@ func botInfoErrorStub() *httpmock.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
func meetingDetailRosterStub(roster []interface{}) *httpmock.Stub {
|
||||
func meetingDetailParticipantsStub(participants []interface{}) *httpmock.Stub {
|
||||
return &httpmock.Stub{
|
||||
Method: "GET",
|
||||
URL: "/open-apis/vc/v1/meetings/7628568141510692381",
|
||||
@@ -92,14 +92,14 @@ func meetingDetailRosterStub(roster []interface{}) *httpmock.Stub {
|
||||
"data": map[string]interface{}{
|
||||
"meeting": map[string]interface{}{
|
||||
"id": "7628568141510692381",
|
||||
"participants": roster,
|
||||
"participants": participants,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func meetingDetailRosterErrorStub() *httpmock.Stub {
|
||||
func meetingDetailParticipantsErrorStub() *httpmock.Stub {
|
||||
return &httpmock.Stub{
|
||||
Method: "GET",
|
||||
URL: "/open-apis/vc/v1/meetings/7628568141510692381",
|
||||
@@ -555,7 +555,7 @@ func TestMeetingEvents_ExecuteJSON_PageAll(t *testing.T) {
|
||||
reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, true, "pt_2"))
|
||||
reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, false, ""))
|
||||
reg.Register(botInfoStub())
|
||||
reg.Register(meetingDetailRosterStub(nil))
|
||||
reg.Register(meetingDetailParticipantsStub(nil))
|
||||
|
||||
err := mountAndRun(t, VCMeetingEvents, []string{
|
||||
"+meeting-events",
|
||||
@@ -597,7 +597,7 @@ func TestMeetingEvents_ExecuteJSON(t *testing.T) {
|
||||
f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig())
|
||||
reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, true, "1710000000000000000"))
|
||||
reg.Register(botInfoStub())
|
||||
reg.Register(meetingDetailRosterStub([]interface{}{
|
||||
reg.Register(meetingDetailParticipantsStub([]interface{}{
|
||||
map[string]interface{}{"id": "bot_001", "user_name": "Demo Bot", "participant_type": "2", "role": "4"},
|
||||
map[string]interface{}{"id": "u1", "user_name": "Alice", "participant_type": "1", "role": "1"},
|
||||
}))
|
||||
@@ -617,7 +617,7 @@ func TestMeetingEvents_ExecuteJSON(t *testing.T) {
|
||||
out = strings.ReplaceAll(out, "\n", "")
|
||||
for _, want := range []string{
|
||||
`"identity":{"id":"bot_001","name":"DemoBot","participant_type":"bot","role":"bot","is_self":true,"label":"DemoBot[bot]"}`,
|
||||
`"current_roster":[`,
|
||||
`"current_participants":[`,
|
||||
`"role":"host"`,
|
||||
`"is_self":true`,
|
||||
`"event_type":"participant_joined"`,
|
||||
@@ -641,11 +641,11 @@ func TestMeetingEvents_ExecuteJSON(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMeetingEvents_ExecuteJSON_RosterErrorDoesNotBlockEvents(t *testing.T) {
|
||||
func TestMeetingEvents_ExecuteJSON_ParticipantsErrorDoesNotBlockEvents(t *testing.T) {
|
||||
f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig())
|
||||
reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, false, ""))
|
||||
reg.Register(botInfoStub())
|
||||
reg.Register(meetingDetailRosterErrorStub())
|
||||
reg.Register(meetingDetailParticipantsErrorStub())
|
||||
|
||||
err := mountAndRun(t, VCMeetingEvents, []string{
|
||||
"+meeting-events",
|
||||
@@ -662,9 +662,9 @@ func TestMeetingEvents_ExecuteJSON_RosterErrorDoesNotBlockEvents(t *testing.T) {
|
||||
out = strings.ReplaceAll(out, "\n", "")
|
||||
for _, want := range []string{
|
||||
`"event_type":"participant_joined"`,
|
||||
`"current_roster":[]`,
|
||||
`"current_participants":[]`,
|
||||
`"warnings":[`,
|
||||
`current_rosterunavailable`,
|
||||
`current_participantsunavailable`,
|
||||
} {
|
||||
if !strings.Contains(out, want) {
|
||||
t.Fatalf("json output missing %q: %s", want, stdout.String())
|
||||
@@ -676,7 +676,7 @@ func TestMeetingEvents_ExecuteJSON_BotIdentityErrorDoesNotBlockEvents(t *testing
|
||||
f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig())
|
||||
reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, false, ""))
|
||||
reg.Register(botInfoErrorStub())
|
||||
reg.Register(meetingDetailRosterStub(nil))
|
||||
reg.Register(meetingDetailParticipantsStub(nil))
|
||||
|
||||
err := mountAndRun(t, VCMeetingEvents, []string{
|
||||
"+meeting-events",
|
||||
@@ -706,7 +706,7 @@ func TestMeetingEvents_ExecuteJSON_BotIdentityErrorDoesNotBlockEvents(t *testing
|
||||
func TestMeetingEvents_ExecuteJSON_UserIdentitySkipsBotInfo(t *testing.T) {
|
||||
f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig())
|
||||
reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, false, ""))
|
||||
reg.Register(meetingDetailRosterStub([]interface{}{
|
||||
reg.Register(meetingDetailParticipantsStub([]interface{}{
|
||||
map[string]interface{}{"id": "ou_testuser", "user_name": "Current User", "participant_type": "1", "role": "1"},
|
||||
map[string]interface{}{"id": "u1", "user_name": "Alice", "participant_type": "1", "role": "1"},
|
||||
}))
|
||||
@@ -726,7 +726,7 @@ func TestMeetingEvents_ExecuteJSON_UserIdentitySkipsBotInfo(t *testing.T) {
|
||||
out = strings.ReplaceAll(out, "\n", "")
|
||||
for _, want := range []string{
|
||||
`"identity":{"id":"ou_testuser","participant_type":"human","role":"user","is_self":true,"label":"ou_testuser[human,user]"}`,
|
||||
`"current_roster":[`,
|
||||
`"current_participants":[`,
|
||||
`"id":"ou_testuser"`,
|
||||
`"is_self":true`,
|
||||
`"event_type":"participant_joined"`,
|
||||
@@ -742,7 +742,7 @@ func TestMeetingEvents_ExecuteJSON_OngoingMeetingOmitsEndTime(t *testing.T) {
|
||||
f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig())
|
||||
reg.Register(meetingEventsStub([]interface{}{participantJoinedEventOngoing()}, false, ""))
|
||||
reg.Register(botInfoStub())
|
||||
reg.Register(meetingDetailRosterStub(nil))
|
||||
reg.Register(meetingDetailParticipantsStub(nil))
|
||||
|
||||
err := mountAndRun(t, VCMeetingEvents, []string{
|
||||
"+meeting-events",
|
||||
@@ -798,7 +798,7 @@ func TestMeetingEvents_ExecuteNDJSONIncludesMetadataRow(t *testing.T) {
|
||||
f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig())
|
||||
reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, true, "1710000000000000000"))
|
||||
reg.Register(botInfoStub())
|
||||
reg.Register(meetingDetailRosterStub([]interface{}{
|
||||
reg.Register(meetingDetailParticipantsStub([]interface{}{
|
||||
map[string]interface{}{"id": "bot_001", "user_name": "Demo Bot", "participant_type": "2", "role": "4"},
|
||||
}))
|
||||
|
||||
@@ -833,7 +833,7 @@ func TestMeetingEvents_ExecuteNDJSONIncludesMetadataRow(t *testing.T) {
|
||||
`"has_more":true`,
|
||||
`"page_token":"1710000000000000000"`,
|
||||
`"identity":`,
|
||||
`"current_roster":[`,
|
||||
`"current_participants":[`,
|
||||
} {
|
||||
if !strings.Contains(lines[1], want) {
|
||||
t.Fatalf("metadata ndjson row missing %q: %s", want, lines[1])
|
||||
@@ -845,7 +845,7 @@ func TestMeetingEvents_ExecuteJSON_PrunesEmptySlices(t *testing.T) {
|
||||
f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig())
|
||||
reg.Register(meetingEventsStub([]interface{}{chatReceivedEvent()}, false, ""))
|
||||
reg.Register(botInfoStub())
|
||||
reg.Register(meetingDetailRosterStub(nil))
|
||||
reg.Register(meetingDetailParticipantsStub(nil))
|
||||
|
||||
err := mountAndRun(t, VCMeetingEvents, []string{
|
||||
"+meeting-events",
|
||||
@@ -879,7 +879,7 @@ func TestMeetingEvents_ExecuteJSON_PreservesReactionItems(t *testing.T) {
|
||||
f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig())
|
||||
reg.Register(meetingEventsStub([]interface{}{mixedChatAndReactionEvent()}, false, ""))
|
||||
reg.Register(botInfoStub())
|
||||
reg.Register(meetingDetailRosterStub(nil))
|
||||
reg.Register(meetingDetailParticipantsStub(nil))
|
||||
|
||||
err := mountAndRun(t, VCMeetingEvents, []string{
|
||||
"+meeting-events",
|
||||
@@ -913,7 +913,7 @@ func TestMeetingEvents_ExecutePretty(t *testing.T) {
|
||||
f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig())
|
||||
reg.Register(meetingEventsStub([]interface{}{participantJoinedEventOngoing(), multiChatReceivedEvent(), magicShareStartedEvent()}, true, "1710000000000000000"))
|
||||
reg.Register(botInfoStub())
|
||||
reg.Register(meetingDetailRosterStub([]interface{}{
|
||||
reg.Register(meetingDetailParticipantsStub([]interface{}{
|
||||
map[string]interface{}{"id": "bot_001", "user_name": "Demo Bot", "participant_type": "2", "role": "4"},
|
||||
map[string]interface{}{"id": "u1", "user_name": "Alice", "participant_type": "1", "role": "1"},
|
||||
}))
|
||||
@@ -960,7 +960,7 @@ func TestMeetingEvents_ExecutePretty_PrintsPageTokenWithoutHasMore(t *testing.T)
|
||||
f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig())
|
||||
reg.Register(meetingEventsStub([]interface{}{participantJoinedEventOngoing()}, false, "pt_last"))
|
||||
reg.Register(botInfoStub())
|
||||
reg.Register(meetingDetailRosterStub(nil))
|
||||
reg.Register(meetingDetailParticipantsStub(nil))
|
||||
|
||||
err := mountAndRun(t, VCMeetingEvents, []string{
|
||||
"+meeting-events",
|
||||
@@ -986,7 +986,7 @@ func TestMeetingEvents_ExecuteEmpty(t *testing.T) {
|
||||
f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig())
|
||||
reg.Register(meetingEventsStub(nil, false, ""))
|
||||
reg.Register(botInfoStub())
|
||||
reg.Register(meetingDetailRosterStub(nil))
|
||||
reg.Register(meetingDetailParticipantsStub(nil))
|
||||
|
||||
err := mountAndRun(t, VCMeetingEvents, []string{
|
||||
"+meeting-events",
|
||||
@@ -1317,7 +1317,7 @@ func TestMeetingEventsIdentityFromParticipant_UnknownUserType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildMeetingEventsOutput_EnrichesUnknownRosterTypeFromActors(t *testing.T) {
|
||||
func TestBuildMeetingEventsOutput_EnrichesUnknownParticipantTypeFromActors(t *testing.T) {
|
||||
event := participantJoinedEvent()
|
||||
payload := common.GetMap(event, "payload")
|
||||
items := common.GetSlice(payload, "participant_joined_items")
|
||||
@@ -1333,21 +1333,21 @@ func TestBuildMeetingEventsOutput_EnrichesUnknownRosterTypeFromActors(t *testing
|
||||
map[string]interface{}{"id": "ou_bot", "user_type": 0, "role": "3"},
|
||||
}, meetingEventsIdentity{})
|
||||
|
||||
if got := len(out.CurrentRoster); got != 1 {
|
||||
t.Fatalf("current_roster len = %d, want 1", got)
|
||||
if got := len(out.CurrentParticipants); got != 1 {
|
||||
t.Fatalf("current_participants len = %d, want 1", got)
|
||||
}
|
||||
if got := out.CurrentRoster[0].ParticipantType; got != "bot" {
|
||||
t.Fatalf("current_roster participant_type = %q, want bot: %#v", got, out.CurrentRoster[0])
|
||||
if got := out.CurrentParticipants[0].ParticipantType; got != "bot" {
|
||||
t.Fatalf("current_participants participant_type = %q, want bot: %#v", got, out.CurrentParticipants[0])
|
||||
}
|
||||
if got := out.CurrentRoster[0].Name; got != "Meeting Bot" {
|
||||
t.Fatalf("current_roster name = %q, want actor name", got)
|
||||
if got := out.CurrentParticipants[0].Name; got != "Meeting Bot" {
|
||||
t.Fatalf("current_participants name = %q, want actor name", got)
|
||||
}
|
||||
if got := out.CurrentRoster[0].Label; got != "Meeting Bot [bot,participant]" {
|
||||
t.Fatalf("current_roster label = %q, want enriched bot label", got)
|
||||
if got := out.CurrentParticipants[0].Label; got != "Meeting Bot [bot,participant]" {
|
||||
t.Fatalf("current_participants label = %q, want enriched bot label", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildMeetingEventsOutput_DoesNotOverwriteRosterName(t *testing.T) {
|
||||
func TestBuildMeetingEventsOutput_DoesNotOverwriteParticipantName(t *testing.T) {
|
||||
event := participantJoinedEvent()
|
||||
payload := common.GetMap(event, "payload")
|
||||
items := common.GetSlice(payload, "participant_joined_items")
|
||||
@@ -1360,14 +1360,14 @@ func TestBuildMeetingEventsOutput_DoesNotOverwriteRosterName(t *testing.T) {
|
||||
}
|
||||
|
||||
out := buildMeetingEventsOutput(map[string]interface{}{}, []interface{}{event}, []interface{}{
|
||||
map[string]interface{}{"id": "ou_user", "user_name": "Roster Name", "user_type": 1, "role": "3"},
|
||||
map[string]interface{}{"id": "ou_user", "user_name": "Participant Name", "user_type": 1, "role": "3"},
|
||||
}, meetingEventsIdentity{})
|
||||
|
||||
if got := out.CurrentRoster[0].Name; got != "Roster Name" {
|
||||
t.Fatalf("current_roster name = %q, want roster name", got)
|
||||
if got := out.CurrentParticipants[0].Name; got != "Participant Name" {
|
||||
t.Fatalf("current_participants name = %q, want participant name", got)
|
||||
}
|
||||
if got := out.CurrentRoster[0].Label; got != "Roster Name [human,participant]" {
|
||||
t.Fatalf("current_roster label = %q, want roster label", got)
|
||||
if got := out.CurrentParticipants[0].Label; got != "Participant Name [human,participant]" {
|
||||
t.Fatalf("current_participants label = %q, want participant label", got)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ metadata:
|
||||
- 再根据 `note_id`、`minute_token` 和用户意图,按 [`lark-vc`](../lark-vc/SKILL.md) 的产物决策读取正文、逐字稿或妙记。
|
||||
- 想看参会人快照:用 `vc meeting get --with-participants`(见 [`lark-vc`](../lark-vc/SKILL.md))
|
||||
5. **默认必须使用** **`--page-all`**,除非用户明确要求“只查一页”,或确实需要控制返回体大小。
|
||||
6. 命令默认输出结构化事件契约:`meeting`、`identity`、`current_roster`、`events`、`warnings`、`has_more`、`page_token`;参会人含 `participant_type`、`role`、`is_self` 和可读 `label`,事件细节保留在 `payload`。
|
||||
6. 命令默认输出结构化事件契约:`meeting`、`identity`、`current_participants`、`events`、`warnings`、`has_more`、`page_token`;参会人含 `participant_type`、`role`、`is_self` 和可读 `label`,事件细节保留在 `payload`。
|
||||
7. 输出格式默认优先 `--format pretty`(时间线更易读,并带当前身份与当前名单标签);需要稳定字段做结构化处理时用 `--format json`;需要流式消费事件时用 `--format ndjson`。
|
||||
8. **必须识别分页信号**:只要响应里出现 `has_more=true`、pretty 里的 `more available`,或返回了非空 `page_token`,就不能把当前结果当作完整事件流;默认应继续分页,或明确告诉用户当前只是部分结果。
|
||||
9. 保留响应里的 `page_token`,下次增量拉取直接续,不要从头再拉。
|
||||
|
||||
@@ -110,7 +110,7 @@ lark-cli vc +meeting-events --as user --meeting-id <id> --page-all --format pret
|
||||
|
||||
### 5. 输出格式差异
|
||||
|
||||
- `--format json`:结构化契约,顶层包含 `meeting`、`identity`、`current_roster`、`events`、`has_more`、`page_token`。参会人身份统一含 `participant_type`、`role`、`is_self`、`label`;每条事件保留 `payload` 便于追溯细节。
|
||||
- `--format json`:结构化契约,顶层包含 `meeting`、`identity`、`current_participants`、`events`、`has_more`、`page_token`。参会人身份统一含 `participant_type`、`role`、`is_self`、`label`;每条事件保留 `payload` 便于追溯细节。
|
||||
- `--format pretty`:默认推荐格式,输出当前身份、当前名单和逐条时间线,适合快速理解“发生了什么”。
|
||||
- `--format ndjson`:输出事件行,并带 metadata 行,适合流式消费。
|
||||
|
||||
@@ -160,7 +160,7 @@ lark-cli vc +meeting-events --as user --meeting-id <id> --page-all --format pret
|
||||
|------|------|
|
||||
| `meeting` | 会议身份与时间状态,包含 `id/topic/meeting_no/start_time/end_time/status` |
|
||||
| `identity` | 当前读取身份,包含 `id/name/participant_type/role/is_self/label` |
|
||||
| `current_roster` | 服务端当前名单;当 roster 缺少姓名或类型为 `unknown` 时,CLI 会用同 ID 的事件 actor 信息补全,不做完整历史 replay |
|
||||
| `current_participants` | 服务端当前参会人名单;当参会人缺少姓名或类型为 `unknown` 时,CLI 会用同 ID 的事件 actor 信息补全,不做完整历史 replay |
|
||||
| `events` | 结构化事件列表;每条事件含 `actors` 和事件细节 `payload` |
|
||||
| `warnings` | 非阻断告警列表,例如当前名单补充信息不可用;事件列表本身仍可使用 |
|
||||
| `has_more` | 是否还有下一页 |
|
||||
|
||||
Reference in New Issue
Block a user