0

I'm trying to host a bot Telegram in a serverless site such as Vercel. I'm essentially channeling this tutorial; for the time being, I'm hosting it locally and binding it to a bot using ngrok. The program goes like this...

package handler

import (
    "fmt"
    "net/http"
    "time"
    "encoding/json"
    "github.com/go-telegram-bot-api/telegram-bot-api"
    "log"
    "io/ioutil"
)

type Hito struct {
    URI  string
    Title string
    fecha time.Time
}

type Response struct {
    Msg string `json:"text"`
    ChatID int64 `json:"chat_id"`
    Method string `json:"method"`
}

var hitos = []Hito {
    Hito {
        URI: "0.Repositorio",
        Title: "Datos básicos y repo",
        fecha: time.Date(2020, time.September, 29, 11, 30, 0, 0, time.UTC),
    },
    Hito {
        URI: "5.Serverless",
        Title: "Trabajando con funciones serverless",
        fecha: time.Date(2020, time.November, 22, 11, 30, 0, 0, time.UTC),
    },

}


func Handler(w http.ResponseWriter, r *http.Request) {
    defer r.Body.Close()
    body, _ := ioutil.ReadAll(r.Body)
    var update tgbotapi.Update
    if err := json.Unmarshal(body,&update); err != nil {
        log.Fatal("Error en el update →", err)
    }
    log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
    currentTime := time.Now()
    var next int
    var queda time.Duration
    for indice, hito := range hitos {
        if ( hito.fecha.After( currentTime ) ) {
            next = indice
            queda = hito.fecha.Sub( currentTime )
        }
    }
    if update.Message.IsCommand() {
        text := ""
        switch update.Message.Command() {
        case "kk":
            if ( next > 0 ) {
                text = queda.String()
            } else {
                text = "Ninguna entrega próxima"
            }
            default:
                text = "No me sé ese comando"
        }
        msg := fmt.Sprintf("{\"text\": \"%s\", %d,\"method\":\"sendMessage\"}",
            text,
            update.Message.Chat.ID, 
        )
        log.Printf("JSON %s", msg)
        fmt.Fprintf(w,msg)
    }
}

Whole code is here. Anyway, problem seems to be in the last statement: fmt.Fprintf(w,msg) is supposed to print the response to the Golang http.ResponseWriter, but it never arrives to its destination. JSON, as printed by the log, seems OK

{"text": "232h47m23.215314069s", 14974002,"method":"sendMessage"}

I'm not totally sure where to either access the response from Telegram, or access the log in Telegram to see what's actually sent, or if I'm doing the whole thing correctly. Any idea where to start looking?

Update: in the comments, it's been pointed out it does not seem valid JSON; however, it's the format used in the original tutorial, and I can't seem to find the correct field name for that value.

Update 2: tested with another JSON value:

{"text": "232h32m43.981011101s", "chat_id": "14974002","method":"sendMessage"}

same result.

jjmerelo
  • 22,578
  • 8
  • 40
  • 86
  • 1
    `fmt.Fprintf(w,string(data))` doesn't appear in your code though, did you quote the wrong code? – Adrian Nov 12 '20 at 18:46
  • 1
    Also if it's supposed to be JSON, then that might be your problem, because it's not valid JSON. `14974002` has no field name. In general it's better to use `encoding/json` to produce JSON output rather than using `fmt`. – Adrian Nov 12 '20 at 18:48
  • @Adrian correct, it's now fixed. The problem is that seems to be the format that is used in the tutorial I link. There does not seem to be any place where the actual name of the field is used. I tried encoding/json before, same failure. As a matter of fact, I defined a Response for marshalling initially, that didn't work either. – jjmerelo Nov 12 '20 at 18:53
  • You might have better luck using data specs from the official documentation rather than from some tutorial on Medium: https://core.telegram.org/bots/api - and it does appear to expect valid JSON, which might explain why your invalid JSON wouldn't work. – Adrian Nov 12 '20 at 18:57
  • @Adrian tried with valid JSON, no luck either. Would there be any way to set the mime type of the http.ResponseWriter?--- well, that was the thing: https://stackoverflow.com/questions/51456253/how-to-set-http-responsewriter-content-type-header-globally-for-all-api-endpoint explained how to set the type – jjmerelo Nov 12 '20 at 18:59
  • Yes, you can set the `Content-Type` header. – Adrian Nov 12 '20 at 19:00

0 Answers0