My objective is to develop Python scripts that read the current messages in the client's Gmail inbox, and read the live messages coming through the client's Gmail inbox. This data will eventually by analyzed by another script, eventually categorized for the purpose of protecting the client against malicious emails.
I have two scripts, being PythonFileEMP.py and webhook.py. PythonFileEMP.py deals with the historical messages in the inbox, while webhook.py deals with the live messages coming through the inbox while it is running.
The issue is that no live test emails are coming through while webhook.py is running, but PythonFileEMP.py is reading all of the 5 recent historical emails successfully.
Cloud Run logs show POST 200 success when live test emails are sent (the test emails are logged correctly). Also, when testing the webhook locally through a curl command in PowerShell, the webhook is successfully triggered. For some reason the test emails just aren't visible in my webhook logging/output in pycharm.
Info that might be useful:
- The webhook is deployed on Google Cloud Run.
- '--allow-unauthenticated' was set during deployment.
- The push subscription is configured to point to https://webhook-service-xxxx.australia-southeast1.run.app/webhook.
- The webhook is containerized using Docker with a Dockerfile and requirements.txt.
- Flask is running on host=0.0.0.0 and port=8080.
Why is this happening and how do you fix this? Thanks in advance :)
Here I have included a minimal repro of script. This script focuses on the main functionality required to receive and log Gmail push notifications through Google Cloud Pub/Sub. This reduced version omits authentication flows, token management, and external dependencies.
from flask import Flask, request, jsonify
import base64
import logging
import json
app = Flask(__name__)
logging.basicConfig(level=logging.DEBUG)
@app.route('/webhook', methods=['POST'])
def gmail_webhook():
try:
# Log raw request data for debugging
logging.debug(f"Headers: {dict(request.headers)}")
logging.debug(f"Body: {request.data.decode('utf-8')}")
# Parse JSON payload
data = request.get_json(silent=True)
if not isinstance(data, dict):
logging.error("Invalid JSON format received.")
return jsonify({"error": "Invalid JSON format received."}), 400
# Extract and decode the message data
message_data = data.get("message", {}).get("data")
if message_data:
decoded_bytes = base64.urlsafe_b64decode(message_data)
decoded_str = decoded_bytes.decode("utf-8")
logging.info(f"Decoded message: {decoded_str}")
else:
logging.warning("No message data found in the request.")
return jsonify({"error": "No message data found."}), 400
return jsonify({"status": "Success", "message": decoded_str}), 200
except Exception as e:
logging.error(f"Unhandled error: {e}")
return jsonify({"error": str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
Output:
- Serving Flask app 'abc'
- Debug mode: on INFO:werkzeug:WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
- Running on all addresses (0.0.0.0)
- Running on http://127.0.0.1:8080
- Running on http://192.168.231.242:8080 INFO:werkzeug:Press CTRL+C to quit INFO:werkzeug: * Restarting with stat WARNING:werkzeug: * Debugger is active! INFO:werkzeug: * Debugger PIN: 142-623-917
POSTthen your webhook is being invoked when deployed to Cloud Run. A minimal repro would help explain your issue clearly.