I am trying to create a demo webserver that returns a TwiML Say block with custom text inside it based on parameters provided with the URL (Yes, POSTing would be better, but I'm not quite sure how to do that). It would work a lot like https://www.twilio.com/labs/twimlets/message except I want to write my own code so I can add more customizations.
I have started by building off of the Weather by Phone demo because it contains customized text inside of xml.
I have created my own google appengine called gracklevoice, and I got the weatherbyphone example working. Now, I'm having trouble when I try to simplify it. My code looks like this:
import os
import wsgiref.handlers
from google.appengine.ext.webapp import template
from google.appengine.ext import webapp
BASE_URL = "http://gracklevoice.appspot.com/"
def xml_response(handler, page, templatevalues=None):
"""
Renders an XML response using a provided template page and values
"""
path = os.path.join(os.path.dirname(__file__), page)
handler.response.headers["Content-Type"] = "text/xml"
handler.response.out.write(template.render(path, templatevalues))
class GracklePage(webapp.RequestHandler):
def get(self):
self.post()
def post(self):
xml_response(self, 'notification.xml')
def main():
application = webapp.WSGIApplication([ \
('/', GracklePage)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
main()
There is the yaml file too:
application: gracklevoice
version: 1
runtime: python27
api_version: 1
threadsafe: no
handlers:
- url: /.*
script: gracklevoice.py
And notification.xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say voice="alice" language="en-US">
This is a message from Grackle.
</Say>
</Response>
This seems it should be really simple, but when my client app sets the call url to http://gracklevoice.appspot.com/ I get an error instead of the voice message: "We are sorry. an application error has occurred. Goodbye." What am I missing?
Looking in the appEngine logs (which are limited in length, welp), I see:
2013-11-18 14:45:09.781
Traceback (most recent call last):
E 2013-11-18 14:45:09.781
File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/wsgiref/handlers.py", line 86, in run
E 2013-11-18 14:45:09.781
self.finish_response()
E 2013-11-18 14:45:09.781
File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/wsgiref/handlers.py", line 128, in finish_response
E 2013-11-18 14:45:09.781
self.write(data)
E 2013-11-18 14:45:09.781
File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/wsgiref/handlers.py", line 204, in write
E 2013-11-18 14:45:09.781
assert type(data) is StringType,"write() argument must be string"
E 2013-11-18 14:45:09.781
AssertionError: write() argument must be string