Skip to content

Instantly share code, notes, and snippets.

@clochix
Last active May 29, 2021 16:43
Show Gist options
  • Save clochix/48a7537b248f4272fc2513cd9722817f to your computer and use it in GitHub Desktop.
Save clochix/48a7537b248f4272fc2513cd9722817f to your computer and use it in GitHub Desktop.
Export data from Cozy Bank
#!/usr/bin/env bash
#########
#
# Export bank operations
#
# Syntax: bankexport claude.mycozy.cloud
#
# Requirements:
# - curl
# - socat
# - jq
#
########
bankexport ()
(
server=''
token=''
verbose='-s'
#
# Check if required applications are available
#
if [ "$(type -t curl)" != "file" ]; then
echo "Please install curl"
return 1
fi
if [ "$(type -t jq)" != "file" ]; then
echo "Please install jq"
return 1
fi
if [ "$(type -t socat)" != "file" ]; then
echo "Please install socat"
return 1
fi
if [ "$#" != "1" ]; then
echo "Syntax bankexport server"
return 1
fi
#
# Step 1: register app and get token
#
server=$(echo "$1" | sed 's/https:\/\///g')
if [ "$server" = "" ]; then
echo "Usage: ${FUNCNAME[0]} URL"
return 1
fi
scope="io.cozy.bank.accounts:GET%20io.cozy.bank.operations:GET"
#echo "Getting token for $server with scope $scope"
registration=$(curl -s -X POST -H "Host: ${server}" -H "Content-Type: application/json" -H "Accept: application/json" -d '{"redirect_uris": ["http://localhost:8080"],"client_name": "cozycli","software_id": "cozycli"}' https://${server}/auth/register | jq ".server=\"${server}\"")
state="$(cat /proc/sys/kernel/random/uuid)"
clientid="$(echo "$registration" | jq -r '.client_id')"
clientsecret="$(echo "$registration" | jq -r '.client_secret')"
registrationtoken="$(echo "$registration" | jq -r '.registration_access_token')"
url="$(curl -s -L -w "%{url_effective}" -o /dev/null "https://${server}/auth/authorize?client_id={$clientid}&response_type=code&scope=${scope}&state=${state}&redirect_uri=http%3A%2F%2Flocalhost:8080")"
echo "Open this URL in your browser"
echo "$url"
answer=$(mktemp)
chmod 600 "$answer"
answer=$(socat -v TCP-LISTEN:8080,crlf,reuseaddr SYSTEM:'echo "OK"' 2>&1 | grep "^GET")
#nc -l -p 8080 -i 1 -c 'while read -r request remaining;do echo $request $remaining >> '${answer}';if [ "$remaining" = "" ];then break;fi;done;echo "HTTP/1.1 200 OK\n\nOK"';
IFS=";" read -r code state2<<< $(echo "$answer" | sed -E "s/^.*&code=([^&]*)&state=(.*) .*$/\1;\2/")
rm -f $answer
if [ "$state2" != "$state" ]; then
echo "Wrong state! Expected ${state}, got ${state2}"
fi
token=$(curl -s -X POST -H "Host: ${server}" -H "Content-Type: application/x-www-form-urlencoded" -H "Accept: application/json" -d "grant_type=authorization_code&code=${code}&client_id=${clientid}&client_secret=${clientsecret}" https://${server}/auth/access_token | jq -r '.access_token')
#
# Step 2: export the data
#
curl $verbose -H "Origin: https://${server}" -H "Authorization: Bearer ${token}" -H "Accept: application/json" "https://${server}/data/io.cozy.bank.accounts/_all_docs?include_docs=true" > bank_accounts.json
curl $verbose -H "Origin: https://${server}" -H "Authorization: Bearer ${token}" -H "Accept: application/json" "https://${server}/data/io.cozy.bank.operations/_all_docs?include_docs=true" > bank_operations.json
echo 'Compte;Établissement;Libellé du compte' > bank_accounts.csv
echo 'Compte;Date;Montant;Libellé de l’opération' > bank_operations.csv
jq -r '.rows[].doc | select(.institutionLabel) | [._id, .institutionLabel, .label] | join(";")' bank_accounts.json | sort >> bank_accounts.csv
jq -r '.rows[].doc | select(.amount) | [.account, .date, (.amount|tostring), .label] | join(";")' bank_operations.json | sort >> bank_operations.csv
join --header -t';' -j1 bank_accounts.csv bank_operations.csv > bank_data.csv
#
# Step 3: revoke the tocken
#
res=$(curl $verbose -H "Origin: https://${server}" -H "Authorization: Bearer ${registrationtoken}" -X DELETE "https://${server}/auth/register/${clientid}")
echo "$res"
)
@captain053
Copy link

Hello,

Merci pour ce script qui comble un vrai manque comme ça a été dit. De mon côté, je suis sur MacOS et j'utilise zsh donc j'ai du faire quelques ajustements pour qu'il fonctionne correctement, voici la liste :

Sur la vérification des dépendances, type avec zsh fonctionne différemment et ne dispose pas du paramètre -t, j'ai donc utilisé -w et modifié le test par "type -w {exec} != "exec: command". Exemple : if [ "$(type -w jq)" != "jq: command" ]; then

J'ai du modifier la variable state state="$(cat /proc/sys/kernel/random/uuid)" en state="$(uuidgen)"
car /proc/sys/kernel/random/uuid n'existe pas sous MacOS donc j'ai remplacé par uuidgen qui fait le job.

J'ai eu des erreurs sur la dernière commande join (ligne 81), sur les paramètres --header et -j qui n'existent pas chez moi. Du coup, j'ai modifié en : join -t';' -1 1 -2 1 bank_accounts.csv bank_operations.csv > bank_data.csv

J'ai aussi utilisé la méthode de @xavgra2 avec bankexport $1 à la fin

Et dernier point, plutôt que d'afficher l'url dans le terminal et de la copier/coller, j'ai modifié le script pour la lancer directement dans le navigateur par défaut avec un simple open $url.

Encore merci !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment