根据数据源发送附件中的数据

Send data in attachment as per data source

我正在尝试创建发送 Notification 结构中可用数据的 Slack 通知,即 Notification 结构将是一个数据源。我很难将通知结构正确插入附件。 请在下面查看我的代码。有人知道我能做什么吗?非常感谢您的帮助。

我的预期结果(即松弛通知)将是这样的:

UserID: 99
Type: Slack or Email
Level: Warning
Received: time.Time (now)
Originator: Originator Name
Immediate:  false
Data:  interface{}
Recipients: {email@gmail.com; Recipient Name}
Customer: {1, Customer Name}
package main

import (
    "fmt"

    "time"

    "github.com/parnurzeal/gorequest"
)

//NotificationType is enum of available notification types
type NotificationType string

const (
    //Email should be sent via email protocols
    Email NotificationType = "email"
)

//NotificationLevel is enum of notification levels
type NotificationLevel string

//Notification levels represent the importance of the notification
const (
    Error   NotificationLevel = "error"
    Warning NotificationLevel = "warning"
    Info    NotificationLevel = "info"
)

//Recipient represents the recipient of the notification
type Recipient struct {
    Email string
    Name  string
}

//Customer represents the customer the notification is about
type Customer struct {
    ID   int
    Name string
}

//Notification is struct containing all information about notification
//This will be used as Datasource in the Attachment
type Notification struct {
    UserID     int
    Type       NotificationType
    Level      NotificationLevel
    Received   time.Time
    Originator string
    Immediate  bool
    Data       interface{}

    // following field are populated by notification service itself
    Recipients []*Recipient
    Customer   *Customer
}

//Field defines fields to be used in the notification
type Field struct {
    Title string
    Value []*Notification
}

// Attachment holds data used in payload
type Attachment struct {
    Text   *string  //`json:"text"`
    Fields []*Field //`json:"fields"`
}

//Payload defines the notification structure
type Payload struct {
    Text        string       `json:"text,omitempty"`
    Attachments []Attachment `json:"attachments,omitempty"`
}

//AddField adds one or multiple fields into the notification
func (attachment *Attachment) AddField(field Field) *Attachment {
    attachment.Fields = append(attachment.Fields, &field)
    return attachment
}

func redirectPolicyFunc(req gorequest.Request, via []gorequest.Request) error {
    return fmt.Errorf("Incorrect token (redirection)")
}

//Send sends new POST request to the webhookURL
func Send(webhookURL string, payload Payload) []error {
    request := gorequest.New()
    resp, _, err := request.
        Post(webhookURL).
        RedirectPolicy(redirectPolicyFunc).
        Send(payload).
        End()

    if err != nil {
        return err
    }
    if resp.StatusCode >= 400 {
        return []error{fmt.Errorf("Error sending msg. Status: %v", resp.Status)}
    }

    return nil
}

func main() {
    webhookURL := "WEBHOOK_URL"

    attachment1 := Attachment{}
    attachment1.AddField(Field{Title: "UserID", Value: "AS PER NOTIFICATION STRUCT"}).AddField(Field{Title: "Type", Value: "AS PER NOTIFICATION STRUCT"}).AddField(Field{Title: "Level", Value: "AS PER NOTIFICATION STRUCT"})
    payload := Payload{
        Text:        "Hello Everyone, this is a new Slack notification",
        Attachments: []Attachment{attachment1},
    }
    err := Send(webhookURL, payload)
    if len(err) > 0 {
        fmt.Printf("error: %s\n", err)
    }
}

下面的代码就是这个请求的解决方案。

package main

import (
    "bytes"
    "encoding/json"
    "errors"
    "fmt"
    "net/http"
    "strings"
    "time"
    "log"
    "strconv"
    )

//DataFeed contains data for the string concatenation
type DataFeed struct {
    CustomerID    int
    CustomerName  string
    CustomerEmail string
    CustomerPhone string
    Received      time.Time
}
//ConcatenateDate takes data from DataFeed and concatenates them into a msg ('\n' separated)
func ConcatenateData(d DataFeed) (msg string) {
    values := []string{}
    values = append(values, "New notification incoming, see more details below:")
    values = append(values, "ID: " + strconv.Itoa(d.CustomerID))
    values = append(values, "Name: " + d.CustomerName)
    values = append(values, "Email: " + d.CustomerEmail)
    values = append(values, "Phone Number: " + d.CustomerPhone)
    values = append(values, "Received: " + (d.Received).String())

    msg = strings.Join(values, "\n")
    //fmt.Println(values)
    //fmt.Println(msg)

    return msg
}

// SlackRequestBody comment here
type SlackRequestBody struct {
    Text string `json:"text"`
}

func SendSlackNotification(webhookURL string, msg string) error {
    slackBody, _ := json.Marshal(SlackRequestBody{Text: msg})
    req, err := http.NewRequest(http.MethodPost, webhookURL, bytes.NewBuffer(slackBody))
    if err != nil {
        return err
    }

    req.Header.Add("Content-Type", "application/json")
    client := &http.Client{Timeout: 10 * time.Second}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }

    buf := new(bytes.Buffer)
    buf.ReadFrom(resp.Body)
    if buf.String() != "ok" {
        return errors.New("Non-ok response returned from Slack")
    }

    return nil
}

func main() {
    webhookURL := "https://hooks.slack.com/services/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"

    e := DataFeed{
        CustomerID:    767,
        CustomerName:  "Tom",
        CustomerEmail: "tom.nemeth85@gmail.com",
        CustomerPhone: "07479551111",
        Received:      time.Now(),
    }

    fmt.Println(e)
    fmt.Printf("\n")
    fmt.Println(ConcatenateData(e))
    
        err := SendSlackNotification(webhookURL, ConcatenateData(e)) //--> Set "e" as argument here
        if err != nil {
            log.Fatal(err)
        }