diff --git a/ircevent/irc.go b/ircevent/irc.go index c942b00..148a169 100644 --- a/ircevent/irc.go +++ b/ircevent/irc.go @@ -56,6 +56,7 @@ var ( SASLFailed = errors.New("SASL setup timed out. Does the server support SASL?") CapabilityNotNegotiated = errors.New("The IRCv3 capability required for this was not negotiated") + NoLabeledResponse = errors.New("The server failed to send a labeled response to the command") serverDidNotQuit = errors.New("server did not respond to QUIT") clientHasQuit = errors.New("client has called Quit()") @@ -396,6 +397,26 @@ func (irc *Connection) SendWithLabel(callback func(*Batch), tags map[string]stri return err } +// GetLabeledResponse sends an IRC message using the IRCv3 labeled-response +// specification, then synchronously waits for the response, which is returned +// as a *Batch. If the server fails to respond correctly, an error will be +// returned. +func (irc *Connection) GetLabeledResponse(tags map[string]string, command string, params ...string) (batch *Batch, err error) { + done := make(chan empty) + err = irc.SendWithLabel(func(b *Batch) { + batch = b + close(done) + }, tags, command, params...) + if err != nil { + return + } + <-done + if batch == nil { + err = NoLabeledResponse + } + return +} + // Send a raw string. func (irc *Connection) SendRaw(message string) error { mlen := len(message) diff --git a/ircevent/irc_labeledresponse_test.go b/ircevent/irc_labeledresponse_test.go index 1b57d42..7dc1ed0 100644 --- a/ircevent/irc_labeledresponse_test.go +++ b/ircevent/irc_labeledresponse_test.go @@ -277,3 +277,32 @@ func synchronize(irc *Connection) { }, nil, "PING", "!") <-event } + +func TestSynchronousLabeledResponse(t *testing.T) { + irccon := connForTesting("go-eventirc", "go-eventirc", false) + irccon.Debug = true + irccon.RequestCaps = []string{"message-tags", "batch", "labeled-response"} + irccon.RealName = "Al_b6AHLrxh8TZb5kNO1gw" + err := irccon.Connect() + if err != nil { + t.Fatalf("labeled response connection failed: %s", err) + } + go irccon.Loop() + + batch, err := irccon.GetLabeledResponse(nil, "WHOIS", irccon.CurrentNick()) + if err != nil { + t.Fatalf("labeled response failed: %v", err) + } + assertEqual(batch.Command, "BATCH") + results := make(map[string]string) + for _, line := range batch.Items { + results[line.Command] = line.Params[len(line.Params)-1] + } + + // RPL_WHOISUSER, last param is the realname + assertEqual(results["311"], "Al_b6AHLrxh8TZb5kNO1gw") + if _, ok := results["379"]; !ok { + t.Errorf("Expected 379 RPL_WHOISMODES in response, but not received") + } + assertEqual(len(irccon.batches), 0) +}