Add Postmark test command for container health checks
Support docker exec and a secured /test-email endpoint to verify email delivery before wiring up the BTCPay webhook. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
118b596631
commit
02d5a5a342
@ -17,3 +17,8 @@ POSTMARK_API_KEY=your_postmark_server_token
|
|||||||
BTCPAY_URL=https://payment.nxtgroup.org
|
BTCPAY_URL=https://payment.nxtgroup.org
|
||||||
FROM_EMAIL=billing@nxtgroup.org
|
FROM_EMAIL=billing@nxtgroup.org
|
||||||
BCC_EMAIL=admin@nxtgroup.org,finance@nxtgroup.org
|
BCC_EMAIL=admin@nxtgroup.org,finance@nxtgroup.org
|
||||||
|
|
||||||
|
# Test Postmark after deploy (docker exec or Portainer console):
|
||||||
|
# python app.py test-email you@example.com
|
||||||
|
# Or from host:
|
||||||
|
# curl -X POST "http://localhost:5000/test-email?token=YOUR_WEBHOOK_SECRET&to=you@example.com"
|
||||||
|
|||||||
58
app.py
58
app.py
@ -58,6 +58,9 @@ def get_html_template(order_id, invoice_id, amount, currency, amount_paid, remai
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def send_postmark_email(to_email, subject, html_body):
|
def send_postmark_email(to_email, subject, html_body):
|
||||||
|
if not POSTMARK_API_KEY:
|
||||||
|
return {"ok": False, "status_code": None, "error": "POSTMARK_API_KEY is not set"}
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"Accept": "application/json",
|
"Accept": "application/json",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@ -71,9 +74,18 @@ def send_postmark_email(to_email, subject, html_body):
|
|||||||
"HtmlBody": html_body,
|
"HtmlBody": html_body,
|
||||||
"MessageStream": "outbound"
|
"MessageStream": "outbound"
|
||||||
}
|
}
|
||||||
|
|
||||||
response = requests.post("https://api.postmarkapp.com/email", json=payload, headers=headers)
|
response = requests.post("https://api.postmarkapp.com/email", json=payload, headers=headers)
|
||||||
return response.status_code == 200
|
result = {"ok": response.status_code == 200, "status_code": response.status_code}
|
||||||
|
if not result["ok"]:
|
||||||
|
result["error"] = response.text
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def send_test_email(to_email):
|
||||||
|
html_body = get_html_template("TEST-001", "test-invoice-id", 100.0, "USD", 50.0, 50.0)
|
||||||
|
subject = "BTCPay Mailer test email"
|
||||||
|
return send_postmark_email(to_email, subject, html_body)
|
||||||
|
|
||||||
@app.route('/btcpay-webhook', methods=['POST'])
|
@app.route('/btcpay-webhook', methods=['POST'])
|
||||||
def btcpay_webhook():
|
def btcpay_webhook():
|
||||||
@ -120,14 +132,46 @@ def btcpay_webhook():
|
|||||||
html_body = get_html_template(order_id, invoice_id, amount, currency, amount_paid, remaining)
|
html_body = get_html_template(order_id, invoice_id, amount, currency, amount_paid, remaining)
|
||||||
subject = f"Action Required: Partial payment received for Order #{order_id}"
|
subject = f"Action Required: Partial payment received for Order #{order_id}"
|
||||||
|
|
||||||
email_sent = send_postmark_email(buyer_email, subject, html_body)
|
result = send_postmark_email(buyer_email, subject, html_body)
|
||||||
|
|
||||||
if email_sent:
|
if result["ok"]:
|
||||||
return jsonify({"status": "success", "message": "Partial payment email sent"}), 200
|
return jsonify({"status": "success", "message": "Partial payment email sent"}), 200
|
||||||
else:
|
return jsonify({"error": "Failed to send email via Postmark", "details": result}), 500
|
||||||
return jsonify({"error": "Failed to send email via Postmark"}), 500
|
|
||||||
|
|
||||||
return jsonify({"status": "ignored", "reason": "Payment meets total or invoice not in New state"}), 200
|
return jsonify({"status": "ignored", "reason": "Payment meets total or invoice not in New state"}), 200
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/test-email', methods=['POST'])
|
||||||
|
def test_email():
|
||||||
|
token = request.args.get('token')
|
||||||
|
if token != WEBHOOK_SECRET:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
|
|
||||||
|
to_email = request.args.get('to') or request.json.get('to') if request.is_json else None
|
||||||
|
if not to_email:
|
||||||
|
return jsonify({"error": "Missing 'to' email address"}), 400
|
||||||
|
|
||||||
|
result = send_test_email(to_email)
|
||||||
|
if result["ok"]:
|
||||||
|
return jsonify({
|
||||||
|
"status": "success",
|
||||||
|
"message": f"Test email sent to {to_email}",
|
||||||
|
"from": FROM_EMAIL,
|
||||||
|
"bcc": BCC_EMAIL,
|
||||||
|
}), 200
|
||||||
|
return jsonify({"error": "Failed to send test email via Postmark", "details": result}), 500
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if len(sys.argv) >= 3 and sys.argv[1] == 'test-email':
|
||||||
|
to = sys.argv[2]
|
||||||
|
outcome = send_test_email(to)
|
||||||
|
if outcome["ok"]:
|
||||||
|
print(f"OK: test email sent to {to} (from {FROM_EMAIL}, bcc {BCC_EMAIL})")
|
||||||
|
sys.exit(0)
|
||||||
|
print(f"FAIL: {outcome}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
app.run(host='0.0.0.0', port=5000)
|
app.run(host='0.0.0.0', port=5000)
|
||||||
Loading…
Reference in New Issue
Block a user