The script
#!/usr/bin/env bash
# /usr/local/bin/send-nightly-report
set -euo pipefail
export YUNGLE_API_KEY="$(cat /etc/yungle/api-key)" # readable by this user only
REPORT="/var/reports/$(date +%F).xlsx"
LOG=/var/log/yungle-reports.jsonl
/usr/local/bin/generate-report > "$REPORT"
yungle send "$REPORT" \
--to finance@example.com \
--title "Nightly report $(date +%F)" \
--expires 7 \
--json \
| jq -c --arg file "$REPORT" '{at: now | todate, file: $file, id, url, notified}' \
>> "$LOG"And the crontab entry, at six every morning:
0 6 * * * /usr/local/bin/send-nightly-report 2>> /var/log/yungle-reports.errWhat each part is for
- A key file, not the crontab — cron environments are easy to leak through
psand backups. Give the key onlytransfers:writeandtransfers:read. --expires 7— a daily report does not need to outlive the week. The value is clamped to your plan’s maximum rather than rejected.- A JSON Lines log— one line per send with the transfer id and link. When someone asks “did Tuesday’s go out?”, the answer is one
grepaway. set -euo pipefail— if the report fails to generate, nothing is sent. An empty report delivered on time is worse than a late one.
If the upload is interrupted
Run the same command again. The CLI remembers an interrupted upload of the same files to the same destination and continues it instead of starting over. For a cron job, the next night’s run is a new report and a new transfer, so there is nothing to clean up.
Checking whether the report was opened is a poll against
GET /transfers/{id}/downloads using the id from the log — there are no webhooks yet. See Transfers.