diff --git a/NTFServer.go b/NTFServer.go
index 103c159..f24144a 100644
--- a/NTFServer.go
+++ b/NTFServer.go
@@ -27,6 +27,8 @@ type NTFServer struct {
conns map[string]*libnmdc.HubConnection // hubnick -> hubconn
verbose bool
+ callOnMainThread chan func()
+
contentedMaxBytes int64
// Except the coalesce buffer, that requires a background worker.
@@ -42,11 +44,12 @@ type upstreamMessage struct {
func NewNTFServer(configFile string, verbose bool) (*NTFServer, error) {
ret := NTFServer{
- configFile: configFile,
- hubMessages: make(chan upstreamMessage, 0),
- conns: make(map[string]*libnmdc.HubConnection),
- coalesceBuffer: make(map[string]time.Time),
- verbose: verbose,
+ configFile: configFile,
+ hubMessages: make(chan upstreamMessage, 0),
+ callOnMainThread: make(chan func(), 0),
+ conns: make(map[string]*libnmdc.HubConnection),
+ coalesceBuffer: make(map[string]time.Time),
+ verbose: verbose,
}
// Config
@@ -215,6 +218,12 @@ func (this *NTFServer) Run() error {
log.Fatalf("Upstream update channel closed unexpectedly")
}
this.HandleHubMessage(hubMsg)
+
+ case mtfn, ok := <-this.callOnMainThread:
+ if !ok {
+ log.Fatalf("Synchronisation channel closed unexpectedly")
+ }
+ mtfn()
}
}
@@ -427,25 +436,33 @@ func (this *NTFServer) HandleGroupMessage(update telegram.Update) error {
return this.HandleTelegramUserParted(int64(update.Message.LeftChatMember.ID), update)
}
+ //
+
+ userID := int64(update.Message.From.ID)
+
+ if update.Message.Sticker != nil && this.contentedMaxBytes > 0 {
+ // Sticker
+ go this.uploadStickerWorker(userID, update.Message.Sticker)
+ }
+
if len(update.Message.Text) > 0 {
- // Find the responsible user's upstream connection
- userID := int64(update.Message.From.ID)
- hubNick, ok := this.config.KnownUsers[userID]
- if !ok {
- return fmt.Errorf("Couldn't send public message for user '%d' unexpectedly missing hub nick!", userID)
- }
-
- conn, ok := this.conns[hubNick]
- if !ok {
- return fmt.Errorf("Couldn't send public message for user '%d' (%s) unexpectedly missing upstream connection!", userID, hubNick)
- }
-
// Intercept some bot commands
if update.Message.Text == "/userlist" || update.Message.Text == "/userlist@"+this.botName {
// Display native userlist inside the groupchat
+ // Find the responsible user's upstream connection
+ hubNick, ok := this.config.KnownUsers[userID]
+ if !ok {
+ return fmt.Errorf("Couldn't send public message for user '%d' unexpectedly missing hub nick!", userID)
+ }
+
+ conn, ok := this.conns[hubNick]
+ if !ok {
+ return fmt.Errorf("Couldn't send public message for user '%d' (%s) unexpectedly missing upstream connection!", userID, hubNick)
+ }
+
usernames, err := this.getUserlistText(conn)
if err != nil {
this.GroupChatSayHTML("Can't get userlist for you (internal error)")
@@ -482,20 +499,37 @@ func (this *NTFServer) HandleGroupMessage(update telegram.Update) error {
}
- // Also add it to the coalesce buffer so that we don't replay it from someone else's NMDC connection
- this.Coalesce(hubNick, sendMsg)
-
- // Submit to NMDC
- err := conn.SayPublic(sendMsg)
- if err != nil {
- log.Printf("Failed to deliver message '%s': %s", sendMsg, err.Error())
- this.GroupChatSayHTML(fmt.Sprintf("Couldn't sync message '%s' because: %s", html.EscapeString(sendMsg), html.EscapeString(err.Error())))
- }
+ return this.HubSay(userID, sendMsg)
}
}
// TODO probably a file/image upload???
// TODO support "editing messages" by re-sending them with a ** suffix
+ return nil
+}
+
+func (this *NTFServer) HubSay(userID int64, sendMsg string) error {
+
+ // Find the responsible user's upstream connection
+ hubNick, ok := this.config.KnownUsers[userID]
+ if !ok {
+ return fmt.Errorf("Couldn't send public message for user '%d' unexpectedly missing hub nick!", userID)
+ }
+
+ conn, ok := this.conns[hubNick]
+ if !ok {
+ return fmt.Errorf("Couldn't send public message for user '%d' (%s) unexpectedly missing upstream connection!", userID, hubNick)
+ }
+
+ // Also add it to the coalesce buffer so that we don't replay it from someone else's NMDC connection
+ this.Coalesce(hubNick, sendMsg)
+
+ // Submit to NMDC
+ err := conn.SayPublic(sendMsg)
+ if err != nil {
+ log.Printf("Failed to deliver message '%s': %s", sendMsg, err.Error())
+ this.GroupChatSayHTML(fmt.Sprintf("Couldn't sync message '%s' because: %s", html.EscapeString(sendMsg), html.EscapeString(err.Error())))
+ }
return nil
}
diff --git a/contented.go b/contented.go
index 4da198f..f647d5c 100644
--- a/contented.go
+++ b/contented.go
@@ -57,6 +57,11 @@ func (this *NTFServer) ContentedUploadFromSync(main *telegram.File, thumbs *[]te
func (this *NTFServer) ContentedUploadSync(fileId string, expectSizeBytes int64) (string, error) {
+ // If file fits under size limit, take it
+ if expectSizeBytes > this.contentedMaxBytes {
+ return "", errors.New("The file was too large for the image host server (and no smaller thumbnail is available)")
+ }
+
// Prepare to download the file from telegram
url, err := this.bot.GetFileDirectURL(fileId)
if err != nil {
diff --git a/upload.go b/upload.go
new file mode 100644
index 0000000..1b27cc3
--- /dev/null
+++ b/upload.go
@@ -0,0 +1,43 @@
+package main
+
+import (
+ "errors"
+ "html"
+ "log"
+
+ telegram "github.com/go-telegram-bot-api/telegram-bot-api"
+)
+
+func (this *NTFServer) uploadStickerWorker(userID int64, s *telegram.Sticker) {
+ var conUrl string
+ var err error
+
+ if int64(s.FileSize) < this.contentedMaxBytes {
+ conUrl, err = this.ContentedUploadSync(s.FileID, int64(s.FileSize))
+
+ } else if s.Thumbnail != nil && int64(s.Thumbnail.FileSize) < this.contentedMaxBytes {
+ conUrl, err = this.ContentedUploadSync(s.Thumbnail.FileID, int64(s.Thumbnail.FileSize))
+
+ } else {
+ err = errors.New("File too big and/or bad thumbnail")
+
+ }
+
+ //
+
+ if err != nil {
+ log.Printf("Sticker upload failed: %s", err.Error())
+ this.callOnMainThread <- func() {
+ this.GroupChatSayHTML("Can't upload sticker for native users: " + html.EscapeString(err.Error()) + "")
+ }
+ return
+ }
+
+ // Sticker upload success
+ this.callOnMainThread <- func() {
+ // n.b. this will fail if the user has disconnected by the time the upload completed
+
+ this.HubSay(userID, s.Emoji+" "+conUrl)
+ }
+
+}