(ns auto-ap.plaid.core (:require [auto-ap.logging :as alog] [auto-ap.time :as atime] [cemerick.url :as url] [clj-http.client :as client] [clojure.data.json :as json] [config.core :as cfg :refer [env]] [slingshot.slingshot :refer [try+]])) (def base-url (-> env :plaid :base-url)) (def client-id (-> env :plaid :client-id)) (def secret-key (-> env :plaid :secret-key)) (defn get-link-token [client-code] (-> (client/post (str base-url "/link/token/create") {:as :json :headers {"Content-Type" "application/json"} :body (json/write-str {"client_id" client-id "secret" secret-key "client_name" "Integreat Consulting" "country_codes" ["US"] "language" "en" "user" {"client_user_id" client-code} "products" ["transactions"]})}) :body :link_token)) (defn get-relink-token [client-code access-token] (-> (client/post (str base-url "/link/token/create") {:as :json :headers {"Content-Type" "application/json"} :body (json/write-str {"client_id" client-id "secret" secret-key "client_name" "Integreat Consulting" "access_token" access-token "country_codes" ["US"] "language" "en" "user" {"client_user_id" client-code}})}) :body :link_token)) (defn exchange-public-token [public-token _] (-> (client/post (str base-url "/item/public_token/exchange") {:as :json :headers {"Content-Type" "application/json"} :body (json/write-str {"client_id" client-id "secret" secret-key "public_token" public-token})}) :body)) (defn get-item [access-token] (try+ (-> (client/post (str base-url "/item/get") {:as :json :headers {"Content-Type" "application/json"} :body (json/write-str {"client_id" client-id "secret" secret-key "access_token" access-token})}) :body) (catch [:status 400] x (let [json (try (json/read-str (:body x)) (catch Exception _ {}))] (throw (ex-info (or (get json "error_message") (get json "display_message") (.getMessage (:throwable &throw-context))) json)))))) (defn get-accounts [access-token] (try+ (-> (client/post (str base-url "/accounts/get") {:as :json :headers {"Content-Type" "application/json"} :body (json/write-str {"client_id" client-id "secret" secret-key "access_token" access-token})}) :body) (catch [:status 400] x (let [json (try (json/read-str (:body x)) (catch Exception _ {}))] (throw (ex-info (or (get json "error_message") (get json "display_message") (.getMessage (:throwable &throw-context))) json)))))) (defn get-balance [access-token] (-> (client/post (str base-url "/accounts/balance/get") {:as :json :headers {"Content-Type" "application/json"} :body (json/write-str {"access_token" access-token "secret" secret-key "client_id" client-id})}) :body)) (defn get-transactions [access-token account-id start end] (alog/info ::searching :start (str start) :end (str end) :acct (str account-id)) (try+ (-> (client/post (str base-url "/transactions/get") {:as :json :headers {"Content-Type" "application/json"} :body (json/write-str {"client_id" client-id "secret" secret-key "access_token" access-token "start_date" (atime/unparse start atime/iso-date) "end_date" (atime/unparse end atime/iso-date) "options" {"account_ids" [account-id] "count" 500}})}) :body) (catch [:status 400] x (let [json (try (json/read-str (:body x)) (catch Exception _ {}))] (throw (ex-info (or (get json "error_message") (get json "display_message") (.getMessage (:throwable &throw-context))) json)))))) (comment (require '[datomic.api :as dc]) (require '[auto-ap.datomic :refer [conn]]) (doto (dc/q '[:find (pull ?ba [{:bank-account/plaid-account [* {:plaid-item/_accounts [*]}]}]) :in $ ?ba] (dc/db conn) [:bank-account/code "NGHW-CB5029"]) clojure.pprint/pprint) (require 'auto-ap.time-reader) (clojure.pprint/pprint (get-transactions "access-production-c0e322fa-f33d-4806-bc42-5fc883fb1ba4" "VZ8Y1azZMdhoYo9MQABrfpgz4jm4kPtakyxN5" #clj-time/date-time "2024-03-15" #clj-time/date-time "2024-03-30")) (clojure.pprint/pprint (get-accounts "access-production-c0e322fa-f33d-4806-bc42-5fc883fb1ba4")))