send to threema
This commit is contained in:
parent
587e0b1e15
commit
90c5f4c5e1
|
@ -1,18 +1,55 @@
|
|||
package threema
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"github.com/o3ma/o3"
|
||||
|
||||
type ThreemaAccount struct {
|
||||
ID string
|
||||
"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
|
||||
}
|
||||
|
||||
func (t *Threema) getAccount(jid string) *ThreemaAccount {
|
||||
return &ThreemaAccount{}
|
||||
}
|
||||
|
||||
func (a *ThreemaAccount) Send(to string, msg string) error {
|
||||
if a.ID == "" {
|
||||
return errors.New("It was not possible to send, becaouse we have no account for you.\nPlease generate one, by sending `generate` to gateway")
|
||||
func (t *Threema) getAccount(jid *models.JID) *Account {
|
||||
if a, ok := t.accountJID[jid.String()]; ok {
|
||||
return a
|
||||
}
|
||||
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{})
|
||||
// TODO error handling
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
tid.Nick = o3.NewPubNick("xmpp:" + jid.String())
|
||||
|
||||
a := &Account{AccountThreema: account}
|
||||
a.Session = o3.NewSessionContext(tid)
|
||||
a.send, a.recieve, err = a.Session.Run()
|
||||
|
||||
// TODO error handling
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
t.accountJID[jid.String()] = a
|
||||
t.accountTID[string(a.TID)] = a
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *Account) Send(to string, msg string) error {
|
||||
return a.Session.SendTextMessage(to, msg, a.send)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package threema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/bdlm/log"
|
||||
"github.com/o3ma/o3"
|
||||
|
||||
"dev.sum7.eu/genofire/golang-lib/database"
|
||||
|
||||
"dev.sum7.eu/genofire/thrempp/models"
|
||||
)
|
||||
|
||||
func (t *Threema) Bot(from *models.JID, request string) string {
|
||||
server := o3.ThreemaRest{}
|
||||
logger := log.WithFields(map[string]interface{}{
|
||||
"type": "threema",
|
||||
"jid": from.String(),
|
||||
})
|
||||
|
||||
switch request {
|
||||
case "generate":
|
||||
|
||||
// test if account already exists
|
||||
account := t.getAccount(from)
|
||||
if account != nil {
|
||||
return fmt.Sprintf("you already has the threema account with id: %s", string(account.TID))
|
||||
}
|
||||
|
||||
// create account
|
||||
id, err := server.CreateIdentity()
|
||||
if err != nil {
|
||||
logger.Warnf("failed to generate: %s", err)
|
||||
return fmt.Sprintf("failed to create a threema account: %s", err)
|
||||
}
|
||||
//TODO works it
|
||||
if err := database.Read.Where(from).First(from); err != nil {
|
||||
database.Write.Create(from)
|
||||
}
|
||||
|
||||
// store account
|
||||
a := models.AccountThreema{}
|
||||
a.XMPPID = from.ID
|
||||
a.TID = make([]byte, len(id.ID))
|
||||
a.LSK = make([]byte, len(id.LSK))
|
||||
copy(a.TID, id.ID[:])
|
||||
copy(a.LSK, id.LSK[:])
|
||||
database.Write.Create(&a)
|
||||
|
||||
// fetch account and connect
|
||||
account = t.getAccount(from)
|
||||
tid := string(account.TID)
|
||||
if tid != "" {
|
||||
logger.WithField("threema", tid).Info("generate")
|
||||
return fmt.Sprintf("threema account with id: %s", tid)
|
||||
}
|
||||
logger.Warn("failed to generate")
|
||||
return "failed to create a threema account"
|
||||
}
|
||||
return "command not supported"
|
||||
}
|
|
@ -7,34 +7,58 @@ import (
|
|||
"gosrc.io/xmpp"
|
||||
|
||||
"dev.sum7.eu/genofire/thrempp/component"
|
||||
"dev.sum7.eu/genofire/thrempp/models"
|
||||
)
|
||||
|
||||
type Threema struct {
|
||||
component.Component
|
||||
out chan xmpp.Packet
|
||||
accountJID map[string]*Account
|
||||
accountTID map[string]*Account
|
||||
}
|
||||
|
||||
func NewThreema(config map[string]interface{}) (component.Component, error) {
|
||||
return &Threema{}, nil
|
||||
t := &Threema{
|
||||
out: make(chan xmpp.Packet),
|
||||
accountJID: make(map[string]*Account),
|
||||
accountTID: make(map[string]*Account),
|
||||
}
|
||||
// TODO load accounts on startup
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (t *Threema) Connect() (chan xmpp.Packet, error) {
|
||||
t.out = make(chan xmpp.Packet)
|
||||
return t.out, nil
|
||||
}
|
||||
func (t *Threema) Send(packet xmpp.Packet) {
|
||||
switch p := packet.(type) {
|
||||
case xmpp.Message:
|
||||
attrs := p.PacketAttrs
|
||||
account := t.getAccount(attrs.From)
|
||||
log.WithFields(map[string]interface{}{
|
||||
"from": attrs.From,
|
||||
"to": attrs.To,
|
||||
}).Debug(p.Body)
|
||||
threemaID := strings.ToUpper(strings.Split(attrs.To, "@")[0])
|
||||
err := account.Send(threemaID, p.Body)
|
||||
if err != nil {
|
||||
msg := xmpp.NewMessage("chat", "", attrs.From, "", "en")
|
||||
from := models.ParseJID(p.PacketAttrs.From)
|
||||
to := models.ParseJID(p.PacketAttrs.To)
|
||||
|
||||
logger := log.WithFields(map[string]interface{}{
|
||||
"from": from,
|
||||
"to": to,
|
||||
})
|
||||
logger.Debug(p.Body)
|
||||
if to.IsDomain() {
|
||||
msg := xmpp.NewMessage("chat", "", from.String(), "", "en")
|
||||
msg.Body = t.Bot(from, p.Body)
|
||||
t.out <- msg
|
||||
return
|
||||
}
|
||||
|
||||
account := t.getAccount(from)
|
||||
if account == nil {
|
||||
msg := xmpp.NewMessage("chat", "", from.String(), "", "en")
|
||||
msg.Body = "It was not possible to send, becouse we have no account for you.\nPlease generate one, by sending `generate` to this gateway"
|
||||
t.out <- msg
|
||||
return
|
||||
}
|
||||
|
||||
threemaID := strings.ToUpper(to.Local)
|
||||
if err := account.Send(threemaID, p.Body); err != nil {
|
||||
msg := xmpp.NewMessage("chat", "", from.String(), "", "en")
|
||||
msg.Body = err.Error()
|
||||
t.out <- msg
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
|
||||
"dev.sum7.eu/genofire/golang-lib/database"
|
||||
|
@ -16,6 +18,48 @@ func (j *JID) TableName() string {
|
|||
return "jid"
|
||||
}
|
||||
|
||||
func ParseJID(jidString string) (jid *JID) {
|
||||
jidSplitTmp := jidRegex.FindAllStringSubmatch(jidString, -1)
|
||||
|
||||
if len(jidSplitTmp) != 1 {
|
||||
return nil
|
||||
}
|
||||
jidSplit := jidSplitTmp[0]
|
||||
|
||||
return &JID{
|
||||
Local: jidSplit[1],
|
||||
Domain: jidSplit[2],
|
||||
}
|
||||
}
|
||||
|
||||
func (jid *JID) String() string {
|
||||
if jid == nil {
|
||||
return ""
|
||||
}
|
||||
str := jid.Domain
|
||||
if jid.Local != "" {
|
||||
str = jid.Local + "@" + str
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func (jid *JID) IsDomain() bool {
|
||||
return jid != nil && jid.Local == "" && jid.Domain != ""
|
||||
}
|
||||
|
||||
func GetJID(jidStr string) (jid *JID) {
|
||||
jidS := ParseJID(jidStr)
|
||||
err := database.Read.Where(jidS).First(jid).Error
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var jidRegex *regexp.Regexp
|
||||
|
||||
func init() {
|
||||
jidRegex = regexp.MustCompile(`^(?:([^@/<>'\" ]+)@)?([^@/<>'\"]+)(?:/([^<>'\" ][^<>'\"]*))?$`)
|
||||
|
||||
database.AddModel(&JID{})
|
||||
}
|
||||
|
|
Reference in New Issue