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

问题描述

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

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

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)
        }