From 79a6c7a2c16a0cc785766e58831ac8f1cd34d68b Mon Sep 17 00:00:00 2001 From: TheWanderingCrow Date: Tue, 11 Nov 2025 10:40:07 -0500 Subject: [PATCH] feat: Implement BudgetClient, add method for syncing bank --- .env.example | 3 +++ .gitignore | 1 + README.md | 2 +- flake.nix | 1 + go.mod | 5 +++++ go.sum | 2 ++ src/main.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 .env.example create mode 100644 go.mod create mode 100644 go.sum create mode 100644 src/main.go diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..1d131ef --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ + BASE_URL= + API_KEY= + SYNC_ID= diff --git a/.gitignore b/.gitignore index d53e06f..a4534d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .direnv/ result +.env diff --git a/README.md b/README.md index 79b8374..8412018 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Learning golang, writing a simple app to interface with an HTTP API and generate # TODO - [ ] Fetch the desired budget file -- [ ] Trigger a bank sync and see if we can wait for it to finish (might need to trigger the sync and then just wait, could also just do daily bank syncs at a certain hour) +- [x] Trigger a bank sync and see if we can wait for it to finish (looks like it's a blocking call so we can safely sync before reports) - [ ] Fetch the category information for each category as well as the overall groups - [ ] Compile a email-friendly report of the information - [ ] Send the email to the desired parties via SMTP diff --git a/flake.nix b/flake.nix index bac2f33..0f35833 100644 --- a/flake.nix +++ b/flake.nix @@ -33,6 +33,7 @@ # FIXME(TODO): Build the package # packages.default = devShells.default = pkgs.mkShell { + ENVIRONMENT = "dev"; nativeBuildInputs = with pkgs; [ go ]; }; }; diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..3b3ee91 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module git.wanderingcrow.net/actualbudget-report + +go 1.25.2 + +require github.com/joho/godotenv v1.5.1 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d61b19e --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= diff --git a/src/main.go b/src/main.go new file mode 100644 index 0000000..e3dabba --- /dev/null +++ b/src/main.go @@ -0,0 +1,53 @@ +package main + +import ( + "github.com/joho/godotenv" + "log" + "net/http" + "os" +) + +type BudgetClient struct { + baseUrl string + apiKey string + syncId string +} + +func CreateBudgetClient(baseUrl string, apiKey string, syncId string) *BudgetClient { + client := BudgetClient{baseUrl, apiKey, syncId} + return &client +} + +func (b BudgetClient) BankSync() bool { + var httpClient http.Client + req, err := http.NewRequest("POST", b.baseUrl+"/v1/budgets/"+b.syncId+"/accounts/banksync", http.NoBody) + if err != nil { + log.Fatal(err) + } + req.Header.Add("x-api-key", b.apiKey) + log.Println("Sent off request") + resp, err := httpClient.Do(req) + if err != nil { + log.Fatal(err) + } + log.Println(resp) + if resp.StatusCode == http.StatusOK { + return true + } else { + return false + } +} + +func main() { + if os.Getenv("ENVIRONMENT") == "dev" { + err := godotenv.Load() + if err != nil { + log.Fatal("Error loading .env file") + } + } + var baseUrl = os.Getenv("BASE_URL") + var apiKey = os.Getenv("API_KEY") + var syncId = os.Getenv("SYNC_ID") + client := CreateBudgetClient(baseUrl, apiKey, syncId) + client.BankSync() +}