154 lines
3.7 KiB
Go
154 lines
3.7 KiB
Go
package threema
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"github.com/bdlm/log"
|
|
"github.com/o3ma/o3"
|
|
"gosrc.io/xmpp"
|
|
|
|
"dev.sum7.eu/genofire/golang-lib/database"
|
|
|
|
"dev.sum7.eu/genofire/thrempp/models"
|
|
)
|
|
|
|
type Account struct {
|
|
models.AccountThreema
|
|
Session o3.SessionContext
|
|
send chan<- o3.Message
|
|
recieve <-chan o3.ReceivedMsg
|
|
deliveredMSG map[uint64]string
|
|
readedMSG map[uint64]string
|
|
}
|
|
|
|
func (t *Threema) getAccount(jid *models.JID) (*Account, error) {
|
|
if a, ok := t.accountJID[jid.String()]; ok {
|
|
return a, nil
|
|
}
|
|
account := models.AccountThreema{}
|
|
|
|
database.Read.Where("xmpp_id = (?)",
|
|
database.Read.Table(jid.TableName()).Select("id").Where(map[string]interface{}{
|
|
"local": jid.Local,
|
|
"domain": jid.Domain,
|
|
}).QueryExpr()).First(&account)
|
|
|
|
var lsk [32]byte
|
|
copy(lsk[:], account.LSK[:])
|
|
tid, err := o3.NewThreemaID(string(account.TID), lsk, o3.AddressBook{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
tid.Nick = o3.NewPubNick("xmpp:" + jid.String())
|
|
|
|
a := &Account{AccountThreema: account}
|
|
a.Session = o3.NewSessionContext(tid)
|
|
a.send, a.recieve, err = a.Session.Run()
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
a.XMPP = *jid
|
|
a.deliveredMSG = make(map[uint64]string)
|
|
a.readedMSG = make(map[uint64]string)
|
|
|
|
go a.reciever(t.out)
|
|
|
|
t.accountJID[jid.String()] = a
|
|
return a, nil
|
|
}
|
|
|
|
func (a *Account) reciever(out chan<- xmpp.Packet) {
|
|
for receivedMessage := range a.recieve {
|
|
if receivedMessage.Err != nil {
|
|
log.Warnf("Error Receiving Message: %s\n", receivedMessage.Err)
|
|
continue
|
|
}
|
|
switch msg := receivedMessage.Msg.(type) {
|
|
case o3.TextMessage:
|
|
sender := msg.Sender().String()
|
|
if string(a.TID) == sender {
|
|
continue
|
|
}
|
|
xMSG := xmpp.NewMessage("chat", sender, a.XMPP.String(), strconv.FormatUint(msg.ID(), 10), "en")
|
|
xMSG.Body = msg.Text()
|
|
xMSG.Extensions = append(xMSG.Extensions, xmpp.ReceiptRequest{})
|
|
xMSG.Extensions = append(xMSG.Extensions, xmpp.ChatMarkerMarkable{})
|
|
out <- xMSG
|
|
|
|
case o3.DeliveryReceiptMessage:
|
|
msgID := msg.MsgID()
|
|
xMSG := xmpp.NewMessage("chat", msg.Sender().String(), a.XMPP.String(), "", "en")
|
|
|
|
if msg.Status() == o3.MSGDELIVERED {
|
|
if id, ok := a.deliveredMSG[msgID]; ok {
|
|
xMSG.Extensions = append(xMSG.Extensions, xmpp.ReceiptReceived{Id: id})
|
|
xMSG.Extensions = append(xMSG.Extensions, xmpp.ChatMarkerReceived{Id: id})
|
|
delete(a.deliveredMSG, msgID)
|
|
} else {
|
|
log.Warnf("found not id in cache to announce received on xmpp side")
|
|
}
|
|
}
|
|
if msg.Status() == o3.MSGREAD {
|
|
if id, ok := a.readedMSG[msgID]; ok {
|
|
xMSG.Extensions = append(xMSG.Extensions, xmpp.ChatMarkerDisplayed{Id: id})
|
|
delete(a.readedMSG, msgID)
|
|
} else {
|
|
log.Warnf("found not id in cache to announce readed on xmpp side")
|
|
}
|
|
}
|
|
|
|
if len(xMSG.Extensions) > 0 {
|
|
out <- xMSG
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (a *Account) Send(to string, msg xmpp.Message) error {
|
|
msgID := ""
|
|
readed := false
|
|
for _, el := range msg.Extensions {
|
|
switch ex := el.(type) {
|
|
case *xmpp.ReceiptReceived:
|
|
msgID = ex.Id
|
|
case *xmpp.ChatMarkerReceived:
|
|
msgID = ex.Id
|
|
case *xmpp.ChatMarkerDisplayed:
|
|
readed = true
|
|
msgID = ex.Id
|
|
}
|
|
}
|
|
if msgID != "" {
|
|
id, err := strconv.ParseUint(msgID, 10, 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
msgType := o3.MSGDELIVERED
|
|
if readed {
|
|
msgType = o3.MSGREAD
|
|
}
|
|
drm, err := o3.NewDeliveryReceiptMessage(&a.Session, to, id, msgType)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
a.send <- drm
|
|
log.WithFields(map[string]interface{}{
|
|
"tid": to,
|
|
"msg_id": id,
|
|
"type": msgType,
|
|
}).Debug("update status of threema message")
|
|
return nil
|
|
}
|
|
|
|
msg3, err := o3.NewTextMessage(&a.Session, to, msg.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
a.deliveredMSG[msg3.ID()] = msg.Id
|
|
a.readedMSG[msg3.ID()] = msg.Id
|
|
a.send <- msg3
|
|
return nil
|
|
}
|