golang实现YNAB API接口调用的插件库ynab的使用

Golang实现YNAB API接口调用的插件库ynab的使用

YNAB API Go库

这是一个非官方的Go客户端,用于YNAB API。它覆盖了YNAB API提供的100%资源。

Go Report Card GoDoc Reference

安装

go get github.com/brunomvsouza/ynab.go

使用方法

要使用这个客户端,你必须从YNAB网页应用的"我的账户"页面获取访问令牌。

下面是一个完整的示例代码,展示如何使用ynab.go库获取预算列表:

package main

import (
	"fmt"

	"github.com/brunomvsouza/ynab.go"
)

const accessToken = "bf0cbb14b4330-not-real-3de12e66a389eaafe2" // 替换为你的真实访问令牌

func main() {
	// 创建YNAB客户端
	c := ynab.NewClient(accessToken)
	
	// 获取所有预算
	budgets, err := c.Budget().GetBudgets()
	if err != nil {
		panic(err)
	}

	// 打印每个预算的名称
	for _, budget := range budgets {
		fmt.Println(budget.Name)
		// 这里可以添加更多处理逻辑...
	}
}

更复杂的示例

下面是一个更完整的示例,展示如何获取特定预算的账户和交易信息:

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/brunomvsouza/ynab.go"
)

const (
	accessToken = "your-access-token-here" // 替换为你的真实访问令牌
	budgetID    = "your-budget-id"        // 替换为你的预算ID
)

func main() {
	// 初始化客户端
	client := ynab.NewClient(accessToken)

	// 1. 获取预算详情
	budget, err := client.Budget().GetBudget(budgetID, nil)
	if err != nil {
		log.Fatalf("获取预算失败: %v", err)
	}
	fmt.Printf("预算名称: %s\n", budget.Name)

	// 2. 获取账户列表
	accounts, err := client.Account().GetAccounts(budgetID)
	if err != nil {
		log.Fatalf("获取账户失败: %v", err)
	}

	for _, account := range accounts {
		fmt.Printf("\n账户: %s (余额: %.2f)\n", account.Name, float64(account.Balance)/1000)

		// 3. 获取最近交易
		sinceDate := time.Now().AddDate(0, -1, 0).Format("2006-01-02") // 过去一个月的交易
		transactions, err := client.Transaction().GetTransactions(budgetID, account.ID, sinceDate)
		if err != nil {
			log.Printf("获取交易失败: %v", err)
			continue
		}

		for _, t := range transactions {
			fmt.Printf("  - %s: %s (%.2f)\n", t.Date, t.Memo, float64(t.Amount)/1000)
		}
	}
}

开发要求

  • 确保安装了Go 1.19或更高版本
  • 运行测试使用命令:go test -race ./...

许可证

BSD-2-Clause


更多关于golang实现YNAB API接口调用的插件库ynab的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现YNAB API接口调用的插件库ynab的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用Golang实现YNAB API接口调用的插件库

YNAB (You Need A Budget) 是一个流行的个人财务管理工具,它提供了丰富的API接口。下面我将介绍如何使用Golang实现YNAB API的调用,并提供一个完整的插件库示例。

1. 准备工作

首先,你需要获取YNAB API的访问令牌:

  1. 登录YNAB账户
  2. 进入"开发者设置"
  3. 创建新的访问令牌

2. 基础库实现

以下是实现YNAB API调用的基础库代码:

package ynab

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"time"
)

const (
	baseURL = "https://api.ynab.com/v1"
)

// Client 是YNAB API客户端
type Client struct {
	apiKey     string
	httpClient *http.Client
}

// NewClient 创建新的YNAB客户端
func NewClient(apiKey string) *Client {
	return &Client{
		apiKey: apiKey,
		httpClient: &http.Client{
			Timeout: time.Second * 30,
		},
	}
}

// doRequest 执行API请求
func (c *Client) doRequest(method, endpoint string, body interface{}) ([]byte, error) {
	var reqBody io.Reader
	if body != nil {
		jsonBody, err := json.Marshal(body)
		if err != nil {
			return nil, err
		}
		reqBody = bytes.NewBuffer(jsonBody)
	}

	req, err := http.NewRequest(method, baseURL+endpoint, reqBody)
	if err != nil {
		return nil, err
	}

	req.Header.Set("Authorization", "Bearer "+c.apiKey)
	req.Header.Set("Content-Type", "application/json")

	resp, err := c.httpClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode >= 400 {
		return nil, errors.New(string(respBody))
	}

	return respBody, nil
}

3. 预算相关功能实现

// Budget 表示YNAB预算
type Budget struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

// GetBudgets 获取所有预算
func (c *Client) GetBudgets() ([]Budget, error) {
	resp, err := c.doRequest("GET", "/budgets", nil)
	if err != nil {
		return nil, err
	}

	var response struct {
		Data struct {
			Budgets []Budget `json:"budgets"`
		} `json:"data"`
	}

	if err := json.Unmarshal(resp, &response); err != nil {
		return nil, err
	}

	return response.Data.Budgets, nil
}

// GetBudgetById 通过ID获取预算
func (c *Client) GetBudgetById(budgetId string) (*Budget, error) {
	resp, err := c.doRequest("GET", fmt.Sprintf("/budgets/%s", budgetId), nil)
	if err != nil {
		return nil, err
	}

	var response struct {
		Data struct {
			Budget Budget `json:"budget"`
		} `json:"data"`
	}

	if err := json.Unmarshal(resp, &response); err != nil {
		return nil, err
	}

	return &response.Data.Budget, nil
}

4. 交易相关功能实现

// Transaction 表示YNAB交易
type Transaction struct {
	ID          string  `json:"id"`
	Date        string  `json:"date"`
	Amount      float64 `json:"amount"`
	PayeeName   string  `json:"payee_name"`
	Category    string  `json:"category_name"`
	Description string  `json:"memo"`
}

// GetTransactions 获取预算的交易
func (c *Client) GetTransactions(budgetId string) ([]Transaction, error) {
	resp, err := c.doRequest("GET", fmt.Sprintf("/budgets/%s/transactions", budgetId), nil)
	if err != nil {
		return nil, err
	}

	var response struct {
		Data struct {
			Transactions []Transaction `json:"transactions"`
		} `json:"data"`
	}

	if err := json.Unmarshal(resp, &response); err != nil {
		return nil, err
	}

	return response.Data.Transactions, nil
}

// CreateTransaction 创建新交易
func (c *Client) CreateTransaction(budgetId string, transaction Transaction) (*Transaction, error) {
	reqBody := struct {
		Transaction Transaction `json:"transaction"`
	}{
		Transaction: transaction,
	}

	resp, err := c.doRequest("POST", fmt.Sprintf("/budgets/%s/transactions", budgetId), reqBody)
	if err != nil {
		return nil, err
	}

	var response struct {
		Data struct {
			Transaction Transaction `json:"transaction"`
		} `json:"data"`
	}

	if err := json.Unmarshal(resp, &response); err != nil {
		return nil, err
	}

	return &response.Data.Transaction, nil
}

5. 使用示例

package main

import (
	"fmt"
	"log"
	"ynab" // 假设上面的代码在ynab包中
)

func main() {
	// 替换为你的YNAB API密钥
	apiKey := "your_ynab_api_key_here"
	client := ynab.NewClient(apiKey)

	// 获取所有预算
	budgets, err := client.GetBudgets()
	if err != nil {
		log.Fatalf("获取预算失败: %v", err)
	}

	fmt.Println("可用预算:")
	for _, budget := range budgets {
		fmt.Printf("- %s (ID: %s)\n", budget.Name, budget.ID)
	}

	// 假设我们使用第一个预算
	if len(budgets) == 0 {
		log.Fatal("没有找到预算")
	}
	budgetId := budgets[0].ID

	// 获取交易
	transactions, err := client.GetTransactions(budgetId)
	if err != nil {
		log.Fatalf("获取交易失败: %v", err)
	}

	fmt.Println("\n最近的交易:")
	for i, t := range transactions {
		if i >= 5 { // 只显示前5笔交易
			break
		}
		fmt.Printf("- %s: %.2f (%s)\n", t.Date, t.Amount, t.PayeeName)
	}

	// 创建新交易示例
	newTransaction := ynab.Transaction{
		Date:        "2023-11-01",
		Amount:      50.00,
		PayeeName:   "超市",
		Category:    "食品杂货",
		Description: "每周购物",
	}

	createdTx, err := client.CreateTransaction(budgetId, newTransaction)
	if err != nil {
		log.Fatalf("创建交易失败: %v", err)
	}

	fmt.Printf("\n创建的交易ID: %s\n", createdTx.ID)
}

6. 高级功能扩展

你可以进一步扩展这个库,添加以下功能:

  1. 账户管理:获取、创建和更新账户
  2. 类别操作:管理预算类别和类别组
  3. 批量操作:批量导入交易
  4. 错误处理:更详细的错误分类和处理
  5. 分页支持:处理大量数据的API响应
  6. 缓存:减少重复API调用

7. 注意事项

  1. API有速率限制(200请求/小时),需要适当处理
  2. 敏感数据(如API密钥)应该安全存储
  3. 考虑添加重试机制处理临时网络问题
  4. 可以使用context包支持请求取消

这个实现提供了YNAB API的基本功能,你可以根据需要进一步扩展和完善它。

回到顶部