diff --git a/xmpp.go b/xmpp.go index c12dd52..e20b57a 100644 --- a/xmpp.go +++ b/xmpp.go @@ -536,12 +536,13 @@ func (c *Client) IsEncrypted() bool { // Chat is an incoming or outgoing XMPP chat message. type Chat struct { - Remote string - Type string - Text string - Roster Roster - Other []string - Stamp time.Time + Remote string + Type string + Text string + Roster Roster + Other []string + OtherElem []XMLElement + Stamp time.Time } type Roster []Contact @@ -584,11 +585,12 @@ func (c *Client) Recv() (stanza interface{}, err error) { v.Delay.Stamp, ) chat := Chat{ - Remote: v.From, - Type: v.Type, - Text: v.Body, - Other: v.Other, - Stamp: stamp, + Remote: v.From, + Type: v.Type, + Text: v.Body, + Other: v.OtherStrings(), + OtherElem: v.Other, + Stamp: stamp, } return chat, nil case *clientQuery: @@ -720,11 +722,46 @@ type clientMessage struct { Thread string `xml:"thread"` // Any hasn't matched element - Other []string `xml:",any"` + Other []XMLElement `xml:",any"` Delay Delay `xml:"delay"` } +func (m *clientMessage) OtherStrings() []string { + a := make([]string, len(m.Other)) + for i, e := range m.Other { + a[i] = e.String() + } + return a +} + +type XMLElement struct { + XMLName xml.Name + InnerXML string `xml:",innerxml"` +} + +func (e *XMLElement) String() string { + r := bytes.NewReader([]byte(e.InnerXML)) + d := xml.NewDecoder(r) + var buf bytes.Buffer + for { + tok, err := d.Token() + if err != nil { + break + } + switch v := tok.(type) { + case xml.StartElement: + err = d.Skip() + case xml.CharData: + _, err = buf.Write(v) + } + if err != nil { + break + } + } + return buf.String() +} + type Delay struct { Stamp string `xml:"stamp,attr"` } diff --git a/xmpp_test.go b/xmpp_test.go index a1a56f6..51f02eb 100644 --- a/xmpp_test.go +++ b/xmpp_test.go @@ -57,7 +57,7 @@ func (*testConn) SetWriteDeadline(time.Time) error { var text = strings.TrimSpace(` - {"random": "text"} + {"random": "<text>"} @@ -80,9 +80,24 @@ func TestStanzaError(t *testing.T) { chat := Chat{ Type: "error", Other: []string{ - "\n\t\t{\"random\": \"text\"}\n\t", + "\n\t\t{\"random\": \"\"}\n\t", "\n\t\t\n\t\t\n\t", }, + OtherElem: []XMLElement{ + XMLElement{ + XMLName: xml.Name{Space: "google:mobile:data", Local: "gcm"}, + InnerXML: "\n\t\t{\"random\": \"<text>\"}\n\t", + }, + XMLElement{ + XMLName: xml.Name{Space: "jabber:client", Local: "error"}, + InnerXML: ` + + + InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n + + `, + }, + }, } if !reflect.DeepEqual(v, chat) { t.Errorf("Recv() = %#v; want %#v", v, chat)