/* Copyright Martin Dosch Licensed under the "MIT License" */ package main import ( "log" "strings" "github.com/xmppo/go-xmpp" ) func processStanzas(client *xmpp.Client, muc string, mucNick string, feeds []string, quiet bool, contact string) { for { // Receive stanzas. stanza, err := client.Recv() if err != nil { log.Fatal("Error: Failed receiving Stanzas:", err) } // Check stanzas, maybe we want to reply. switch v := stanza.(type) { // Reply to requests for source and feeds. case xmpp.Chat: var command string // Check for room mention of the bots nick if the the message type is groupchat. if v.Type == "groupchat" { // Leave if option quiet is set. if quiet { break } // Get first word of the message and transform it to lower case. mention := strings.ToLower(strings.Split(v.Text, " ")[0]) // If it is not the bots nick remove one trailing character as // a lot of clients append `:` or `,` to mentions. if mention != strings.ToLower(mucNick) { mentionLength := len(mention) // Leave if mentionLength is <= 0 if mentionLength <= 0 { break } mention = mention[:mentionLength-1] // Leave if the message is not addressed to the bot. if mention != strings.ToLower(mucNick) { break } } // As the first word is the mention of the bots nickname, the command is // the second word in a groupchat message. command = strings.ToLower(strings.Split(v.Text, " ")[1]) // If the message type is chat (e.g. private message), the command is the // first word. } else if v.Type == "chat" { command = strings.ToLower(strings.Split(v.Text, " ")[0]) } else { break } // Check for the command. switch command { // Reply with a short summary of available commands for `help`. case "help": reply := "The following commands are available:\n" + "\"contact\": Show contact for this bot.\n" + "\"feeds\": List feeds I'm following.\n" + "\"ping\": Sends back a pong.\n" + "\"source\": Show source code URL." if v.Type == "groupchat" { _, err = client.Send(xmpp.Chat{ Remote: muc, Type: "groupchat", Text: strings.Split(v.Remote, "/")[1] + ": " + reply, }) if err != nil { log.Fatal("Error: Failed sending message to MUC:", err) } } else if v.Type == "chat" { _, err = client.Send(xmpp.Chat{ Remote: v.Remote, Type: "chat", Text: reply, }) if err != nil { log.Fatal("Error: Failed sending message to ", v.Remote, ": ", err) } } // Reply with repo address for `source`. case "source": reply := "My source can be found at " + "https://salsa.debian.org/mdosch/feed-to-muc" if v.Type == "groupchat" { _, err = client.Send(xmpp.Chat{ Remote: muc, Type: "groupchat", Text: strings.Split(v.Remote, "/")[1] + ": " + reply, }) if err != nil { log.Fatal("Error: Failed sending message to MUC:", err) } } else if v.Type == "chat" { _, err = client.Send(xmpp.Chat{ Remote: v.Remote, Type: "chat", Text: reply, }) if err != nil { log.Fatal("Error: Failed sending message to ", v.Remote, ": ", err) } } // Reply with the list of monitored feeds for `feeds`. case "feeds": var feedList string for _, feed := range feeds { // Add next feed element and a newline. feedList = feedList + feed + "\n" } reply := "Feeds I'm following:\n" + feedList if v.Type == "groupchat" { _, err = client.Send(xmpp.Chat{ Remote: muc, Type: "groupchat", Text: strings.Split(v.Remote, "/")[1] + ": " + reply, }) if err != nil { log.Fatal("Error: Failed sending message to MUC:", err) } } else if v.Type == "chat" { _, err = client.Send(xmpp.Chat{ Remote: v.Remote, Type: "chat", Text: reply, }) if err != nil { log.Fatal("Error: Failed sending message to ", v.Remote, ": ", err) } } // Reply with pong to ping requests. case "ping", "bing": var reply string if command == "bing" { reply = "bong" } else { reply = "pong" } if v.Type == "groupchat" { _, err = client.Send(xmpp.Chat{ Remote: muc, Type: "groupchat", Text: strings.Split(v.Remote, "/")[1] + ": " + reply, }) if err != nil { log.Fatal("Error: Failed sending message to MUC:", err) } } else if v.Type == "chat" { _, err = client.Send(xmpp.Chat{ Remote: v.Remote, Type: "chat", Text: reply, }) if err != nil { log.Fatal("Error: Failed sending message to ", v.Remote, ": ", err) } } // Reply with contact address if set. case "contact": if contact == "" { contact = "Sorry, no contact information provided." } if v.Type == "groupchat" { _, err = client.Send(xmpp.Chat{ Remote: muc, Type: "groupchat", Text: strings.Split(v.Remote, "/")[1] + ": " + contact, }) if err != nil { log.Fatal("Error: Failed sending message to MUC:", err) } } else if v.Type == "chat" { _, err = client.Send(xmpp.Chat{ Remote: v.Remote, Type: "chat", Text: contact, }) if err != nil { log.Fatal("Error: Failed sending message to ", v.Remote, ": ", err) } } } // Reply to pings and disco queries. case xmpp.IQ: if (v.Type == "error") && (v.ID == ID) { log.Fatal("MUC not available. processStanza") } if (v.Type == "result") && (v.ID == ID) { pingReceived = true } if v.Type == "get" { // Reply to disco#info requests according to https://xmpp.org/extensions/xep-0030.html. if strings.Contains(string(v.Query), "") { _, err := client.RawInformation(client.JID(), v.From, v.ID, "result", ""+ ""+ "") if err != nil { log.Fatal("Error: Failed to reply to disco#info:", err) } } else if strings.Contains(string(v.Query), "") { // Reply to pings. _, err := client.RawInformation(client.JID(), v.From, v.ID, "result", "") if err != nil { log.Fatal("Error: Failed to reply to ping:", err) } } else { // Send error replies for all other IQs. _, err := client.RawInformation(client.JID(), v.From, v.ID, "error", "") if err != nil { log.Fatal("Error: Failed to send error IQ:", err) } } } default: break } } }