package x3_client import ( "bytes" "encoding/json" "fmt" "io" "net/http" ) func makeGetRequest[R any](httpClient *http.Client, url string) (R, error) { var res R resp, err := httpClient.Get(url) if err != nil { return res, err } respBody, err := io.ReadAll(resp.Body) if err != nil { return res, err } err = json.Unmarshal(respBody, &res) if err != nil { return res, err } return res, nil } func makePostRequest[Q, R any](httpClient *http.Client, url string, req Q) (R, error) { var res R body, err := json.Marshal(req) if err != nil { return res, err } resp, err := httpClient.Post(url, "application/json", bytes.NewReader(body)) if err != nil { return res, err } respBody, err := io.ReadAll(resp.Body) if err != nil { return res, err } err = json.Unmarshal(respBody, &res) if err != nil { return res, err } return res, nil } const loginURL = "/login" func (c *X3Client) Login(request LoginRequest) (GeneralResponse[LoginResponse], error) { return makePostRequest[interface{}, GeneralResponse[LoginResponse]](c.httpClient, c.Host+loginURL+fmt.Sprintf("?username=%s&password=%s", request.Username, request.Password), nil) } const inboundsURL = "/panel/api/inbounds/list" func (c *X3Client) GetInbounds() (GeneralResponse[[]Inbound], error) { return makeGetRequest[GeneralResponse[[]Inbound]](c.httpClient, c.Host+inboundsURL) } const inboundURL = "/panel/api/inbounds/get/%d" func (c *X3Client) GetInbound(inboundId int) (GeneralResponse[Inbound], error) { return makeGetRequest[GeneralResponse[Inbound]](c.httpClient, c.Host+fmt.Sprintf(inboundURL, inboundId)) } const inboundClientTrafficURL = "/panel/api/inbounds/getClientTraffics/%s" func (c *X3Client) GetInboundClientTraffic(email string) (GeneralResponse[ClientStats], error) { return makeGetRequest[GeneralResponse[ClientStats]](c.httpClient, c.Host+fmt.Sprintf(inboundClientTrafficURL, email)) } const inboundClientTrafficByIdURL = "/panel/api/inbounds/getClientTrafficsById/%s" func (c *X3Client) GetInboundClientTrafficById(uuid string) (GeneralResponse[ClientStats], error) { return makeGetRequest[GeneralResponse[ClientStats]](c.httpClient, c.Host+fmt.Sprintf(inboundClientTrafficByIdURL, uuid)) } const inboundCreateBackupURL = "/panel/api/inbounds/createbackup" func (c *X3Client) CreateInboundBackup() (GeneralResponse[interface{}], error) { return makeGetRequest[GeneralResponse[interface{}]](c.httpClient, c.Host+inboundCreateBackupURL) } const clientIpsURL = "/panel/api/inbounds/clientIps/%s" func (c *X3Client) GetClientIps(email string) (GeneralResponse[string], error) { return makePostRequest[interface{}, GeneralResponse[string]](c.httpClient, c.Host+fmt.Sprintf(clientIpsURL, email), nil) } const addInboundURL = "/panel/api/inbounds/add" func (c *X3Client) AddInbound(inbound Inbound) (GeneralResponse[Inbound], error) { return makePostRequest[Inbound, GeneralResponse[Inbound]](c.httpClient, c.Host+addInboundURL, inbound) } const addClientToInboundURL = "/panel/api/inbounds/addClient" func (c *X3Client) AddClientToInbound(client CreateClient) (GeneralResponse[interface{}], error) { return makePostRequest[CreateClient, GeneralResponse[interface{}]](c.httpClient, c.Host+addClientToInboundURL, client) } const updateInboundURL = "/panel/api/inbounds/update/%d" func (c *X3Client) UpdateInbound(inbound Inbound) (GeneralResponse[Inbound], error) { return makePostRequest[Inbound, GeneralResponse[Inbound]](c.httpClient, c.Host+fmt.Sprintf(updateInboundURL, inbound.Id), inbound) } // TODO: Check if client id is int not an uuid const updateClientInboundURL = "/panel/api/inbounds/updateClient/%d" func (c *X3Client) UpdateClientInbound(client CreateClient) (GeneralResponse[interface{}], error) { return makePostRequest[CreateClient, GeneralResponse[interface{}]](c.httpClient, c.Host+fmt.Sprintf(updateClientInboundURL, client.Id), client) } const clearClientIpsURL = "/panel/api/inbounds/clearClientIps/%s" func (c *X3Client) ClearClientIps(email string) (GeneralResponse[interface{}], error) { return makePostRequest[interface{}, GeneralResponse[interface{}]](c.httpClient, c.Host+fmt.Sprintf(clearClientIpsURL, email), nil) } const resetAllTrafficURL = "/panel/api/inbounds/resetAllTraffics" func (c *X3Client) ResetAllTraffic() (GeneralResponse[interface{}], error) { return makePostRequest[interface{}, GeneralResponse[interface{}]](c.httpClient, c.Host+resetAllTrafficURL, nil) } const resetAllClientTrafficByInboundURL = "/panel/api/inbounds/resetAllClientTraffics/%d" func (c *X3Client) ResetAllClientTrafficByInbound(inboundId int) (GeneralResponse[interface{}], error) { return makePostRequest[interface{}, GeneralResponse[interface{}]](c.httpClient, c.Host+fmt.Sprintf(resetAllClientTrafficByInboundURL, inboundId), nil) } const resetClientTrafficURL = "/panel/api/inbounds/%d/resetClientTraffic/%s" func (c *X3Client) ResetClientTraffic(inboundId int, email string) (GeneralResponse[interface{}], error) { return makePostRequest[interface{}, GeneralResponse[interface{}]](c.httpClient, c.Host+fmt.Sprintf(resetClientTrafficURL, inboundId, email), nil) } const deleteClientURL = "/panel/api/inbounds/%d/delClient/%s" func (c *X3Client) DeleteClient(inboundId int, uuid string) (GeneralResponse[interface{}], error) { return makePostRequest[interface{}, GeneralResponse[interface{}]](c.httpClient, c.Host+fmt.Sprintf(deleteClientURL, inboundId, uuid), nil) } const deleteInboundURL = "/panel/api/inbounds/del/%d" func (c *X3Client) DeleteInbound(inboundId int) (GeneralResponse[interface{}], error) { return makePostRequest[interface{}, GeneralResponse[interface{}]](c.httpClient, c.Host+fmt.Sprintf(deleteInboundURL, inboundId), nil) } const deleteDepletedClientsURL = "/panel/api/inbounds/delDepletedClients/%d" func (c *X3Client) DeleteDepletedClients(inboundId int) (GeneralResponse[interface{}], error) { return makePostRequest[interface{}, GeneralResponse[interface{}]](c.httpClient, c.Host+fmt.Sprintf(deleteDepletedClientsURL, inboundId), nil) } const onlineClientsURL = "/panel/api/inbounds/onlines" func (c *X3Client) GetOnlineClients() (GeneralResponse[interface{}], error) { return makePostRequest[interface{}, GeneralResponse[interface{}]](c.httpClient, c.Host+onlineClientsURL, nil) }