iT邦幫忙

0

GO (golang) 用 json 方式送出 telagrem bot 訊息

原本用 curl 送 telagrem bot 訊息 是

curl -X POST \
     -H 'Content-Type: application/json' \
     -d '{"chat_id": "123456789", "text": "This is a test from curl", "disable_notification": true}' \
     https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage

想用 go 來寫寫看 ... 寫出來會 400 錯誤

package main
import (
    "net/http"
    "encoding/json"
    "fmt"
    "bytes"
)

func main() {
    request_url := "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage"
    client := &http.Client{}
  
    values := make(map[string]interface{})
    values["chat_id"] = "123456789"
    values["text"] = "This is a test from curl"
    values["disable_notification"] =  true

    jsonStr, _ := json.Marshal(values)
    req, _ := http.NewRequest("POST", request_url, bytes.NewBuffer(jsonStr))
    req.Header.Set("content-type", "application-json")

    res, err := client.Do(req)
    if(err != nil){
        fmt.Println(err)
    } else {
        fmt.Println(res.Status)
    }
}

當然不用 json 也可送 telegram ....只是想練習看看 ....

看更多先前的討論...收起先前的討論...
dragonH iT邦超人 5 級 ‧ 2020-04-25 14:32:42 檢舉
所以 error 的內容是什麼
echochio iT邦高手 1 級 ‧ 2020-04-26 01:44:15 檢舉
就 400 的錯誤
dragonH iT邦超人 5 級 ‧ 2020-04-26 02:18:03 檢舉
400 應該是叫做 http error code

理論上它應該會跟你說原因

token invalid 之類的
echochio iT邦高手 1 級 ‧ 2020-04-26 08:53:23 檢舉
{"ok":false,"error_code":400,"description":"Bad Request: message text is empty"}
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

不明
【**此則訊息已被站方移除**】
0
froce
iT邦大師 1 級 ‧ 2020-04-25 12:57:31
values := make(map[string]interface{})
values["chat_id"] = "123456789"
values["text"] = "This is a test from curl"
values["disable_notification"] =  true

改成這樣試試。

type Message struct {
	Chat_id                    string   `json:"chat_id"`
	Text                       string   `json:"text"`
	Disable_notification       bool   `json:"disable_notification"`
}

m := Message{"123456789", "This is a test from curl", true}
jsonStr, _ := json.Marshal(m)

你用map[string]interface{}對於golang這種強型別的靜態語言來說可能太模糊了。
Unmarshal可能可以接受,Marshal的話通常會先自定義資料型態。
然後偷懶不想定struct的話可以用MarshalIndent試試。
https://golang.org/pkg/encoding/json/#example_MarshalIndent

看更多先前的回應...收起先前的回應...
echochio iT邦高手 1 級 ‧ 2020-04-25 13:17:38 檢舉
package main
import (
    "net/http"
    "encoding/json"
    "fmt"
    "bytes"
)

type Message struct {
	Chat_id                    string   `json:"chat_id"`
	Text                       string   `json:"text"`
	Disable_notification       bool   `json:"disable_notification"`
}

func main() {
    request_url := "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage"
    client := &http.Client{}
    
    m := Message{"123456789", "This is a test", true}
    jsonStr, _ := json.Marshal(m)
    
    req, _ := http.NewRequest("POST", request_url, bytes.NewBuffer(jsonStr))
    req.Header.Set("content-type", "application-json")

    res, err := client.Do(req)
    if(err != nil){
        fmt.Println(err)
    } else {
        fmt.Println(res.Status)
    }
}

還是 400 錯誤 ....

$TELEGRAM_BOT_TOKEN <-- ??

echochio iT邦高手 1 級 ‧ 2020-04-25 23:54:00 檢舉

樓上的大大,請您去看原文的 curl 範例
我不會吧我的 bot token 貼出來吧...
chat id 也不可能是 123456789

echochio iT邦高手 1 級 ‧ 2020-04-26 09:56:07 檢舉

@froce
錄了封包發現 ....header 有 gzip
已拿掉 gzip 還是一樣 ....
map 與 struct 兩個封包 相同
但是發現 curl 送出的 header 是

Content-Type: application/json
Content-Length: 81

{"chat_id": "-390234700", "text": "This is a test", "disable_notification": true}

map 與 struct 送出的 header 是

Content-Length: 86
Content-Type: application-json

{"chat_id":"-390234700","disable_notification":true,"text":"This is a test"}

有甚麼地方有可能錯 ?

froce iT邦大師 1 級 ‧ 2020-04-26 10:06:36 檢舉

chat_id改成int64試試看。

那個 token , 我是好意提醒.
如果你有變化隱藏,那很好啊.
我回答過很多問題,有些就是在一些小地方.你的code 也沒有
顯示出你有替換,所以我就好意提醒.

你回了,"請您去看原文的 curl 範例
我不會吧我的 bot token 貼出來吧...
chat id 也不可能是 123456789."

是啦,不可能,好厲害的,怎麼可能會錯,bala bala.

我自己幾年前就寫了 Go, Rust 的 telegram bot,
我不需要去看那些範例啦.
我也只能祝你排查順利囉.

echochio iT邦高手 1 級 ‧ 2020-04-27 21:15:31 檢舉

剛剛試過 chat_id改成int64 還是不行
錄到封包是

####
T 127.0.0.1:37604 -> 127.0.0.1:5000 [AP] #4
  POST /bot610418721:AAGBzrJ5dYipW0DB9799999YFB6RDwM8x7s/sendMessage HTTP/1.1..Host: 127.0.0.1:5000..User-Agent: Go-http-client/1.1..Content-Length: 75..
  Content-Type: application-json....{"chat_id":-390234700,"text":"This is a test","disable_notification":true}.
##
T 127.0.0.1:5000 -> 127.0.0.1:37604 [AP] #6
  HTTP/1.1 400 Bad Request..Server: nginx/1.14.1..Date: Mon, 27 Apr 2020 13:11:06 GMT..Content-Type: application/json..Content-Length: 80..Connection: ke
  ep-alive..Strict-Transport-Security: max-age=390234700; includeSubDomains; preload..Access-Control-Allow-Origin: *..Access-Control-Expose-Headers: Conte
  nt-Length,Content-Type,Date,Server,Connection....{"ok":false,"error_code":400,"description":"Bad Request: message text is empty"}
####^Cexit

有空再試好了 ...
用其他語言寫沒啥問題 .....
go + net/http + json 不行有空再試
問題應該在 json , 如不用 json 是可以的

package main
import (
    "net/http"
)

func main() {
http.Get("https://api.telegram.org/bot610418721:AAGBzrJ5dYipW0DB9799999YFB6RDwM8x7s/sendMessage?chat_id=-390234700&text=test")
}

echochio iT邦高手 1 級 ‧ 2020-04-28 21:04:53 檢舉

搞定了
那網路上抄的 .... Content-Type: application-json
不能 work
改成 ....
Content-Type: application/json
可以 work
加 gzip , map 或 struct 都可 work ....
chat_id 是 string 沒錯

我要發表回答

立即登入回答