| 
									
										
										
										
											2017-06-16 10:33:35 +02:00
										 |  |  | package xmpp | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2017-08-11 19:59:19 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2017-08-11 19:59:19 +02:00
										 |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 17:45:42 +02:00
										 |  |  | 	xmpp "github.com/mattn/go-xmpp" | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 	log "github.com/sirupsen/logrus" | 
					
						
							| 
									
										
										
										
											2017-08-11 17:45:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/genofire/logmania/bot" | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | 	"github.com/genofire/logmania/database" | 
					
						
							| 
									
										
										
										
											2017-06-16 10:33:35 +02:00
										 |  |  | 	"github.com/genofire/logmania/lib" | 
					
						
							|  |  |  | 	"github.com/genofire/logmania/notify" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | const ( | 
					
						
							|  |  |  | 	proto      = "xmpp:" | 
					
						
							|  |  |  | 	protoGroup = "xmpp-muc:" | 
					
						
							|  |  |  | 	nickname   = "logmania" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var logger = log.WithField("notify", proto) | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-16 10:33:35 +02:00
										 |  |  | type Notifier struct { | 
					
						
							|  |  |  | 	notify.Notifier | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 	client    *xmpp.Client | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | 	channels  map[string]bool | 
					
						
							|  |  |  | 	db        *database.DB | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 	formatter *log.TextFormatter | 
					
						
							| 
									
										
										
										
											2017-06-16 10:33:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | func Init(config *lib.NotifyConfig, db *database.DB, bot *bot.Bot) notify.Notifier { | 
					
						
							| 
									
										
										
										
											2017-06-16 10:33:35 +02:00
										 |  |  | 	options := xmpp.Options{ | 
					
						
							|  |  |  | 		Host:          config.XMPP.Host, | 
					
						
							|  |  |  | 		User:          config.XMPP.Username, | 
					
						
							|  |  |  | 		Password:      config.XMPP.Password, | 
					
						
							|  |  |  | 		NoTLS:         config.XMPP.NoTLS, | 
					
						
							|  |  |  | 		Debug:         config.XMPP.Debug, | 
					
						
							|  |  |  | 		Session:       config.XMPP.Session, | 
					
						
							|  |  |  | 		Status:        config.XMPP.Status, | 
					
						
							|  |  |  | 		StatusMessage: config.XMPP.StatusMessage, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	client, err := options.NewClient() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 		logger.Error(err) | 
					
						
							| 
									
										
										
										
											2017-06-16 10:33:35 +02:00
										 |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-08-11 17:45:42 +02:00
										 |  |  | 	go func() { | 
					
						
							|  |  |  | 		for { | 
					
						
							|  |  |  | 			chat, err := client.Recv() | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | 				if err == io.EOF { | 
					
						
							|  |  |  | 					client, err = options.NewClient() | 
					
						
							|  |  |  | 					log.Warn("reconnect") | 
					
						
							|  |  |  | 					if err != nil { | 
					
						
							|  |  |  | 						log.Panic(err) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					continue | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 				logger.Warn(err) | 
					
						
							| 
									
										
										
										
											2017-08-11 17:45:42 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			switch v := chat.(type) { | 
					
						
							|  |  |  | 			case xmpp.Chat: | 
					
						
							|  |  |  | 				bot.Handle(func(answer string) { | 
					
						
							|  |  |  | 					client.SendHtml(xmpp.Chat{Remote: v.Remote, Type: "chat", Text: answer}) | 
					
						
							| 
									
										
										
										
											2017-08-11 19:59:19 +02:00
										 |  |  | 				}, fmt.Sprintf("xmpp:%s", strings.Split(v.Remote, "/")[0]), v.Text) | 
					
						
							| 
									
										
										
										
											2017-08-11 17:45:42 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | 	for _, toAddresses := range db.HostTo { | 
					
						
							|  |  |  | 		for to, _ := range toAddresses { | 
					
						
							|  |  |  | 			toAddr := strings.TrimPrefix(to, protoGroup) | 
					
						
							|  |  |  | 			client.JoinMUCNoHistory(toAddr, nickname) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 	logger.Info("startup") | 
					
						
							|  |  |  | 	return &Notifier{ | 
					
						
							|  |  |  | 		client: client, | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | 		db:     db, | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 		formatter: &log.TextFormatter{ | 
					
						
							|  |  |  | 			DisableTimestamp: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-16 10:33:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | func (n *Notifier) Send(e *log.Entry) error { | 
					
						
							|  |  |  | 	e, to := n.db.SendTo(e) | 
					
						
							| 
									
										
										
										
											2017-08-10 20:11:35 +02:00
										 |  |  | 	if to == nil { | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 		return errors.New("no reciever found") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	text, err := n.formatter.Format(e) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2017-08-10 20:11:35 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-08-11 19:59:19 +02:00
										 |  |  | 	for _, toAddr := range to { | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | 		if strings.HasPrefix(toAddr, protoGroup) { | 
					
						
							|  |  |  | 			toAddr = strings.TrimPrefix(toAddr, protoGroup) | 
					
						
							|  |  |  | 			if _, ok := n.channels[toAddr]; ok { | 
					
						
							|  |  |  | 				n.client.JoinMUCNoHistory(toAddr, nickname) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			_, err = n.client.SendHtml(xmpp.Chat{Remote: toAddr, Type: "groupchat", Text: string(text)}) | 
					
						
							| 
									
										
										
										
											2017-08-11 19:59:19 +02:00
										 |  |  | 			if err != nil { | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 				logger.Error("xmpp to ", to, " error:", err) | 
					
						
							| 
									
										
										
										
											2017-08-11 19:59:19 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | 			toAddr = strings.TrimPrefix(toAddr, proto) | 
					
						
							|  |  |  | 			_, err := n.client.SendHtml(xmpp.Chat{Remote: toAddr, Type: "chat", Text: string(text)}) | 
					
						
							| 
									
										
										
										
											2017-08-11 19:59:19 +02:00
										 |  |  | 			if err != nil { | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 				logger.Error("xmpp to ", to, " error:", err) | 
					
						
							| 
									
										
										
										
											2017-08-11 19:59:19 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-10 20:11:35 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | func (n *Notifier) Close() { | 
					
						
							|  |  |  | 	for jid := range n.channels { | 
					
						
							|  |  |  | 		n.client.LeaveMUC(jid) | 
					
						
							| 
									
										
										
										
											2017-10-25 00:36:16 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-10 18:57:36 +01:00
										 |  |  | 	n.client.Close() | 
					
						
							| 
									
										
										
										
											2017-06-16 10:33:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func init() { | 
					
						
							| 
									
										
										
										
											2017-08-09 08:45:45 +02:00
										 |  |  | 	notify.AddNotifier(Init) | 
					
						
							| 
									
										
										
										
											2017-06-16 10:33:35 +02:00
										 |  |  | } |