upngo

package module
v0.0.0-...-ce6b9a0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2020 License: MIT Imports: 12 Imported by: 0

README

upngo

CLI and library for working with UpBank via its API.

TODO

  • Ping
  • List accounts
  • List transactions
  • Get specific account
  • Get specific transaction
  • Get webhooks
  • Create webhooks
  • Get speific webhook
  • Delete webhook
  • Ping webhook
  • List webhook logs
  • Generate completion
  • Move raw API wrapper into api subdirectory and create nicer high-level wrapper

CLI

The CLI lets you do anything you can do via the library or API it just provides a nice CLI wrapper.

$ upngo help
Talk to your bank from the CLI!

Usage:
  upngo [command]

Available Commands:
  add         A brief description of your command
  completion  Generate completion script
  get         Get accounts or transactions.
  help        Help about any command
  init        Initialise the UpBank CLI for ease of use by adding the token to your keyring.
  list        List accounts or transactions
  ping        Ping UpBank. Useful to test your token is correct.

Flags:
  -h, --help      help for upngo
  -v, --verbose   Verbose logging

Use "upngo [command] --help" for more information about a command.
Completion

You can generate completions for upgngoctl with:

upngoctl completion zsh

If you use a different shell, replace zsh with the shell you use.

This command will output the completion script the console. You can save this to the directory you source your completions from. See the output of:

upngoctl help completion

for more details on how to get completion working.

Webhook management

The other parts of the CLI are cool but I think the really useful bit will be being able to manage webhooks.

Library

Currently the library is just a raw wrapper around the API. There is nothing done to distill the API output into more idiomatic Go. For instance, the structures directly map to the JSON and are highly nested, which is unnecessarily difficult to work with because we can wrap them up into some nice Go types. In particular anything to do with money can probably be wrapped up into a currency.Amountand things like that.

Documentation

Index

Constants

View Source
const (
	MaxWebhookURLLength         = 64
	MaxWebhookDescriptionLength = 300
)

Variables

View Source
var ErrNotImplemented = errors.New("not implemented")

Functions

This section is empty.

Types

type AccountObject

type AccountObject struct {
	Links RelatedLinksObject `json:"links"`
	Data  DataObject         `json:"data"`
}

type AccountResource

type AccountResource struct {
	ID            string              `json:"id"`
	Type          string              `json:"type"`
	Attributes    AttributesObject    `json:"attributes"`
	Links         SelfLinkObject      `json:"links"`
	Relationships RelationshipsObject `json:"relationships"`
}

type AccountResponse

type AccountResponse struct {
	Data AccountResource `json:"data"`
}

AccountResponse represents a response from the account endpoint.

type AccountType

type AccountType string

AccountType represents an enum of the possible account type. Currently that is only saver and transactional but I guess there could potentially be more supported in the future.

const (
	AccountTypeSaver         AccountType = "SAVER"
	AccountTypeTransactional AccountType = "TRANSACTIONAL"
)

type AccountsOption

type AccountsOption struct {
	// contains filtered or unexported fields
}

AccountsOption represents an option (URL param) for the Accounts endpoint.

This type isn't exposed so we instead expose constructors to build it with the given values. Once it gets to the point that this struct is constructed, the type of value doesn't really matter because it's just going into the URL param so it's a string for convenience. It's the job of the constructor to convert the given value to a string.

For constructors, the `name` should be the key in the URL param and `value` should be the value, i.e. options will be formatted as `<name>=<value>` in the URL.

func WithPageSize

func WithPageSize(size int) AccountsOption

WithPageSize specifies that the API should return `size` number of accounts.

type AccountsResponse

type AccountsResponse struct {
	Data  []AccountResource `json:"data"`
	Links LinksObject       `json:"links"`
}

type AttributesObject

type AttributesObject struct {
	DisplayName string      `json:"displayName"`
	AccountType AccountType `json:"accountType"`
	Balance     MoneyObject `json:"balance"`
	CreatedAt   time.Time   `json:"createdAt"`
}

type CashbackObject

type CashbackObject struct {
	Description string      `json:"description"`
	Amount      MoneyObject `json:"amount"`
}

type Client

type Client struct {
	// contains filtered or unexported fields
}

func NewClient

func NewClient(token string) *Client

func (*Client) Account

func (c *Client) Account(id string) (AccountResponse, error)

Account retrieves an account by its ID.

func (*Client) Accounts

func (c *Client) Accounts(options ...AccountsOption) (AccountsResponse, error)

Accounts lists all the accounts associated with the authenticated account.

func (*Client) Ping

func (c *Client) Ping() error

Ping pings the UpBank API and returns an error if there is an problem.

func (Client) PingWebhook

func (c Client) PingWebhook(id string) (WebhookPingResponse, error)

func (*Client) RegisterWebhook

func (c *Client) RegisterWebhook(webhookURL string, opts ...RegisterWebhookOption) (WebhookResponse, error)

RegisterWebhook registers a webhook for the given URL.

func (*Client) Transaction

func (c *Client) Transaction(id string) (TransactionResponse, error)

Transaction retrieves a transaction by its ID.

func (*Client) Transactions

func (c *Client) Transactions(options ...TransactionsOption) (TransactionsResponse, error)

Transactions lists all the transactions associated with the authenticated account.

func (*Client) Webhooks

func (c *Client) Webhooks() (WebhooksResponse, error)

Webhooks gets all the webhooks.

type DataObject

type DataObject struct {
	Type string `json:"type"`
	ID   string `json:"id"`
}

type ErrorObject

type ErrorObject struct {
	Status string `json:"status"`
	Title  string `json:"title"`
	Detail string `json:"detail"`
}

type ErrorResponse

type ErrorResponse struct {
	Errors []ErrorObject `json:"errors"`
	Source SourceObject  `json:"source"`
}

type HoldInfoObject

type HoldInfoObject struct {
	Amount        MoneyObject `json:"amount"`
	ForeignAmount MoneyObject `json:"foreignAmount"`
}

type LinksObject

type LinksObject struct {
	Prev string `json:"prev"`
	Next string `json:"next"`
}

type LogsLinkObject

type LogsLinkObject struct {
	Links LogsRelatedObject `json:"links"`
}

type LogsRelatedObject

type LogsRelatedObject struct {
	Related string `json:"related"`
}

type LogsRelationship

type LogsRelationship struct {
	Logs LogsLinkObject `json:"logs"`
}

type MoneyObject

type MoneyObject struct {
	CurrencyCode     string `json:"currencyCode"`
	Value            string `json:"value"`
	ValueInBaseUnits int64  `json:"valueInBaseUnits"`
}

func (MoneyObject) Format

func (m MoneyObject) Format() string

type PingResponse

type PingResponse struct {
	Meta PingResponseMeta `json:"meta"`
}

type PingResponseMeta

type PingResponseMeta struct {
	ID          string `json:"id"`
	StatusEmoji string `json:"statusEmoji"`
}

type RegisterWebhookOption

type RegisterWebhookOption struct {
	// contains filtered or unexported fields
}

func WithDescription

func WithDescription(desc string) RegisterWebhookOption

type RegisterWebhookRequest

type RegisterWebhookRequest struct {
	Data WebhookInputResource `json:"data"`
}

type RelatedLinksObject

type RelatedLinksObject struct {
	Related string `json:"related"`
}

type RelationshipsObject

type RelationshipsObject struct {
	Transactions TransactionsObject `json:"transactions"`
}

type Resource

type Resource struct {
	ID    string         `json:"id"`
	Type  string         `json:"type"`
	Links SelfLinkObject `json:"links"`
}

type RoundUpObject

type RoundUpObject struct {
	Amount       MoneyObject `json:"amount"`
	BoostPortion MoneyObject `json:"boostPortion"`
}

type SelfLinkObject

type SelfLinkObject struct {
	Self string `json:"self"`
}

type SourceObject

type SourceObject struct {
	Parameter string `json:"parameter"`
	Pointer   string `json:"pointer"`
}

type TagObject

type TagObject struct {
	Data  []interface{}  `json:"data"`
	Links SelfLinkObject `json:"links"`
}

TagObject is an undocumented part of the transactions response. I'm not sure what `Data` contains as I've only seen it as empty so far. We shall see!

type TransactionAttributes

type TransactionAttributes struct {
	Description   string            `json:"description"`
	Status        TransactionStatus `json:"status"`
	RawText       string            `json:"rawText"`
	Message       string            `json:"message"`
	HoldInfo      HoldInfoObject    `json:"holdInfo"`
	RoundUp       RoundUpObject     `json:"roundUp"`
	Cashback      CashbackObject    `json:"cashback"`
	Amount        MoneyObject       `json:"amount"`
	ForeignAmount MoneyObject       `json:"foreignAmount"`
	SettledAt     time.Time         `json:"settledAt"`
	CreatedAt     time.Time         `json:"createdAt"`
}

type TransactionRelationshipsObject

type TransactionRelationshipsObject struct {
	Account AccountObject `json:"account"`
	Tags    TagObject     `json:"tags"`
}

type TransactionResource

type TransactionResource struct {
	Resource
	Attributes    TransactionAttributes          `json:"attributes"`
	Relationships TransactionRelationshipsObject `json:"relationships"`
}

type TransactionResponse

type TransactionResponse struct {
	Data  TransactionResource `json:"data"`
	Links LinksObject         `json:"links"`
}

type TransactionStatus

type TransactionStatus string
const (
	TransactionStatusHeld    TransactionStatus = "HELD"
	TransactionStatusSettled TransactionStatus = "SETTELED"
)

type TransactionsLinksObject

type TransactionsLinksObject struct {
	Related string `json:"related"`
}

type TransactionsObject

type TransactionsObject struct {
	Links TransactionsLinksObject `json:"links"`
}

type TransactionsOption

type TransactionsOption struct {
	// contains filtered or unexported fields
}

TransactionsOption is an option for the transactions API.

func WithFilterSince

func WithFilterSince(since time.Time) TransactionsOption

func WithFilterUntil

func WithFilterUntil(until time.Time) TransactionsOption

func WithTransactionPageSize

func WithTransactionPageSize(size int) TransactionsOption

TODO: This is a horrible name but otherwise it clashes with the accounts page size option. Anyway, I'm thinking either have to test out whether we can have a base option then alias it for the specific ones but I'm not sure if that will still be typesafe. Alternatively, it might be good, in general, to split out each resoure into a subclient, then they could have different namespaces.

type TransactionsResponse

type TransactionsResponse struct {
	Data  []TransactionResource `json:"data"`
	Links LinksObject           `json:"links"`
}

type WebhookEventResource

type WebhookEventResource struct {
	Type          string                            `json:"type"`
	ID            string                            `json:"id"`
	Attributes    WebhookEventResourceAttributes    `json:"attributes"`
	Relationships WebhookEventResourceRelationships `json:"relationships"`
}

type WebhookEventResourceAttributes

type WebhookEventResourceAttributes struct {
	EventType WebhookEventType `json:"eventType"`
	CreatedAt time.Time        `json:"createdAt"`
}

type WebhookEventResourceRelationships

type WebhookEventResourceRelationships struct {
	Webhook struct {
		Data struct {
			Type string `json:"type"`
			ID   string `json:"id"`
		} `json:"data"`
		Links struct {
			Related string `json:"related"`
		} `json:"links"`
	} `json:"webhook"`
	Transaction struct {
		Data struct {
			Type string `json:"type"`
			ID   string `json:"id"`
		} `json:"data"`
		Links RelatedLinksObject `json:"links"`
	} `json:"transaction"`
}

type WebhookEventType

type WebhookEventType string
const (
	WebhookEventTypeTransactionCreated WebhookEventType = "TRANSACTION_CREATED"
	WebhookEventTypeTransactionSettled WebhookEventType = "TRANSACTION_SETTLED"
	WebhookEventTypeTransactionDeleted WebhookEventType = "TRANSACTION_DELETED"
	WebhookEventTypePing               WebhookEventType = "PING"
)

type WebhookInputResource

type WebhookInputResource struct {
	Attributes WebhookInputResourceAttributes `json:"attributes"`
}

type WebhookInputResourceAttributes

type WebhookInputResourceAttributes struct {
	// Max length 300 chars
	URL string `json:"url"`
	// Max length 64 chars
	Description string `json:"description"`
}

type WebhookPingResponse

type WebhookPingResponse struct {
	Data WebhookEventResource `json:"data"`
}

type WebhookResource

type WebhookResource struct {
	Type          string             `json:"type"`
	ID            string             `json:"id"`
	Attributes    WebhooksAttributes `json:"attributes"`
	Relationships LogsRelationship   `json:"relationships"`
	Links         SelfLinkObject     `json:"links"`
}

type WebhookResponse

type WebhookResponse struct {
	Data  WebhookResource `json:"data"`
	Links LinksObject     `json:"links"`
}

type WebhooksAttributes

type WebhooksAttributes struct {
	URL         string    `json:"url"`
	Description string    `json:"description"`
	SecretKey   string    `json:"secretKey"`
	CreatedAt   time.Time `json:"createdAt"`
}

type WebhooksResponse

type WebhooksResponse struct {
	Data  []WebhookResource `json:"data"`
	Links LinksObject       `json:"links"`
}

Directories

Path Synopsis
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL