// 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
"lab.pztrn.name/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)
}