From 11b48bde97ee1c3bf55463181605f64132c1cf2f Mon Sep 17 00:00:00 2001 From: Rogee Date: Sun, 16 Aug 2026 20:02:38 +0800 Subject: [PATCH] H-162: fall back to mapped assignee for XST routing (#38) Co-authored-by: Rogee --- .../shangwutong/internal/delivery/outbound.go | 2 +- .../internal/delivery/outbound_test.go | 22 ++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/channels/shangwutong/internal/delivery/outbound.go b/channels/shangwutong/internal/delivery/outbound.go index 7ae04181..43ecf4a0 100644 --- a/channels/shangwutong/internal/delivery/outbound.go +++ b/channels/shangwutong/internal/delivery/outbound.go @@ -327,7 +327,7 @@ func (o *Outbound) xstRoute(ctx context.Context, message *dbgen.OutboundMessage) if err != nil { return nil, fmt.Errorf("load XST conversation state: %w", err) } - route := &swt.XSTRoute{SID: message.SwtSid, CID: value(mapping.XstCid), Token: value(mapping.XstToken), State: value(state), KFName: value(mapping.XstKfname)} + route := &swt.XSTRoute{SID: message.SwtSid, CID: value(mapping.XstCid), Token: value(mapping.XstToken), State: value(state), KFName: firstText(value(mapping.XstKfname), value(mapping.SwtAssigneeName))} if err := route.Validate(); err != nil { return nil, err } diff --git a/channels/shangwutong/internal/delivery/outbound_test.go b/channels/shangwutong/internal/delivery/outbound_test.go index d3d854f7..8e2aca26 100644 --- a/channels/shangwutong/internal/delivery/outbound_test.go +++ b/channels/shangwutong/internal/delivery/outbound_test.go @@ -63,8 +63,11 @@ func TestXSTOutboundRequiresBothStagesAndEcho(t *testing.T) { primaryCalls, xstCalls := 0, 0 sender := senderStub{ beforeReturn: func() { primaryCalls++ }, - xst: func(swt.XSTRoute, string) (swt.SendResult, error) { + xst: func(route swt.XSTRoute, _ string) (swt.SendResult, error) { xstCalls++ + if route.KFName != "口腔客服2" { + t.Fatalf("XST KFName = %q", route.KFName) + } return swt.SendResult{Status: "ok"}, nil }, } @@ -690,11 +693,14 @@ func deliveryDatabase(t *testing.T, ctx context.Context) (*store.Store, *dbgen.A func seedXSTRoute(t *testing.T, database *store.Store, account *dbgen.Account) { t.Helper() ctx := context.Background() - events := []swt.HeartbeatEvent{ - {SessionID: "visitor", Kind: 65, Text: "xst|sbox\x1axst-route-token\x1aquery\x1aword\x1acity\x1a48989266", SeqID: 41, RawLine: "xst profile"}, - {SessionID: "visitor", Kind: 31, OpName: "agent", Text: "ACT_XST|NotShow|QuDaoVisitorInfoMsg|private", SeqID: 42, RawLine: "xst state"}, - {SessionID: "visitor", Kind: 0, OpName: "agent", Text: "5", SeqID: 43, RawLine: "chatting"}, - {SessionID: "visitor", Kind: 24, Text: "cid-1", SeqID: 44, RawLine: "cid"}, + events, err := swt.ParseHeartbeatBody( + "visitor 65 %7Cxst%7Csbox%1Axst-route-token%1Aquery%1Aword%1Acity%1A48989266 41 639183484622475271\r\n" + + "visitor 31 %7Cdistribute_lastoname%7C%E5%8F%A3%E8%85%94%E5%AE%A2%E6%9C%8D2 42 639183484622475272\r\n" + + "visitor 31 %7CACT_XST%7CNotShow%7CQuDaoVisitorInfoMsg%7Cprivate 43 639183484622475273\r\n" + + "visitor 0 %7C5 44 639183484622475274\r\n" + + "visitor 24 cid-1 45 639183484622475275\r\n") + if err != nil { + t.Fatal(err) } if _, err := database.PersistHeartbeat(ctx, account, events); err != nil { t.Fatal(err) @@ -705,6 +711,10 @@ func seedXSTRoute(t *testing.T, database *store.Store, account *dbgen.Account) { t.Fatalf("seed XST route = %v, %v", worked, err) } } + mapping, err := database.Reader().GetConversationMap(ctx, dbgen.GetConversationMapParams{AccountID: account.ID, SwtSid: "visitor"}) + if err != nil || mapping.XstKfname != nil || mapping.SwtAssigneeName == nil || *mapping.SwtAssigneeName != "口腔客服2" { + t.Fatalf("real heartbeat mapping = %#v, %v", mapping, err) + } } func deliveryPayload(t *testing.T, attachments []gochat.WebhookAttachment) string {