Compare commits

...

7 commits
v0.2 ... main

Author SHA1 Message Date
TheWanderingCrow
586e336cb8 chore: release v2.0 2025-12-30 22:11:21 -05:00
TheWanderingCrow
1c1b2a3a1d fix!: SMTP now works properly in non-dev environments 2025-12-30 21:50:16 -05:00
TheWanderingCrow
43d4e6caee chore: update sha256 2025-12-30 21:21:02 -05:00
TheWanderingCrow
00104dc59a docs: fix syntax error in README.md 2025-12-27 11:04:28 -05:00
TheWanderingCrow
ae765605d9 chore: release v1.0 2025-12-27 10:57:43 -05:00
TheWanderingCrow
6eb0beb355 add support for encryption key protected budget files 2025-12-27 10:45:49 -05:00
TheWanderingCrow
700659ff60 fix: make module work and add instructions for using 2025-12-26 17:23:31 -05:00
4 changed files with 74 additions and 59 deletions

View file

@ -12,8 +12,10 @@ inputs.actualbudget-report.url = "git+https://git.wanderingcrow.net/TheWandering
Then in your configuration (using sops-nix, you will need to adjust it if you use agenix or alternatives):
```nix
nixpkgs.overlays = [ inputs.actualbudget-report.overlays.default ];
imports = [
inputs.actualbudget-report.nixosModules.default;
inputs.actualbudget-report.nixosModules.default
];
# Fill out all the following environment variables for the service
@ -25,6 +27,7 @@ sops.templates."actualbudget-report-env".content = ''
SMTP_PASSWORD=
SMTP_HOST=
SMTP_RECIPIENTS=
BUDGET_ENCRYPTION_KEY=
'';
services.actualbudget-report = {

View file

@ -7,44 +7,52 @@
};
outputs =
inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = [
"x86_64-linux"
"aarch64-linux"
"aarch64-darwin"
"x86_64-darwin"
];
flake.nixosModules = {
default = ./modules/actualbudget-report;
};
perSystem =
{
config,
self',
inputs',
pkgs,
system,
...
}:
{
packages.default = pkgs.buildGoModule {
name = "actualbudget-report";
src = pkgs.fetchFromGitea {
domain = "git.wanderingcrow.net";
owner = "TheWanderingCrow";
repo = "actualbudget-report";
rev = "v0.1";
hash = "sha256-1Z3+Efx0MCsZhfz49nKsdaWgyVt9+7kekwgfQyaYUxQ=";
inputs@{
self,
flake-parts,
...
}:
flake-parts.lib.mkFlake
{
inherit inputs;
}
{
imports = [ inputs.flake-parts.flakeModules.easyOverlay ];
systems = [
"x86_64-linux"
"aarch64-linux"
"aarch64-darwin"
"x86_64-darwin"
];
flake.nixosModules.default = ./modules/actualbudget-report;
perSystem =
{
config,
self',
inputs',
pkgs,
system,
...
}:
{
overlayAttrs = { inherit (config.packages) actualbudget-report; };
packages.actualbudget-report = pkgs.buildGoModule {
name = "actualbudget-report";
src = pkgs.fetchFromGitea {
domain = "git.wanderingcrow.net";
owner = "TheWanderingCrow";
repo = "actualbudget-report";
rev = "v2.0";
hash = "sha256-H+pA9dFsP5QQ3W32NEU1TWYiOiti53jnzN3Bnq+QJ5Q=";
};
vendorHash = "sha256-NHTKwUSIbNCUco88JbHOo3gt6S37ggee+LWNbHaRGEs=";
};
devShells.default = pkgs.mkShell {
ENVIRONMENT = "dev";
nativeBuildInputs = with pkgs; [
devenv
];
};
vendorHash = "sha256-NHTKwUSIbNCUco88JbHOo3gt6S37ggee+LWNbHaRGEs=";
};
devShells.default = pkgs.mkShell {
ENVIRONMENT = "dev";
nativeBuildInputs = with pkgs; [
devenv
];
};
};
};
};
}

32
main.go
View file

@ -32,10 +32,11 @@ import (
)
type BudgetClient struct {
baseUrl string
apiKey string
syncId string
fullUrl string
baseUrl string
apiKey string
syncId string
fullUrl string
encryptionKey string
}
type BudgetMonthsResponse struct {
@ -73,9 +74,12 @@ type BudgetMonthsResponse struct {
} `json:"data"`
}
func CreateBudgetClient(baseUrl string, apiKey string, syncId string) *BudgetClient {
// Create budget client, you may pass empty strings to optional parameters
// Required: baseUrl, apiKey, syncId
// Optional: encryptionKey
func CreateBudgetClient(baseUrl string, apiKey string, syncId string, encryptionKey string) *BudgetClient {
fullUrl := baseUrl + "/v1/budgets/" + syncId
client := BudgetClient{baseUrl, apiKey, syncId, fullUrl}
client := BudgetClient{baseUrl, apiKey, syncId, fullUrl, encryptionKey}
return &client
}
@ -111,7 +115,9 @@ func (b BudgetClient) GetBudgetMonths() *BudgetMonthsResponse {
currentTime := time.Now()
year, month := currentTime.Year(), int(currentTime.Month())
budgetMonth := fmt.Sprintf("%v-%v", year, month)
resp := b.callApi("GET", "/months/"+budgetMonth, nil)
resp := b.callApi("GET", "/months/"+budgetMonth, map[string]string{
"budget-encryption-password": b.encryptionKey,
})
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Fatal("GetBudgetAmounts failed with: " + string(resp.Status))
@ -139,11 +145,13 @@ func main() {
var baseUrl = os.Getenv("BASE_URL")
var apiKey = os.Getenv("API_KEY")
var syncId = os.Getenv("SYNC_ID")
var encryptionKey = os.Getenv("BUDGET_ENCRYPTION_KEY")
var smtpUsername = os.Getenv("SMTP_USERNAME")
var smtpPassword = os.Getenv("SMTP_PASSWORD")
var smtpHost = os.Getenv("SMTP_HOST")
var smtpPort = os.Getenv("SMTP_PORT")
var smtpRecipients = os.Getenv("SMTP_RECIPIENTS")
client := CreateBudgetClient(baseUrl, apiKey, syncId)
client := CreateBudgetClient(baseUrl, apiKey, syncId, encryptionKey)
if !client.BankSync() {
log.Println("Bank Sync failed, information may not be up to date")
}
@ -177,12 +185,8 @@ func main() {
message := []byte(subject + mime + body + categories.String())
var auth smtp.Auth
if os.Getenv("ENVIRONMENT") == "dev" {
auth = nil
} else {
auth = smtp.PlainAuth("", smtpUsername, smtpPassword, smtpHost)
}
err := smtp.SendMail(smtpHost, auth, smtpUsername, strings.Split(smtpRecipients, ","), []byte(message))
auth = smtp.PlainAuth("", smtpUsername, smtpPassword, smtpHost)
err := smtp.SendMail(smtpHost+":"+smtpPort, auth, smtpUsername, strings.Split(smtpRecipients, ","), []byte(message))
if err != nil {
log.Fatal(err)
}

View file

@ -1,8 +1,8 @@
{
pkgs,
config,
options,
lib,
pkgs,
...
}:
let
@ -10,8 +10,8 @@ let
opt = options.services.actualbudget-report;
inherit (lib)
mkEnableOption
mkOption
mkPackageOption
mkOption
mkIf
types
;
@ -20,12 +20,12 @@ in
options = {
services.actualbudget-report = {
enable = mkEnableOption "Actualbudget email reports";
package = mkPackageOption pkgs.default;
interval = {
interval = mkOption {
type = types.str;
default = "Sun 12:00:00";
description = "systemd-timer OnCalendar legal string for sending reports.";
};
package = mkPackageOption pkgs "actualbudget-report" { };
environmentFile = mkOption {
type = types.path;
default = "";
@ -39,11 +39,11 @@ in
description = "Actualbudget report sender service";
serviceConfig = {
Type = "oneshot";
ExecStart = "${cfg.package}/bin/actualbudget-report";
ExecStart = "${pkgs.actualbudget-report}/bin/actualbudget-report";
EnvironmentFile = cfg.environmentFile;
};
};
systemd.timers.flamesite-backup = {
systemd.timers.actualbudget-report = {
enable = true;
wantedBy = [ "timers.target" ];
timerConfig = {