Files
lambda/xmpp-helpers.go
T
2026-08-16 20:07:53 +01:00

203 lines
4.9 KiB
Go

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(`
<message from='%s'
id='yd53c486'
to='%s'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE'>
<value>http://jabber.org/protocol/muc#request</value>
</field>
<field var='muc#role'
type='list-single'
label='Requested role'>
<value>participant</value>
</field>
</x>
</message>
`, 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
}