2

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
4
  • Your question would benefit from including a minimal repro of your issue. If you're getting a 200 on the POST then your webhook is being invoked when deployed to Cloud Run. A minimal repro would help explain your issue clearly. Commented May 26 at 20:56
  • @DazWilkin Would this equate to a summary at the top or bottom of my question where the issue is trimmed down to its bare necessities? Thank you for the comment. Commented May 28 at 6:10
  • There's an important difference between summarizing a problem (what you've done), showing your working (exact commands, output, logs etc.) which is better, and providing a minimal repro (best) so that others may perform the same steps to see the issue for themselves. Critically, you state that Cloud Logging is recording a 200 and that you believe the issues is "between Cloud Run and the webhook" but this is a contradiction; a 200 can only result when the code within a container (or a suitably configured liveness|readiness probe) returns a 200. Commented May 28 at 13:37
  • @DazWilkin That makes sense, thank you for clarifying as I was unfamiliar with this term until now. I will go ahead and include a minimal repro in my question that lays out all of the steps so others can see the issue for themselves. I appreciate your support :) Commented May 29 at 9:26

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.