| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | package threema | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 	"errors" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 	"strconv" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/bdlm/log" | 
					
						
							|  |  |  | 	"github.com/o3ma/o3" | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | 	"gosrc.io/xmpp/stanza" | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | func (a *Account) receiver(out chan<- stanza.Packet) { | 
					
						
							| 
									
										
										
										
											2019-06-02 10:41:19 +02:00
										 |  |  | 	for receivedMessage := range a.receive { | 
					
						
							| 
									
										
										
										
											2019-06-03 00:02:18 +02:00
										 |  |  | 		if receivedMessage.Err != nil { | 
					
						
							|  |  |  | 			log.Warnf("Error Receiving Message: %s\n", receivedMessage.Err) | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | 			xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, To: a.XMPP.String()}) | 
					
						
							| 
									
										
										
										
											2019-06-03 00:02:18 +02:00
										 |  |  | 			xMSG.Body = fmt.Sprintf("error on decoding message:\n%v", receivedMessage.Err) | 
					
						
							|  |  |  | 			out <- xMSG | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 		sender := receivedMessage.Msg.Sender().String() | 
					
						
							|  |  |  | 		if string(a.TID) == sender { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 		if p, err := a.receiving(receivedMessage.Msg); err != nil { | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | 			xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String()}) | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 			xMSG.Body = fmt.Sprintf("error on decoding message: %s\n%v", err, receivedMessage.Msg.Serialize()) | 
					
						
							|  |  |  | 			out <- xMSG | 
					
						
							|  |  |  | 		} else if p != nil { | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 			out <- p | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | func requestExtensions(xMSG *stanza.Message) { | 
					
						
							|  |  |  | 	xMSG.Extensions = append(xMSG.Extensions, stanza.ReceiptRequest{}) | 
					
						
							|  |  |  | 	xMSG.Extensions = append(xMSG.Extensions, stanza.Markable{}) | 
					
						
							|  |  |  | 	xMSG.Extensions = append(xMSG.Extensions, stanza.StateActive{}) | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, error) { | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 	logger := log.WithFields(map[string]interface{}{ | 
					
						
							|  |  |  | 		"from": receivedMessage.Sender().String(), | 
					
						
							|  |  |  | 		"to":   a.XMPP.String(), | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	switch msg := receivedMessage.(type) { | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 	case o3.TextMessage: | 
					
						
							|  |  |  | 		sender := msg.Sender().String() | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | 		xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String(), Id: strconv.FormatUint(msg.ID(), 10)}) | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 		xMSG.Body = msg.Text() | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 		requestExtensions(&xMSG) | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 		logger.WithField("text", xMSG.Body).Debug("send text") | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 		return xMSG, nil | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-02 23:49:26 +02:00
										 |  |  | 	case o3.AudioMessage: | 
					
						
							|  |  |  | 		if a.threema.httpUploadPath == "" { | 
					
						
							|  |  |  | 			return nil, errors.New("no place to store files at transport configurated") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		data, err := msg.GetAudioData(a.Session) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 			logger.Warnf("unable to read data from message: %s", err) | 
					
						
							| 
									
										
										
										
											2019-06-02 23:49:26 +02:00
										 |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		xMSG, err := a.FileToXMPP(msg.Sender().String(), msg.ID(), "mp3", data) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 			logger.Warnf("unable to create data from message: %s", err) | 
					
						
							| 
									
										
										
										
											2019-06-02 23:49:26 +02:00
										 |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		xMSG.Type = "chat" | 
					
						
							|  |  |  | 		requestExtensions(&xMSG) | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 		logger.WithField("url", xMSG.Body).Debug("send audio") | 
					
						
							| 
									
										
										
										
											2019-06-02 23:49:26 +02:00
										 |  |  | 		return xMSG, nil | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 	case o3.ImageMessage: | 
					
						
							|  |  |  | 		if a.threema.httpUploadPath == "" { | 
					
						
							|  |  |  | 			return nil, errors.New("no place to store files at transport configurated") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		data, err := msg.GetImageData(a.Session) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 			logger.Warnf("unable to read data from message: %s", err) | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		xMSG, err := a.FileToXMPP(msg.Sender().String(), msg.ID(), "jpg", data) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 			logger.Warnf("unable to create data from message: %s", err) | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		xMSG.Type = "chat" | 
					
						
							|  |  |  | 		requestExtensions(&xMSG) | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 		logger.WithField("url", xMSG.Body).Debug("send image") | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 		return xMSG, nil | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	case o3.DeliveryReceiptMessage: | 
					
						
							|  |  |  | 		msgID := msg.MsgID() | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | 		xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: msg.Sender().String(), To: a.XMPP.String()}) | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 		state := "" | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if msg.Status() == o3.MSGDELIVERED { | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 			state = "delivered" | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 			if id, ok := a.deliveredMSG[msgID]; ok { | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | 				xMSG.Extensions = append(xMSG.Extensions, stanza.ReceiptReceived{ID: id}) | 
					
						
							|  |  |  | 				xMSG.Extensions = append(xMSG.Extensions, stanza.MarkReceived{ID: id}) | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 				delete(a.deliveredMSG, msgID) | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 				logger.Warnf("found not id in cache to announce received on xmpp side") | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if msg.Status() == o3.MSGREAD { | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 			state = "displayed" | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 			if id, ok := a.readedMSG[msgID]; ok { | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | 				xMSG.Extensions = append(xMSG.Extensions, stanza.MarkDisplayed{ID: id}) | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 				delete(a.readedMSG, msgID) | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 				logger.Warnf("found not id in cache to announce readed on xmpp side") | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if len(xMSG.Extensions) > 0 { | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 			logger.WithField("state", state).Debug("send state") | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 			return xMSG, nil | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 		return nil, nil | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 	case o3.TypingNotificationMessage: | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | 		xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: msg.Sender().String(), To: a.XMPP.String(), Id: strconv.FormatUint(msg.ID(), 10)}) | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 		if msg.OnOff != 0 { | 
					
						
							|  |  |  | 			logger.Debug("composing") | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | 			xMSG.Extensions = append(xMSG.Extensions, stanza.StateComposing{}) | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			logger.Debug("inactive") | 
					
						
							| 
									
										
										
										
											2019-06-28 03:03:38 +02:00
										 |  |  | 			xMSG.Extensions = append(xMSG.Extensions, stanza.StateInactive{}) | 
					
						
							| 
									
										
										
										
											2019-06-06 20:53:06 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return xMSG, nil | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-06-02 21:39:21 +02:00
										 |  |  | 	return nil, errors.New("not known data format") | 
					
						
							| 
									
										
										
										
											2019-06-02 00:50:54 +02:00
										 |  |  | } |