Unmarshaling dynamic JSON
I would not implement method UnmarshalJSON as it is not really necessary. Instead, I would create Audio and Photo types and put them as fields into Attachment type. It would be easier to reference data as field than get it as a value from map.

package main

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

type Response struct {
    Id          int `json:"id"`
    FromId      int `json:"from_id"`
    Attachments []Attachment
}

type Audio struct {
    Artist string `json:"artist"`
    Title  string `json:"title"`
}

type Photo struct {
    Id  int    `json:"id"`
    Url string `json:"url"`
}

type Attachment struct {
    Type  string
    Audio `json:"audio"`
    Photo `json:"photo"`
}

func main() {
    encoded := `
    {
        "id": 123,
        "from_id": 234,
        "attachments": [
            {
                "type": "audio",
                "audio": {
                    "artist": "Van Halen",
                    "title": "Eruption"
                }
            },
            {
                "type": "photo",
                "photo": {
                    "id": 123,
                    "url": "http://someurl.com"
                }
            }
        ]
    }
    `

    response := &amp;Response{}
    reader := strings.NewReader(encoded)
    err := json.NewDecoder(reader).Decode(&amp;response)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(response)
}