package main import ( "context" "fmt" "gosrc.io/xmpp" "gosrc.io/xmpp/stanza" ) // This file has small functions that can be used to do XMPP stuff without writing tons of boilerplate // Basic message sender. Anything more complex should be written by hand func sendMessage(c xmpp.Sender, sendTo string, msgType stanza.StanzaType, body string, subject string, thread string, exts []stanza.MsgExtension) error { m := stanza.Message{ Attrs: stanza.Attrs{ To: sendTo, Type: msgType, }, Body: body, Subject: subject, Thread: thread, Extensions: exts, } err := c.Send(m) if err != nil { return err } return nil } // Joins a MUC func joinMuc(c xmpp.Sender, jid string, muc string, nick string, password string) error { var joinPresence stanza.Presence addr := muc + "/" + nick if password == "" { joinPresence = stanza.Presence{ Attrs: stanza.Attrs{ From: jid, To: addr, }, Extensions: []stanza.PresExtension{ &stanza.MucPresence{}, }, } } else { joinPresence = stanza.Presence{ Attrs: stanza.Attrs{ From: jid, To: addr, }, Extensions: []stanza.PresExtension{ &stanza.MucPresence{ Password: password, }, }, } } err := client.Send(joinPresence) if err != nil { return err } return nil } func joinMucWithoutHistory(c xmpp.Sender, jid string, muc string, nick string, password string) error { var joinPresence stanza.Presence addr := muc + "/" + nick if password == "" { joinPresence = stanza.Presence{ Attrs: stanza.Attrs{ From: jid, To: addr, }, Extensions: []stanza.PresExtension{ &stanza.MucPresence{ History: stanza.History{ MaxChars: stanza.NewNullableInt(0), MaxStanzas: stanza.NewNullableInt(0), Seconds: stanza.NewNullableInt(0), }, }, }, } } else { joinPresence = stanza.Presence{ Attrs: stanza.Attrs{ From: jid, To: addr, }, Extensions: []stanza.PresExtension{ &stanza.MucPresence{ Password: password, History: stanza.History{ MaxChars: stanza.NewNullableInt(0), MaxStanzas: stanza.NewNullableInt(0), Seconds: stanza.NewNullableInt(0), }, }, }, } } err := client.Send(joinPresence) if err != nil { return err } return nil } // jid MustParse but using gosrc's instead of mellium // This function will panic if its an invalid JID func JidMustParse(s string) *stanza.Jid { j, err := stanza.NewJid(s) if err != nil { panic(err) } return j } func sendVoiceRequest(c xmpp.Sender, sendTo string) error { err := c.SendRaw(fmt.Sprintf(` http://jabber.org/protocol/muc#request participant `, clientroot.Session.BindJid, sendTo)) if err != nil { return err } return nil } func addPEPBookmark(c xmpp.Sender, jid string, name string, nick string, autojoin bool, password string) (stanza.IQ, error) { item := new(stanza.Item) item.Id = jid bookmark := Bookmark{} bookmark.Name = name bookmark.Autojoin = autojoin bookmark.Nick = nick bookmark.Password = password node := bookmark.ToNode() options_form := new(stanza.Form) options_form.Type = "submit" persist := new(stanza.Field) persist.Type = "boolean" persist.Var = "pubsub#persist_items" persist.ValuesList = []string{"true"} options_form.Fields = append(options_form.Fields, persist) max_items := new(stanza.Field) max_items.Type = "text-single" max_items.Var = "pubsub#max_items" max_items.ValuesList = []string{"max"} options_form.Fields = append(options_form.Fields, max_items) send_last_published_item := new(stanza.Field) send_last_published_item.Type = "text-single" send_last_published_item.Var = "pubsub#send_last_published_item" send_last_published_item.ValuesList = []string{"never"} options_form.Fields = append(options_form.Fields, send_last_published_item) access_model := new(stanza.Field) access_model.Type = "text-single" access_model.Var = "pubsub#access_model" access_model.ValuesList = []string{"whitelist"} options_form.Fields = append(options_form.Fields, access_model) options := new(stanza.PublishOptions) options.Form = options_form item.Any = node items := []stanza.Item{*item} pubsub, err := stanza.NewPublishItemOptsRq("", "urn:xmpp:bookmarks:1", items, options) if err != nil { return stanza.IQ{}, err } ctx := context.TODO() channel, err := c.SendIQ(ctx, pubsub) if err != nil { return stanza.IQ{}, err } result := <-channel return result, nil }