多维表格

package feishu

import (
	"encoding/json"
	"fmt"
	"xxxx/pkg/httpc"
	"net/http"
)

type Client struct {
	appId  string
	secret string
}

func NewClient(appId, secret string) *Client {
	return &Client{
		appId:  appId,
		secret: secret,
	}
}


func (c *Client) getTenantAccessToken() (string, error) {
	req := fmt.Sprintf("{\"app_id\": \"%s\",\"app_secret\": \"%s\"}", c.appId, c.secret)
	body, err := httpc.Request(http.MethodPost, "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
		map[string]string{"Content-Type": "application/json; charset=utf-8"}, []byte(req))

	if err != nil {
		return "", err
	}
	var resp TokenResp
	err = jsonx.UnmarshalFromString(body, &resp)
	if err != nil {
		return "", err
	}
	if resp.Code != 0 {
		return "", errors.New(resp.Msg)
	}
	return resp.TenantAccessToken, nil
}


// BatchCreateRecordsRequest represents the request body for batch creating records
type BatchCreateRecordsRequest struct {
	Records []Record `json:"records"`
}

// Record represents a single record in the batch create request
type Record struct {
	Fields map[string]interface{} `json:"fields"`
}

// BatchCreateRecordsResponse represents the response from batch creating records
type BatchCreateRecordsResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data struct {
		Records []Record `json:"records"`
	} `json:"data"`
}

// BatchCreateRecords creates multiple records in a Bitable table
// appToken: the unique identifier of the Bitable app
// tableId: the unique identifier of the table
// records: slice of records to create, each record is a map of field name to value
func (c *Client) BatchCreateRecords(appToken, tableId string, records []map[string]interface{}) (*BatchCreateRecordsResponse, error) {
	token, err := c.getTenantAccessToken()
	if err != nil {
		return nil, fmt.Errorf("failed to get tenant access token: %v", err)
	}

	// Prepare request body
	reqRecords := make([]Record, len(records))
	for i, r := range records {
		reqRecords[i] = Record{Fields: r}
	}

	reqBody := BatchCreateRecordsRequest{
		Records: reqRecords,
	}

	reqBytes, err := json.Marshal(reqBody)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal request body: %v", err)
	}

	// Make API request
	url := fmt.Sprintf("https://open.feishu.cn/open-apis/bitable/v1/apps/%s/tables/%s/records/batch_create", appToken, tableId)
	headers := map[string]string{
		"Authorization": "Bearer " + token,
		"Content-Type":  "application/json; charset=utf-8",
	}

	respBody, err := httpc.Request(http.MethodPost, url, headers, reqBytes)
	if err != nil {
		return nil, fmt.Errorf("failed to make request: %v", err)
	}

	var resp BatchCreateRecordsResponse
	if err := json.Unmarshal([]byte(respBody), &resp); err != nil {
		return nil, fmt.Errorf("failed to unmarshal response: %v", err)
	}

	if resp.Code != 0 {
		return nil, fmt.Errorf("API error: %s", resp.Msg)
	}

	return &resp, nil
}
package httpc

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"

	"github.com/zeromicro/go-zero/core/logx"
)

func Request(method, url string, headers map[string]string, data []byte) (string, error) {
	req, err := http.NewRequest(method, url, bytes.NewReader(data))
	if err != nil {
		return "", err
	}
	if len(headers) > 0 {
		for k, v := range headers {
			req.Header.Set(k, v)
		}
	}
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Failed to send request:", err)
		return "", err
	}
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			logx.Errorf("request err:%v", err)
		}
	}(resp.Body)
	body, err := ioutil.ReadAll(resp.Body)
	return string(body), nil
}

最后更新于