0

I am new to python and coding in general and I have been tasked with creating a Google Chat Bot that will send an alert in a Google Chat Room when our hardware monitoring service detects an issue. The general premise of the project is that the monitoring service takes my webhook URL and uses it to give me the JSON and I have to get that to the Google Chat in a readable and timely fashion.

This is what I have so far :

from flask import Flask, request, abort, Response
from json import dumps
from httplib2 import Http


app = Flask(__name__)

def main(botmsg):
    url = #placeholder for Google Chat Webhook URL#
    bot_message = {
        'text' : botmsg}
        
    message_headers = {'Content-Type': 'application/json; charset=UTF-8'}

    http_obj = Http()

    Response = http_obj.request(
        uri=url,
        method='post',
        headers=message_headers,
        body=dumps(bot_message),
    )
    print(Response)

@app.route('/', methods=['POST'])
def respond():
    if request.method == 'POST':
        print(request.json)
        return Response(status=200)

    else: abort(400)

if __name__ == '__main__':
    app.run()

At first I had this exact file running locally. I would spin up my flask server but I could never get the main() to ping the Google Chat when I triggered it with a local webhook. Alone, the main function is working but I couldn't call the function in response to receiving the webhook. Now I am struggling with the same issue with this code in a Google Function pinging it using Github.

I get this error in my function logs when I ping it with the webhook:

"TypeError: Object of type Request is not JSON serializable"

I have been scraping the internet for weeks on how to do this to no avail so if anyone could give me some pointers it would be greatly appreciated!

  • As a test, print out the `request.mimetype` and see what it gives you. I suspect it's not application/json which is why it's not json serializable. Your outgoing response is, but what you get back might not be? – Gabe Weiss Jun 29 '21 at 16:57
  • Oh also: ```Response = http_obj.request( uri=url, method='post', headers=message_headers, body=dumps(bot_message), )``` might be problematic. `Response` is one of your imports, and you're assigning the request to a variable with the same name. Are you sure that's behaving how you want? – Gabe Weiss Jun 29 '21 at 18:04
  • @Gabe Weiss Thanks for the quick response! I have tried everything I can think of to print the `request.mimetype` but I couldn't figure it out. Also I have the incoming webhook set to application/json on Github if that's what you're looking for. And as for the Response/request variable bit, the main function works as a stand alone so I don't suspect it is an issue. – elitheintern Jun 30 '21 at 13:22
  • Is your `respond()` method firing? That print() statement there should be showing up in the Cloud Logging. If you go to the Cloud Functions list, in the 3 dot menu on the far right in the list one of the menu options is "View logs" if you click it, it'll take you to the logging page filtered to your function's logs. If that `respond()` is firing, you should see something in the logs. – Gabe Weiss Jun 30 '21 at 17:41
  • @Gabe Weiss Good catch! I don't see anything in the logs so that must be the issue. Also I don't quite understand how the HTML trigger works. Does it just run the code? What is the significance of the entry point in this case? And how should I call the `respond()`? Once again thanks so much for your help! – elitheintern Jul 01 '21 at 12:58
  • Are you seeing ANYTHING happening in the logs for the function? Are you calling it at all? This might be a whole other problem. :D My suggestion would be, to get a feel for how things work to go through some of the Cloud Function tutorials and quickstarts. Functions might not be what you want. If you want to run a flask app, Cloud Run is likely a better option since it's more persistent than Functions. Check out this SO answer: https://stackoverflow.com/questions/62654837/python-flask-app-using-google-cloud-functions That might help. Flask in Functions is...more complicated than in Run. – Gabe Weiss Jul 01 '21 at 18:50
  • Another way to think about it, is Functions IS the flask app...and you create individual functions for each callback in the flask app, which might not be what you want or need. So e.g. that respond() call would be its own function entirely on its own. – Gabe Weiss Jul 01 '21 at 18:51

0 Answers0