@linuxoid_inrus

Как правильно распарсить JSON телеграма?

Раньше нормально парсил JSON таким способом, но сейчас что-то пошло не так

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

func main(){
	token := "d"
	url := fmt.Sprintf("https://api.telegram.org/bot%s/getUpdates", token)
	res, err := http.Get(url)
	if err != nil {
		panic(err)
	}

		bodyBytes, err := ioutil.ReadAll(res.Body)

	var data map[string]interface{}
		json.Unmarshal(bodyBytes, &data)

	fmt.Println(data["result"].(map[string]interface{})["chat"])


}


Ошибка:
panic: interface conversion: interface {} is []interface {}, not map[string]interface {}

goroutine 1 [running]:
main.main()
  • Вопрос задан
  • 192 просмотра
Решения вопроса 1
bitniks
@bitniks
Go/PHP/Symfony developer
Первый вариант, это распарсить вручную. Выглядит так
package main

import (
	"fmt"
	"encoding/json"
	"log"
)

func main() {
	bodyBytes := []byte(`{"ok":true,"result":[{"update_id":715296593,
"message":{"message_id":5,"from":{"id":362268798,"is_bot":false,"first_name":"\u041a\u043e\u0442\ud83d\udd25","username":".....","language_code":"ru"},"chat":{"id":362268798,"first_name":"\u041a\u043e\u0442\ud83d\udd25","username":"....","type":"private"},"date":1604728384,"text":"/start","entities":[{"offset":0,"length":6,"type":"bot_command"}]}}]}`)

	var data map[string]interface{}
	err := json.Unmarshal(bodyBytes, &data)
	if err != nil {
		log.Fatal(err)
	}
	
	result, ok := data["result"].([]interface{})
	if !ok {
		log.Fatal("Failed to type-cast result")
	}
	firstResult, ok := result[0].(map[string]interface{})
	if !ok {
		log.Fatal("Failed to type-cast first result")
	}
	message, ok := firstResult["message"].(map[string]interface{})
	if !ok {
		log.Fatal("Failed to type-cast message")
	}
	chat, ok := message["chat"].(map[string]interface{})
	if !ok {
		log.Fatal("Failed to type-cast chat")
	}

	fmt.Println("id =", chat["id"])
	fmt.Println("type = ", chat["type"])
	fmt.Println("username = ", chat["username"])
	fmt.Println("first_name = ", chat["first_name"])
}

https://play.golang.org/p/ZDis4Y9be31

Второй вариант более корректный и удобный. Описать структурой ответ и распарсить json в эту структуру
package main

import (
	"fmt"
	"encoding/json"
	"log"
)

type Response struct {
	Results []Result `json:"result"`
}

type Result struct {
	Message Message `json:"message"`
}

type Message struct {
	Chat Chat `json:"chat"`
}

type Chat struct {
	 ID int `json:"id"`
	 FirstName string `json:"first_name"`
	 UserName string `json:"username"`
	 Type string `json:"type"`
}

func main() {
	bodyBytes := []byte(`{"ok":true,"result":[{"update_id":715296593,
"message":{"message_id":5,"from":{"id":362268798,"is_bot":false,"first_name":"\u041a\u043e\u0442\ud83d\udd25","username":".....","language_code":"ru"},"chat":{"id":362268798,"first_name":"\u041a\u043e\u0442\ud83d\udd25","username":"....","type":"private"},"date":1604728384,"text":"/start","entities":[{"offset":0,"length":6,"type":"bot_command"}]}}]}`)

	var response Response
	err := json.Unmarshal(bodyBytes, &response)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("id =", response.Results[0].Message.Chat.ID)
	fmt.Println("type = ", response.Results[0].Message.Chat.Type)
	fmt.Println("username = ", response.Results[0].Message.Chat.UserName)
	fmt.Println("first_name = ", response.Results[0].Message.Chat.FirstName)
}

https://play.golang.org/p/qrROYHjn-Cc
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Вам приходит слайс []interface{}, а вы его пытаетесь приводить к map[string]interface{}

На самом деле, у вас подход изначально не очень, лучше всего парсить JSON в структуру, а не в map[string]interface{}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы