func (m AlertMapper) Decode(source io.ReadCloser) ([]models.AlertGroup, error) {
	groups := []models.AlertGroup{}
	receivers := map[string]alertsGroupReceiver{}
	resp := alertsGroupsAPISchema{}
	defer source.Close()
	err := json.NewDecoder(source).Decode(&resp)
	if err != nil {
		return groups, err
	}
	if resp.Status != "success" {
		return groups, errors.New(resp.Error)
	}
	for _, d := range resp.Data {
		for _, b := range d.Blocks {
			rcv, found := receivers[b.RouteOps.Receiver]
			if !found {
				rcv = alertsGroupReceiver{
					Name: b.RouteOps.Receiver,
				}
				receivers[b.RouteOps.Receiver] = rcv
			}
			alertList := models.AlertList{}
			for _, a := range b.Alerts {
				status := models.AlertStateActive
				silencedBy := []string{}
				if a.Silenced > 0 {
					silencedBy = append(silencedBy, strconv.Itoa(a.Silenced))
					status = models.AlertStateSuppressed
				}
				inhibitedBy := []string{}
				if a.Inhibited {
					inhibitedBy = append(inhibitedBy, "0")
					status = models.AlertStateSuppressed
				}
				a := models.Alert{
					Receiver:     rcv.Name,
					Annotations:  models.AnnotationsFromMap(a.Annotations),
					Labels:       a.Labels,
					StartsAt:     a.StartsAt,
					EndsAt:       a.EndsAt,
					GeneratorURL: a.GeneratorURL,
					State:        status,
					InhibitedBy:  inhibitedBy,
					SilencedBy:   silencedBy,
				}
				sort.Strings(a.InhibitedBy)
				sort.Strings(a.SilencedBy)
				a.UpdateFingerprints()
				alertList = append(alertList, a)
			}
			ug := models.AlertGroup{
				Receiver: rcv.Name,
				Labels:   d.Labels,
				Alerts:   alertList,
			}
			rcv.Groups = append(rcv.Groups, ug)
			receivers[rcv.Name] = rcv
		}
	}
	for _, rcv := range receivers {
		for _, ag := range rcv.Groups {
			groups = append(groups, ag)
		}
	}
	return groups, nil
}
Decode Alertmanager API response body and return unsee model instances
package v04
import (
	"encoding/json"
	"errors"
	"io"
	"sort"
	"strconv"
	"time"
	"github.com/blang/semver"
	"github.com/cloudflare/unsee/internal/mapper"
	"github.com/cloudflare/unsee/internal/models"
	"github.com/cloudflare/unsee/internal/uri"
)
type alert struct {
	Annotations  map[string]string `json:"annotations"`
	Labels       map[string]string `json:"labels"`
	StartsAt     time.Time         `json:"startsAt"`
	EndsAt       time.Time         `json:"endsAt"`
	GeneratorURL string            `json:"generatorURL"`
	Inhibited    bool              `json:"inhibited"`
	Silenced     int               `json:"silenced"`
}
type alertsGroups struct {
	Labels map[string]string `json:"labels"`
	Blocks []struct {
		Alerts   []alert `json:"alerts"`
		RouteOps struct {
			Receiver string `json:"receiver"`
		} `json:"routeOpts"`
	} `json:"blocks"`
}
type alertsGroupsAPISchema struct {
	Status string         `json:"status"`
	Data   []alertsGroups `json:"data"`
	Error  string         `json:"error"`
}
type alertsGroupReceiver struct {
	Name   string
	Groups []models.AlertGroup
}
type AlertMapper struct {
	mapper.AlertMapper
}
func (m AlertMapper) AbsoluteURL(baseURI string) (string, error) {
	return uri.JoinURL(baseURI, "api/v1/alerts/groups")
}
func (m AlertMapper) QueryArgs() string {
	return ""
}
func (m AlertMapper) IsSupported(version string) bool {
	versionRange := semver.MustParseRange(">=0.4.0 <0.5.0")
	return versionRange(semver.MustParse(version))
}