You've already forked monobank-firefly3-bot
							
							Compare commits
	
		
			2 Commits
		
	
	
		
			1646d484fb
			...
			fb7796c475
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						fb7796c475
	
				 | 
					
					
						|||
| 
						
						
							
						
						e1c9f56921
	
				 | 
					
					
						
@@ -12,6 +12,7 @@ import (
 | 
				
			|||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"slices"
 | 
						"slices"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -28,6 +29,15 @@ func ImportTransaction(monobankTransaction monobank.WebHookResponse) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// check if transaction hs been logged
 | 
				
			||||||
 | 
						isTransactionAlreadyLogged, err := LogContainsTransactionID(monobankTransaction.Data.StatementItem.Id)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if isTransactionAlreadyLogged {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// find accounts
 | 
						// find accounts
 | 
				
			||||||
	destAccount := App().Config.GetAccountByMonobankId(monobankTransaction.Data.Account)
 | 
						destAccount := App().Config.GetAccountByMonobankId(monobankTransaction.Data.Account)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -92,8 +102,21 @@ func ImportTransaction(monobankTransaction monobank.WebHookResponse) error {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
 | 
								// check name match
 | 
				
			||||||
 | 
								isDescriptionMatch := false
 | 
				
			||||||
 | 
								if row.NamesLooseMatch {
 | 
				
			||||||
 | 
									for _, name := range row.Names {
 | 
				
			||||||
 | 
										if strings.HasPrefix(monobankTransaction.Data.StatementItem.Description, name) {
 | 
				
			||||||
 | 
											isDescriptionMatch = true
 | 
				
			||||||
 | 
											break
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									isDescriptionMatch = slices.Contains(row.Names, monobankTransaction.Data.StatementItem.Description)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// check name & mcc
 | 
								// check name & mcc
 | 
				
			||||||
			if !(slices.Contains(row.Names, monobankTransaction.Data.StatementItem.Description) || slices.Contains(row.MccCodes, int(monobankTransaction.Data.StatementItem.Mcc))) {
 | 
								if !(isDescriptionMatch || slices.Contains(row.MccCodes, int(monobankTransaction.Data.StatementItem.Mcc))) {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -135,7 +158,7 @@ func ImportTransaction(monobankTransaction monobank.WebHookResponse) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				// when transfer between different currencies, convert
 | 
									// when transfer between different currencies, convert
 | 
				
			||||||
				sourceAccount := App().Config.GetAccountByFirefly3Name(firefly3Transaction.SourceName)
 | 
									sourceAccount := App().Config.GetAccountByFirefly3Name(firefly3Transaction.SourceName)
 | 
				
			||||||
				if sourceAccount.Currency != destAccount.Currency {
 | 
									if len(sourceAccount.Currency) > 0 && sourceAccount.Currency != destAccount.Currency {
 | 
				
			||||||
					// swap amounts
 | 
										// swap amounts
 | 
				
			||||||
					firefly3Transaction.ForeignAmount = firefly3Transaction.Amount
 | 
										firefly3Transaction.ForeignAmount = firefly3Transaction.Amount
 | 
				
			||||||
					firefly3Transaction.Amount = strconv.Itoa(int(math.Abs(math.Round(monobankTransaction.Data.StatementItem.OperationAmount / 100))))
 | 
										firefly3Transaction.Amount = strconv.Itoa(int(math.Abs(math.Round(monobankTransaction.Data.StatementItem.OperationAmount / 100))))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
package app
 | 
					package app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"bufio"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -20,3 +22,49 @@ func LogString(str string) {
 | 
				
			|||||||
		fmt.Println(err)
 | 
							fmt.Println(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LogContainsTransactionID(transactionID string) (bool, error) {
 | 
				
			||||||
 | 
						if len(os.Getenv("LOG_FILE")) == 0 {
 | 
				
			||||||
 | 
							return false, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// open the log file for reading.
 | 
				
			||||||
 | 
						logFile, err := os.Open(os.Getenv("LOG_FILE"))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return false, fmt.Errorf("error opening log file: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer logFile.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// create a new scanner to read the log file line by line.
 | 
				
			||||||
 | 
						scanner := bufio.NewScanner(logFile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// iterate over each line of the log file.
 | 
				
			||||||
 | 
						for scanner.Scan() {
 | 
				
			||||||
 | 
							// unmarshal the JSON data from the current line.
 | 
				
			||||||
 | 
							var transactionData struct {
 | 
				
			||||||
 | 
								Data struct {
 | 
				
			||||||
 | 
									StatementItem struct {
 | 
				
			||||||
 | 
										ID string `json:"id"`
 | 
				
			||||||
 | 
									} `json:"statementItem"`
 | 
				
			||||||
 | 
								} `json:"data"`
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := json.Unmarshal(scanner.Bytes(), &transactionData)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								// skip lines that are not valid JSON.
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// check if the transaction ID matches the given ID.
 | 
				
			||||||
 | 
							if transactionData.Data.StatementItem.ID == transactionID {
 | 
				
			||||||
 | 
								return true, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// check for any errors that occurred during scanning.
 | 
				
			||||||
 | 
						if err := scanner.Err(); err != nil {
 | 
				
			||||||
 | 
							return false, fmt.Errorf("error scanning log file: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// transaction ID not found in the log file.
 | 
				
			||||||
 | 
						return false, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,25 +1,26 @@
 | 
				
			|||||||
package config
 | 
					package config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Config struct {
 | 
					type Config struct {
 | 
				
			||||||
	Accounts         []ConfigAccount          `json:"accounts"`
 | 
						Accounts         []Account          `json:"accounts"`
 | 
				
			||||||
	TransactionTypes []ConfigTransactionTypes `json:"transaction_types"`
 | 
						TransactionTypes []TransactionTypes `json:"transaction_types"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ConfigAccount struct {
 | 
					type Account struct {
 | 
				
			||||||
	Firefly3Name string `json:"firefly3_name,omitempty"`
 | 
						Firefly3Name string `json:"firefly3_name,omitempty"`
 | 
				
			||||||
	MonobankId   string `json:"monobank_id,omitempty"`
 | 
						MonobankId   string `json:"monobank_id,omitempty"`
 | 
				
			||||||
	Currency     string `json:"currency,omitempty"`
 | 
						Currency     string `json:"currency,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ConfigTransactionTypes struct {
 | 
					type TransactionTypes struct {
 | 
				
			||||||
	Names           []string                `json:"names,omitempty"`
 | 
						Names           []string                `json:"names,omitempty"`
 | 
				
			||||||
	NamesRefund     []string                `json:"names_refund,omitempty"`
 | 
						NamesRefund     []string                `json:"names_refund,omitempty"`
 | 
				
			||||||
 | 
						NamesLooseMatch bool                    `json:"names_loose_match,omitempty"` // "name%" match
 | 
				
			||||||
	MccCodes        []int                   `json:"mcc_codes,omitempty"`
 | 
						MccCodes        []int                   `json:"mcc_codes,omitempty"`
 | 
				
			||||||
	Firefly3    ConfigTransactionTypeFirefly3 `json:"firefly3,omitempty"`
 | 
						Firefly3        TransactionTypeFirefly3 `json:"firefly3,omitempty"`
 | 
				
			||||||
	SumMax          int                     `json:"sum_max,omitempty"`
 | 
						SumMax          int                     `json:"sum_max,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ConfigTransactionTypeFirefly3 struct {
 | 
					type TransactionTypeFirefly3 struct {
 | 
				
			||||||
	Type                     string `json:"type,omitempty"`
 | 
						Type                     string `json:"type,omitempty"`
 | 
				
			||||||
	Destination              string `json:"destination,omitempty"`
 | 
						Destination              string `json:"destination,omitempty"`
 | 
				
			||||||
	Description              string `json:"description,omitempty"`
 | 
						Description              string `json:"description,omitempty"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,21 +1,21 @@
 | 
				
			|||||||
package config
 | 
					package config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Config) GetAccountByMonobankId(q string) ConfigAccount {
 | 
					func (c *Config) GetAccountByMonobankId(q string) Account {
 | 
				
			||||||
	for _, row := range c.Accounts {
 | 
						for _, row := range c.Accounts {
 | 
				
			||||||
		if row.MonobankId == q {
 | 
							if row.MonobankId == q {
 | 
				
			||||||
			return row
 | 
								return row
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ConfigAccount{}
 | 
						return Account{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Config) GetAccountByFirefly3Name(q string) ConfigAccount {
 | 
					func (c *Config) GetAccountByFirefly3Name(q string) Account {
 | 
				
			||||||
	for _, row := range c.Accounts {
 | 
						for _, row := range c.Accounts {
 | 
				
			||||||
		if row.Firefly3Name == q {
 | 
							if row.Firefly3Name == q {
 | 
				
			||||||
			return row
 | 
								return row
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ConfigAccount{}
 | 
						return Account{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user