使用Golang拉取阿里云昨天费用发送到钉钉

使用Golang拉取阿里云昨天费用发送到钉钉

初始化go项目

  • 初始化项目,如果是简单的脚本,怎么方便怎么来
  • 直接进入项目目录初始化也行
cd /apps/app/QueryAccount/
go mod init QueryAccount
  • 但是如果是项目,或者复杂一点点就,建议使用
go mod init gitee.com/xxx/skills/
  • Golang代理推荐
# 下包报错换一下试试吧,不行再换一个
go env -w GOPROXY=https://goproxy.cn,direct

阿里云文档

  • 使用的阿里云的QueryBillOverview
  • 具体使用到什么参数我都写到脚本的结构体中了,有一些我没用我就注释了
https://help.aliyun.com/document_detail/472990.html?spm=a2c4g.472986.0.0.6441a859jhnwCv
https://api.aliyun.com/api/BssOpenApi/2017-12-14/QueryAccountTransactions?spm=a2c4g.472990.0.0.29e65bbfBsxOkp&RegionId=

脚本

  • 具体不解释了,里面有注释,BillItem结构体我只取了我想要的,如果你觉得不够,可以到上面阿里云文档中拿
  • 具体情况可以将Print大法注释去掉,排错
  • 我这里直接借用了SkyWalking机器人,也很简单,具体创建和使用钉钉机器人流程可以看我之前的文章《使用Golang编写Webhook向钉钉告警》
package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"os"
	"strconv"
	"time"

	bssopenapi20171214 "github.com/alibabacloud-go/bssopenapi-20171214/v5/client"
	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
)

// 定义QueryBillOverview账单结构体来映射响应中的Item
type BillItem struct {
	BillingCycle    string `json:"BillingCycle"`    // 账单日期
	Amount          string `json:"Amount"`          // 消费金额
	TransactionTime string `json:"TransactionTime"` // 交易时间
	Remarks         string `json:"Remarks"`         // 交易产品
	Balance         string `json:"Balance"`         // 当前剩余余额

}

// 钉钉消息结构
type DingTalkMessage struct {
	Msgtype  string `json:"msgtype"`
	Markdown struct {
		Title string `json:"title"`
		Text  string `json:"text"`
	} `json:"markdown"`
}

func CreateClient() (_result *bssopenapi20171214.Client, _err error) {
	config := &openapi.Config{
		AccessKeyId:     tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
		AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
	}
	config.Endpoint = tea.String("business.aliyuncs.com")
	client, err := bssopenapi20171214.NewClient(config)
	return client, err
}

func foo(startTime, endTime string) (map[string]string, error) {
	client, err := CreateClient()
	if err != nil {
		return nil, err
	}

	// 阿里云skd
	queryAccountTransactionsRequest := &bssopenapi20171214.QueryAccountTransactionsRequest{
		PageNum:         tea.Int32(1),
		PageSize:        tea.Int32(300),
		CreateTimeStart: tea.String(startTime),
		CreateTimeEnd:   tea.String(endTime),
	}

	// 获取数据
	runtime := &util.RuntimeOptions{}
	response, err := client.QueryAccountTransactionsWithOptions(queryAccountTransactionsRequest, runtime)
	if err != nil {
		var sdkErr *tea.SDKError
		if errors.As(err, &sdkErr) {
			fmt.Println(sdkErr.Message)
		} else {
			fmt.Println(err.Error())
		}

		return nil, err
	}

	// fmt.Println("Test1.Print大法.赋值前查看数据结构:", response.Body.Data.AccountTransactionsList.AccountTransactionsList)

	// 使用map来存储交易产品和对应的总金额
	totalAmounts := make(map[string]string)
	for _, item := range response.Body.Data.AccountTransactionsList.AccountTransactionsList {
		remarks := *item.Remarks                       // 交易产品
		amountStr := *item.Amount                      // 消费金额
		amount, _ := strconv.ParseFloat(amountStr, 64) // 假设金额是浮点数

		// 如果map中已存在该交易产品,则累加金额
		if currentAmount, ok := totalAmounts[remarks]; ok {
			currentAmountFloat, _ := strconv.ParseFloat(currentAmount, 64)
			totalAmounts[remarks] = fmt.Sprintf("%.2f", currentAmountFloat+amount) // 保留两位小数
		} else {
			totalAmounts[remarks] = fmt.Sprintf("%.2f", amount) // 初始化为当前金额
		}
	}

	return totalAmounts, nil
}

// 发送钉钉消息
func sendToDingTalk(webhookURL string, message DingTalkMessage) error {
	jsonData, err := json.Marshal(message)
	if err != nil {
		return err
	}

	req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(jsonData))
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	// 可选:检查响应状态码等
	return nil
}

func main() {
	// 获取当前时间
	now := time.Now().UTC() // 使用UTC时间以确保时区一致性
	// fmt.Println("当前时间:", now.Format(time.RFC3339))

	// 计算昨天的日期
	yesterday := now.AddDate(0, 0, -1)
	startTime := time.Date(yesterday.Year(), yesterday.Month(), yesterday.Day(), 0, 0, 0, 0, time.UTC)  // 构造昨天的开始时间(凌晨00:00:00)
	endTime := time.Date(yesterday.Year(), yesterday.Month(), yesterday.Day(), 23, 59, 59, 0, time.UTC) // 构造昨天的结束时间(23:59:59)

	// 将 time.Time 转换为字符串
	startTimeStr := startTime.Format(time.RFC3339)
	endTimeStr := endTime.Format(time.RFC3339)
	sheetNameStr := yesterday.Format("2006-01-02")

	totalAmounts, err := foo(startTimeStr, endTimeStr)
	if err != nil {
		panic(err)
	}

	// 初始化钉钉消息的文本部分
	var buffer bytes.Buffer
	buffer.WriteString("<font color='#FF7D00'>SkyWalking 告警通知汇总</font>\n\n")

	// 遍历totalAmounts,将每个交易产品的信息添加到钉钉消息的文本中
	var totalConsumption float64 = 0
	buffer.WriteString("<hr>\n")
	buffer.WriteString(fmt.Sprintf("<font color=' #008000 '> 汇报%s阿里云消费情况 </font>", sheetNameStr))
	for remarks, amount := range totalAmounts {
		buffer.WriteString("<hr>\n")
		buffer.WriteString(fmt.Sprintf("<font color='#FF7D00'> 交易产品 </font>: %s <br> \n <font color='#FF7D00'>消费总金额</font>:%s <br>\n", remarks, amount))

		amountFloat, _ := strconv.ParseFloat(amount, 64)
		totalConsumption += amountFloat
	}

	totalConsumptionStr := fmt.Sprintf("%.2f", totalConsumption)
	buffer.WriteString("<hr>\n")
	buffer.WriteString(fmt.Sprintf("<font color=' #008000 '> %s当天所有交易产品总消费为:%s </font> \n", sheetNameStr, totalConsumptionStr))

	// 构造钉钉消息
	dingTalkMessage := DingTalkMessage{
		Msgtype: "markdown",
		Markdown: struct {
			Title string `json:"title"`
			Text  string `json:"text"`
		}{
			Title: "SkyWalking 告警通知汇总",
			Text:  buffer.String(),
		},
	}

	// 发送钉钉消息
	if err := sendToDingTalk("https://oaxxxxxx----你的钉钉webhook----xxxxxxxx", dingTalkMessage); err != nil {
		return
	}
	// for remarks, amount := range totalAmounts {
	// 	fmt.Printf("交易产品: %s\n 消费总金额: %s\n", remarks, amount)
	// }

}
  • 结果大概是这样
    请添加图片描述

  • 这里我将所有后付费产品(按量计费)相同产品价格合并了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值