feat: add direct message testing to XMPP doctor command
- Add reusable MessageBody and XMPPMessage structs to xmpp client - Refactor SendMessage to use shared structs instead of inline definitions - Add SendDirectMessage method for direct user messaging (type="chat") - Enhance doctor command with --test-dm flag (enabled by default) - Add testDirectMessage function that sends test message to admin@localhost - Update help text, examples, and timing measurements for direct messages 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
5551a8bc8d
commit
5d143808a3
4 changed files with 1110 additions and 24 deletions
|
@ -27,6 +27,7 @@ type Config struct {
|
|||
Resource string
|
||||
TestRoom string
|
||||
TestMUC bool
|
||||
TestDirectMessage bool
|
||||
Verbose bool
|
||||
InsecureSkipVerify bool
|
||||
}
|
||||
|
@ -41,20 +42,22 @@ func main() {
|
|||
flag.StringVar(&config.Resource, "resource", defaultResource, "XMPP resource")
|
||||
flag.StringVar(&config.TestRoom, "test-room", defaultTestRoom, "MUC room JID for testing")
|
||||
flag.BoolVar(&config.TestMUC, "test-muc", true, "Enable MUC room testing (join/wait/leave)")
|
||||
flag.BoolVar(&config.TestDirectMessage, "test-dm", true, "Enable direct message testing (send message to admin user)")
|
||||
flag.BoolVar(&config.Verbose, "verbose", true, "Enable verbose logging")
|
||||
flag.BoolVar(&config.InsecureSkipVerify, "insecure-skip-verify", true, "Skip TLS certificate verification (for development)")
|
||||
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, "xmpp-client-doctor - Test XMPP client connectivity and MUC operations\n\n")
|
||||
fmt.Fprintf(os.Stderr, "This tool tests the XMPP client implementation by connecting to an XMPP server,\n")
|
||||
fmt.Fprintf(os.Stderr, "performing connection tests, optionally testing MUC room operations,\n")
|
||||
fmt.Fprintf(os.Stderr, "performing connection tests, optionally testing MUC room operations and direct messages,\n")
|
||||
fmt.Fprintf(os.Stderr, "and then disconnecting gracefully.\n\n")
|
||||
fmt.Fprintf(os.Stderr, "Usage:\n")
|
||||
fmt.Fprintf(os.Stderr, " %s [flags]\n\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, "Examples:\n")
|
||||
fmt.Fprintf(os.Stderr, " %s # Test basic connectivity\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, " %s --test-muc # Test connectivity and MUC operations\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, " %s --test-muc=false # Test connectivity only\n\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, " %s --test-dm # Test connectivity and direct messages\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, " %s --test-muc=false --test-dm=false # Test connectivity only\n\n", os.Args[0])
|
||||
fmt.Fprintf(os.Stderr, "Flags:\n")
|
||||
flag.PrintDefaults()
|
||||
fmt.Fprintf(os.Stderr, "\nDefault values are configured for the development server in ./sidecar/\n")
|
||||
|
@ -75,6 +78,9 @@ func main() {
|
|||
if config.TestMUC {
|
||||
log.Printf(" Test Room: %s", config.TestRoom)
|
||||
}
|
||||
if config.TestDirectMessage {
|
||||
log.Printf(" Test Direct Messages: enabled")
|
||||
}
|
||||
}
|
||||
|
||||
// Test the XMPP client
|
||||
|
@ -89,6 +95,9 @@ func main() {
|
|||
if config.TestMUC {
|
||||
fmt.Println("✅ XMPP MUC operations test passed!")
|
||||
}
|
||||
if config.TestDirectMessage {
|
||||
fmt.Println("✅ XMPP direct message test passed!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,6 +163,7 @@ func testXMPPClient(config *Config) error {
|
|||
}
|
||||
|
||||
var mucDuration time.Duration
|
||||
var dmDuration time.Duration
|
||||
|
||||
// Test MUC operations if requested
|
||||
if config.TestMUC {
|
||||
|
@ -165,6 +175,16 @@ func testXMPPClient(config *Config) error {
|
|||
mucDuration = time.Since(start)
|
||||
}
|
||||
|
||||
// Test direct message if requested
|
||||
if config.TestDirectMessage {
|
||||
start = time.Now()
|
||||
err = testDirectMessage(client, config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("direct message test failed: %w", err)
|
||||
}
|
||||
dmDuration = time.Since(start)
|
||||
}
|
||||
|
||||
if config.Verbose {
|
||||
log.Printf("Disconnecting from XMPP server...")
|
||||
}
|
||||
|
@ -185,11 +205,17 @@ func testXMPPClient(config *Config) error {
|
|||
if config.TestMUC {
|
||||
log.Printf(" MUC operations time: %v", mucDuration)
|
||||
}
|
||||
if config.TestDirectMessage {
|
||||
log.Printf(" Direct message time: %v", dmDuration)
|
||||
}
|
||||
log.Printf(" Disconnect time: %v", disconnectDuration)
|
||||
totalTime := connectDuration + pingDuration + disconnectDuration
|
||||
if config.TestMUC {
|
||||
totalTime += mucDuration
|
||||
}
|
||||
if config.TestDirectMessage {
|
||||
totalTime += dmDuration
|
||||
}
|
||||
log.Printf(" Total time: %v", totalTime)
|
||||
}
|
||||
|
||||
|
@ -265,6 +291,34 @@ func testMUCOperations(client *xmpp.Client, config *Config) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func testDirectMessage(client *xmpp.Client, config *Config) error {
|
||||
if config.Verbose {
|
||||
log.Printf("Testing direct message functionality...")
|
||||
log.Printf("Sending test message to admin user...")
|
||||
}
|
||||
|
||||
// Send a test message to the admin user
|
||||
testMessage := fmt.Sprintf("Test direct message from XMPP doctor at %s", time.Now().Format("15:04:05"))
|
||||
adminJID := "admin@localhost" // Default admin user for development server
|
||||
|
||||
start := time.Now()
|
||||
err := client.SendDirectMessage(adminJID, testMessage)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send direct message to %s: %w", adminJID, err)
|
||||
}
|
||||
sendDuration := time.Since(start)
|
||||
|
||||
if config.Verbose {
|
||||
log.Printf("✅ Successfully sent direct message in %v", sendDuration)
|
||||
log.Printf("Message: %s", testMessage)
|
||||
log.Printf("Recipient: %s", adminJID)
|
||||
log.Printf("Direct message test summary:")
|
||||
log.Printf(" Send message time: %v", sendDuration)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func maskPassword(password string) string {
|
||||
if len(password) <= 2 {
|
||||
return "****"
|
||||
|
|
173
go.mod
173
go.mod
|
@ -3,7 +3,6 @@ module github.com/mattermost/mattermost-plugin-bridge-xmpp
|
|||
go 1.24.3
|
||||
|
||||
require (
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/mattermost/mattermost/server/public v0.1.10
|
||||
github.com/pkg/errors v0.9.1
|
||||
|
@ -13,53 +12,225 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
|
||||
4d63.com/gochecknoglobals v0.2.1 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/4meepo/tagalign v1.3.4 // indirect
|
||||
github.com/Abirdcfly/dupword v0.1.1 // indirect
|
||||
github.com/Antonboom/errname v0.1.13 // indirect
|
||||
github.com/Antonboom/nilnil v0.1.9 // indirect
|
||||
github.com/Antonboom/testifylint v1.4.3 // indirect
|
||||
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
|
||||
github.com/Crocmagnon/fatcontext v0.5.2 // indirect
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
|
||||
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
||||
github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect
|
||||
github.com/alecthomas/go-check-sumtype v0.1.4 // indirect
|
||||
github.com/alexkohler/nakedret/v2 v2.0.4 // indirect
|
||||
github.com/alexkohler/prealloc v1.0.0 // indirect
|
||||
github.com/alingse/asasalint v0.0.11 // indirect
|
||||
github.com/ashanbrown/forbidigo v1.6.0 // indirect
|
||||
github.com/ashanbrown/makezero v1.1.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bkielbasa/cyclop v1.2.1 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/blizzy78/varnamelen v0.8.0 // indirect
|
||||
github.com/bombsimon/wsl/v4 v4.4.1 // indirect
|
||||
github.com/breml/bidichk v0.2.7 // indirect
|
||||
github.com/breml/errchkjson v0.3.6 // indirect
|
||||
github.com/butuzov/ireturn v0.3.0 // indirect
|
||||
github.com/butuzov/mirror v1.2.0 // indirect
|
||||
github.com/catenacyber/perfsprint v0.7.1 // indirect
|
||||
github.com/ccojocar/zxcvbn-go v1.0.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/charithe/durationcheck v0.0.10 // indirect
|
||||
github.com/chavacava/garif v0.1.0 // indirect
|
||||
github.com/ckaznocha/intrange v0.2.0 // indirect
|
||||
github.com/curioswitch/go-reassign v0.2.0 // indirect
|
||||
github.com/daixiang0/gci v0.13.5 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/denis-tingaikin/go-header v0.5.0 // indirect
|
||||
github.com/dnephin/pflag v1.0.7 // indirect
|
||||
github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a // indirect
|
||||
github.com/ettle/strcase v0.2.0 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/fatih/structtag v1.2.0 // indirect
|
||||
github.com/firefart/nonamedreturns v1.0.5 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/fzipp/gocyclo v0.6.0 // indirect
|
||||
github.com/ghostiam/protogetter v0.3.6 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
||||
github.com/go-critic/go-critic v0.11.4 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/go-toolsmith/astcast v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astcopy v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astequal v1.2.0 // indirect
|
||||
github.com/go-toolsmith/astfmt v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astp v1.1.0 // indirect
|
||||
github.com/go-toolsmith/strparse v1.1.0 // indirect
|
||||
github.com/go-toolsmith/typep v1.1.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.1.0 // indirect
|
||||
github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gofrs/flock v0.12.1 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
|
||||
github.com/golangci/gofmt v0.0.0-20240816233607-d8596aa466a9 // indirect
|
||||
github.com/golangci/golangci-lint v1.61.0 // indirect
|
||||
github.com/golangci/misspell v0.6.0 // indirect
|
||||
github.com/golangci/modinfo v0.3.4 // indirect
|
||||
github.com/golangci/plugin-module-register v0.1.1 // indirect
|
||||
github.com/golangci/revgrep v0.5.3 // indirect
|
||||
github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gordonklaus/ineffassign v0.1.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
|
||||
github.com/gostaticanalysis/comment v1.4.2 // indirect
|
||||
github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
|
||||
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.3 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.2 // indirect
|
||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jgautheron/goconst v1.7.1 // indirect
|
||||
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
|
||||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
|
||||
github.com/jjti/go-spancheck v0.6.2 // indirect
|
||||
github.com/jonboulle/clockwork v0.2.2 // indirect
|
||||
github.com/julz/importas v0.1.0 // indirect
|
||||
github.com/karamaru-alpha/copyloopvar v1.1.0 // indirect
|
||||
github.com/kisielk/errcheck v1.7.0 // indirect
|
||||
github.com/kkHAIKE/contextcheck v1.1.5 // indirect
|
||||
github.com/kulti/thelper v0.6.3 // indirect
|
||||
github.com/kunwardeep/paralleltest v1.0.10 // indirect
|
||||
github.com/kyoh86/exportloopref v0.1.11 // indirect
|
||||
github.com/lasiar/canonicalheader v1.1.1 // indirect
|
||||
github.com/ldez/gomoddirectives v0.2.4 // indirect
|
||||
github.com/ldez/tagliatelle v0.5.0 // indirect
|
||||
github.com/leonklingele/grouper v1.1.2 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/lufeee/execinquery v1.2.1 // indirect
|
||||
github.com/macabu/inamedparam v0.1.3 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/maratori/testableexamples v1.0.0 // indirect
|
||||
github.com/maratori/testpackage v1.1.1 // indirect
|
||||
github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect
|
||||
github.com/mattermost/ldap v0.0.0-20231116144001-0f480c025956 // indirect
|
||||
github.com/mattermost/logr/v2 v2.0.21 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mgechev/revive v1.3.9 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moricho/tparallel v0.3.2 // indirect
|
||||
github.com/nakabonne/nestif v0.3.1 // indirect
|
||||
github.com/nishanths/exhaustive v0.12.0 // indirect
|
||||
github.com/nishanths/predeclared v0.2.2 // indirect
|
||||
github.com/nunnatsa/ginkgolinter v0.16.2 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/polyfloyd/go-errorlint v1.6.0 // indirect
|
||||
github.com/prometheus/client_golang v1.12.1 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.32.1 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/quasilyte/go-ruleguard v0.4.3-0.20240823090925-0fe6f58b47b1 // indirect
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect
|
||||
github.com/quasilyte/gogrep v0.5.0 // indirect
|
||||
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
|
||||
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
|
||||
github.com/ryancurrah/gomodguard v1.3.5 // indirect
|
||||
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
|
||||
github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
|
||||
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
|
||||
github.com/sashamelentyev/usestdlibvars v1.27.0 // indirect
|
||||
github.com/securego/gosec/v2 v2.21.2 // indirect
|
||||
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/sivchari/containedctx v1.0.3 // indirect
|
||||
github.com/sivchari/tenv v1.10.0 // indirect
|
||||
github.com/sonatard/noctx v0.0.2 // indirect
|
||||
github.com/sourcegraph/go-diff v0.7.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/cobra v1.8.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.12.0 // indirect
|
||||
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
|
||||
github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.4.1 // indirect
|
||||
github.com/tdakkota/asciicheck v0.2.0 // indirect
|
||||
github.com/tetafro/godot v1.4.17 // indirect
|
||||
github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect
|
||||
github.com/timonwong/loggercheck v0.9.4 // indirect
|
||||
github.com/tinylib/msgp v1.2.5 // indirect
|
||||
github.com/tomarrell/wrapcheck/v2 v2.9.0 // indirect
|
||||
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
|
||||
github.com/ultraware/funlen v0.1.0 // indirect
|
||||
github.com/ultraware/whitespace v0.1.1 // indirect
|
||||
github.com/uudashr/gocognit v1.1.3 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/wiggin77/merror v1.0.5 // indirect
|
||||
github.com/wiggin77/srslog v1.0.1 // indirect
|
||||
github.com/xen0n/gosmopolitan v1.2.2 // indirect
|
||||
github.com/yagipy/maintidx v1.0.0 // indirect
|
||||
github.com/yeya24/promlinter v0.3.0 // indirect
|
||||
github.com/ykadowak/zerologlint v0.1.5 // indirect
|
||||
gitlab.com/bosi/decorder v0.4.2 // indirect
|
||||
go-simpler.org/musttag v0.12.2 // indirect
|
||||
go-simpler.org/sloglint v0.7.2 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/automaxprocs v1.5.3 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/term v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/tools v0.29.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47 // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gotest.tools/gotestsum v1.7.0 // indirect
|
||||
honnef.co/go/tools v0.5.1 // indirect
|
||||
mellium.im/reader v0.1.0 // indirect
|
||||
mellium.im/xmlstream v0.15.4 // indirect
|
||||
mvdan.cc/gofumpt v0.7.0 // indirect
|
||||
mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect
|
||||
)
|
||||
|
||||
tool (
|
||||
github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
gotest.tools/gotestsum
|
||||
)
|
||||
|
|
|
@ -52,6 +52,21 @@ type SendMessageResponse struct {
|
|||
StanzaID string `json:"stanza_id"`
|
||||
}
|
||||
|
||||
// MessageBody represents the body element of an XMPP message
|
||||
type MessageBody struct {
|
||||
XMLName xml.Name `xml:"body"`
|
||||
Text string `xml:",chardata"`
|
||||
}
|
||||
|
||||
// XMPPMessage represents a complete XMPP message stanza
|
||||
type XMPPMessage struct {
|
||||
XMLName xml.Name `xml:"jabber:client message"`
|
||||
Type string `xml:"type,attr"`
|
||||
To string `xml:"to,attr"`
|
||||
From string `xml:"from,attr"`
|
||||
Body MessageBody `xml:"body"`
|
||||
}
|
||||
|
||||
// GhostUser represents an XMPP ghost user
|
||||
type GhostUser struct {
|
||||
JID string `json:"jid"`
|
||||
|
@ -324,26 +339,12 @@ func (c *Client) SendMessage(req MessageRequest) (*SendMessageResponse, error) {
|
|||
sendCtx, cancel := context.WithTimeout(c.ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Create the message body structure
|
||||
type messageBody struct {
|
||||
XMLName xml.Name `xml:"body"`
|
||||
Text string `xml:",chardata"`
|
||||
}
|
||||
|
||||
// Create complete message with body
|
||||
type message struct {
|
||||
XMLName xml.Name `xml:"jabber:client message"`
|
||||
Type string `xml:"type,attr"`
|
||||
To string `xml:"to,attr"`
|
||||
From string `xml:"from,attr"`
|
||||
Body messageBody `xml:"body"`
|
||||
}
|
||||
|
||||
fullMsg := message{
|
||||
fullMsg := XMPPMessage{
|
||||
Type: "groupchat",
|
||||
To: to.String(),
|
||||
From: c.jidAddr.String(),
|
||||
Body: messageBody{Text: req.Message},
|
||||
Body: MessageBody{Text: req.Message},
|
||||
}
|
||||
|
||||
// Send the message using the session encoder
|
||||
|
@ -359,6 +360,39 @@ func (c *Client) SendMessage(req MessageRequest) (*SendMessageResponse, error) {
|
|||
return response, nil
|
||||
}
|
||||
|
||||
// SendDirectMessage sends a direct message to a specific user
|
||||
func (c *Client) SendDirectMessage(userJID, message string) error {
|
||||
if c.session == nil {
|
||||
if err := c.Connect(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
to, err := jid.Parse(userJID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse user JID: %w", err)
|
||||
}
|
||||
|
||||
// Create a context with timeout for the send operation
|
||||
sendCtx, cancel := context.WithTimeout(c.ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Create direct message using reusable structs
|
||||
msg := XMPPMessage{
|
||||
Type: "chat",
|
||||
To: to.String(),
|
||||
From: c.jidAddr.String(),
|
||||
Body: MessageBody{Text: message},
|
||||
}
|
||||
|
||||
// Send the message using the session encoder
|
||||
if err := c.session.Encode(sendCtx, msg); err != nil {
|
||||
return fmt.Errorf("failed to send direct message: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResolveRoomAlias resolves a room alias to room JID
|
||||
func (c *Client) ResolveRoomAlias(roomAlias string) (string, error) {
|
||||
// For XMPP, return the alias as-is if it's already a valid JID
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue