Compare commits
7 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
586e336cb8 | ||
|
|
1c1b2a3a1d | ||
|
|
43d4e6caee | ||
|
|
00104dc59a | ||
|
|
ae765605d9 | ||
|
|
6eb0beb355 | ||
|
|
700659ff60 |
4 changed files with 74 additions and 59 deletions
|
|
@ -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):
|
Then in your configuration (using sops-nix, you will need to adjust it if you use agenix or alternatives):
|
||||||
```nix
|
```nix
|
||||||
|
nixpkgs.overlays = [ inputs.actualbudget-report.overlays.default ];
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
inputs.actualbudget-report.nixosModules.default;
|
inputs.actualbudget-report.nixosModules.default
|
||||||
];
|
];
|
||||||
|
|
||||||
# Fill out all the following environment variables for the service
|
# Fill out all the following environment variables for the service
|
||||||
|
|
@ -25,6 +27,7 @@ sops.templates."actualbudget-report-env".content = ''
|
||||||
SMTP_PASSWORD=
|
SMTP_PASSWORD=
|
||||||
SMTP_HOST=
|
SMTP_HOST=
|
||||||
SMTP_RECIPIENTS=
|
SMTP_RECIPIENTS=
|
||||||
|
BUDGET_ENCRYPTION_KEY=
|
||||||
'';
|
'';
|
||||||
|
|
||||||
services.actualbudget-report = {
|
services.actualbudget-report = {
|
||||||
|
|
|
||||||
84
flake.nix
84
flake.nix
|
|
@ -7,44 +7,52 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
inputs@{ flake-parts, ... }:
|
inputs@{
|
||||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
self,
|
||||||
systems = [
|
flake-parts,
|
||||||
"x86_64-linux"
|
...
|
||||||
"aarch64-linux"
|
}:
|
||||||
"aarch64-darwin"
|
flake-parts.lib.mkFlake
|
||||||
"x86_64-darwin"
|
{
|
||||||
];
|
inherit inputs;
|
||||||
flake.nixosModules = {
|
}
|
||||||
default = ./modules/actualbudget-report;
|
{
|
||||||
};
|
imports = [ inputs.flake-parts.flakeModules.easyOverlay ];
|
||||||
perSystem =
|
systems = [
|
||||||
{
|
"x86_64-linux"
|
||||||
config,
|
"aarch64-linux"
|
||||||
self',
|
"aarch64-darwin"
|
||||||
inputs',
|
"x86_64-darwin"
|
||||||
pkgs,
|
];
|
||||||
system,
|
flake.nixosModules.default = ./modules/actualbudget-report;
|
||||||
...
|
perSystem =
|
||||||
}:
|
{
|
||||||
{
|
config,
|
||||||
packages.default = pkgs.buildGoModule {
|
self',
|
||||||
name = "actualbudget-report";
|
inputs',
|
||||||
src = pkgs.fetchFromGitea {
|
pkgs,
|
||||||
domain = "git.wanderingcrow.net";
|
system,
|
||||||
owner = "TheWanderingCrow";
|
...
|
||||||
repo = "actualbudget-report";
|
}:
|
||||||
rev = "v0.1";
|
{
|
||||||
hash = "sha256-1Z3+Efx0MCsZhfz49nKsdaWgyVt9+7kekwgfQyaYUxQ=";
|
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
32
main.go
|
|
@ -32,10 +32,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type BudgetClient struct {
|
type BudgetClient struct {
|
||||||
baseUrl string
|
baseUrl string
|
||||||
apiKey string
|
apiKey string
|
||||||
syncId string
|
syncId string
|
||||||
fullUrl string
|
fullUrl string
|
||||||
|
encryptionKey string
|
||||||
}
|
}
|
||||||
|
|
||||||
type BudgetMonthsResponse struct {
|
type BudgetMonthsResponse struct {
|
||||||
|
|
@ -73,9 +74,12 @@ type BudgetMonthsResponse struct {
|
||||||
} `json:"data"`
|
} `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
|
fullUrl := baseUrl + "/v1/budgets/" + syncId
|
||||||
client := BudgetClient{baseUrl, apiKey, syncId, fullUrl}
|
client := BudgetClient{baseUrl, apiKey, syncId, fullUrl, encryptionKey}
|
||||||
return &client
|
return &client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +115,9 @@ func (b BudgetClient) GetBudgetMonths() *BudgetMonthsResponse {
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
year, month := currentTime.Year(), int(currentTime.Month())
|
year, month := currentTime.Year(), int(currentTime.Month())
|
||||||
budgetMonth := fmt.Sprintf("%v-%v", year, 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()
|
defer resp.Body.Close()
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
log.Fatal("GetBudgetAmounts failed with: " + string(resp.Status))
|
log.Fatal("GetBudgetAmounts failed with: " + string(resp.Status))
|
||||||
|
|
@ -139,11 +145,13 @@ func main() {
|
||||||
var baseUrl = os.Getenv("BASE_URL")
|
var baseUrl = os.Getenv("BASE_URL")
|
||||||
var apiKey = os.Getenv("API_KEY")
|
var apiKey = os.Getenv("API_KEY")
|
||||||
var syncId = os.Getenv("SYNC_ID")
|
var syncId = os.Getenv("SYNC_ID")
|
||||||
|
var encryptionKey = os.Getenv("BUDGET_ENCRYPTION_KEY")
|
||||||
var smtpUsername = os.Getenv("SMTP_USERNAME")
|
var smtpUsername = os.Getenv("SMTP_USERNAME")
|
||||||
var smtpPassword = os.Getenv("SMTP_PASSWORD")
|
var smtpPassword = os.Getenv("SMTP_PASSWORD")
|
||||||
var smtpHost = os.Getenv("SMTP_HOST")
|
var smtpHost = os.Getenv("SMTP_HOST")
|
||||||
|
var smtpPort = os.Getenv("SMTP_PORT")
|
||||||
var smtpRecipients = os.Getenv("SMTP_RECIPIENTS")
|
var smtpRecipients = os.Getenv("SMTP_RECIPIENTS")
|
||||||
client := CreateBudgetClient(baseUrl, apiKey, syncId)
|
client := CreateBudgetClient(baseUrl, apiKey, syncId, encryptionKey)
|
||||||
if !client.BankSync() {
|
if !client.BankSync() {
|
||||||
log.Println("Bank Sync failed, information may not be up to date")
|
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())
|
message := []byte(subject + mime + body + categories.String())
|
||||||
|
|
||||||
var auth smtp.Auth
|
var auth smtp.Auth
|
||||||
if os.Getenv("ENVIRONMENT") == "dev" {
|
auth = smtp.PlainAuth("", smtpUsername, smtpPassword, smtpHost)
|
||||||
auth = nil
|
err := smtp.SendMail(smtpHost+":"+smtpPort, auth, smtpUsername, strings.Split(smtpRecipients, ","), []byte(message))
|
||||||
} else {
|
|
||||||
auth = smtp.PlainAuth("", smtpUsername, smtpPassword, smtpHost)
|
|
||||||
}
|
|
||||||
err := smtp.SendMail(smtpHost, auth, smtpUsername, strings.Split(smtpRecipients, ","), []byte(message))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
|
pkgs,
|
||||||
config,
|
config,
|
||||||
options,
|
options,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
|
|
@ -10,8 +10,8 @@ let
|
||||||
opt = options.services.actualbudget-report;
|
opt = options.services.actualbudget-report;
|
||||||
inherit (lib)
|
inherit (lib)
|
||||||
mkEnableOption
|
mkEnableOption
|
||||||
mkOption
|
|
||||||
mkPackageOption
|
mkPackageOption
|
||||||
|
mkOption
|
||||||
mkIf
|
mkIf
|
||||||
types
|
types
|
||||||
;
|
;
|
||||||
|
|
@ -20,12 +20,12 @@ in
|
||||||
options = {
|
options = {
|
||||||
services.actualbudget-report = {
|
services.actualbudget-report = {
|
||||||
enable = mkEnableOption "Actualbudget email reports";
|
enable = mkEnableOption "Actualbudget email reports";
|
||||||
package = mkPackageOption pkgs.default;
|
interval = mkOption {
|
||||||
interval = {
|
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "Sun 12:00:00";
|
default = "Sun 12:00:00";
|
||||||
description = "systemd-timer OnCalendar legal string for sending reports.";
|
description = "systemd-timer OnCalendar legal string for sending reports.";
|
||||||
};
|
};
|
||||||
|
package = mkPackageOption pkgs "actualbudget-report" { };
|
||||||
environmentFile = mkOption {
|
environmentFile = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
default = "";
|
default = "";
|
||||||
|
|
@ -39,11 +39,11 @@ in
|
||||||
description = "Actualbudget report sender service";
|
description = "Actualbudget report sender service";
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
ExecStart = "${cfg.package}/bin/actualbudget-report";
|
ExecStart = "${pkgs.actualbudget-report}/bin/actualbudget-report";
|
||||||
EnvironmentFile = cfg.environmentFile;
|
EnvironmentFile = cfg.environmentFile;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
systemd.timers.flamesite-backup = {
|
systemd.timers.actualbudget-report = {
|
||||||
enable = true;
|
enable = true;
|
||||||
wantedBy = [ "timers.target" ];
|
wantedBy = [ "timers.target" ];
|
||||||
timerConfig = {
|
timerConfig = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue