// OpenSAPS - Open Slack API server for everyone. // // Copyright (c) 2017, Stanislav N. aka pztrn. // All rights reserved. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . package matrixpusher import ( // stdlib "bytes" crand "crypto/rand" "encoding/json" "errors" "fmt" "io/ioutil" "net/http" "strconv" "strings" // local "gitlab.com/pztrn/opensaps/slack/message" ) // Constants for random transaction ID. const ( letterBytes = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" // 36 possibilities letterIdxBits = 6 // 6 bits to represent 64 possibilities / indexes letterIdxMask = 1< 0 { if strings.Contains(key, "repeatable_item_") { c.Log.Debugln("Repeatable key in pre-stage, skipping:", key) continue } } c.Log.Debugln("Processing message data key:", key) // Check if we have an item with "_url" appendix. This means // that we should generate a link. val_url, found := message_data[key+"_url"] // Generate a link and put into message if key with "_url" // was found. var s string = "" if found { c.Log.Debugln("Found _url key, will create HTML link") s = fmt.Sprintf("%s", val_url, value) } else { c.Log.Debugln("Found no _url key, will use as-is") s = value } msg_tpl = strings.Replace(msg_tpl, "{"+key+"}", s, -1) } // Process repeatables. repeatable_tpl, repeatable_found := message_data["repeatable_message"] if repeatable_found { var repeatables_string string = "" repeatables_count, _ := strconv.Atoi(message_data["repeatables_count"]) idx := 0 for { if idx == repeatables_count { c.Log.Debug("IDX goes above repeatables_count, breaking loop") break } var repstring string = repeatable_tpl for i := range repeatables { c.Log.Debugln("Processing repeatable variable:", repeatables[i]+strconv.Itoa(idx)) var data string = "" rdata := message_data["repeatable_item_"+repeatables[i]+strconv.Itoa(idx)] rurl, rurl_found := message_data["repeatable_item_"+repeatables[i]+strconv.Itoa(idx)+"_url"] if rurl_found { c.Log.Debugln("Found _url key, will create HTML link") data = fmt.Sprintf("%s", rurl, rdata) } else { c.Log.Debugln("Found no _url key, will use as-is") data = rdata } repstring = strings.Replace(repstring, "{"+repeatables[i]+"}", data, -1) } repeatables_string += repstring c.Log.Debugln("Repeatable string:", repstring) idx += 1 } msg_tpl = strings.Replace(msg_tpl, "{repeatables}", repeatables_string, -1) } msg_tpl = strings.Replace(msg_tpl, "{newline}", "
", -1) // Replace all "\n" with "
". msg_tpl = strings.Replace(msg_tpl, "\n", "
", -1) c.Log.Debugln("Crafted message:", msg_tpl) // Send message. mxc.SendMessage(msg_tpl) } // This function sends already prepared message to room. func (mxc *MatrixConnection) SendMessage(message string) { c.Log.Debugf("Sending message to connection '%s': '%s'", mxc.conn_name, message) // We should send notices as it is preferred behaviour for bots and // appservices. //msgStr := fmt.Sprintf(`{"msgtype": "m.text", "body": "%s", "format": "org.matrix.custom.html", "formatted_body": "%s"}`, message, message) msg := MatrixMessage{} msg.MsgType = "m.notice" msg.Body = message msg.Format = "org.matrix.custom.html" msg.FormattedBody = message msgBytes, err := json.Marshal(&msg) if err != nil { c.Log.Errorln("Failed to marshal message into JSON:", err.Error()) return } msgStr := string(msgBytes) reply, err := mxc.doPutRequest("/rooms/"+mxc.room_id+"/send/m.room.message/"+mxc.generateTnxId(), msgStr) if err != nil { c.Log.Fatalf("Failed to send message to room '%s' (conn: '%s'): %s", mxc.room_id, mxc.conn_name, err.Error()) } c.Log.Debugf("Message sent, reply: %s", string(reply)) } func (mxc *MatrixConnection) Shutdown() { c.Log.Infof("Shutting down connection '%s'...", mxc.conn_name) _, err := mxc.doPostRequest("/logout", "{}") if err != nil { c.Log.Errorf("Error occured while trying to log out from Matrix (conn %s): %s", mxc.conn_name, err.Error()) } mxc.token = "" c.Log.Infof("Connection '%s' successfully shutted down", mxc.conn_name) }