I've been following this tutorial in order to set up a lambda function that replies to incoming texts from a Twilio webhook. The function seems to be working fine and receiving the text data, but when it passes the TwiML back to Twilio there's some kind of formatting issue. I'm getting a 12200 - Schema validation warning in the Twilio error log but I can't for the life of me find the issue with the TwiML. The message says:
WARN "Content is not allowed in prolog." at line 1, cols 1.
I've set up the API Gateway with the proper settings as stated in the tutorial. The Integration Request mapping template is set to application/x-www-form-urlencoded and the Integration Response and Method Response templates are set to application/xml.
My lambda function is:
def lambda_handler(event, context):
return '<?xml version="1.0" encoding="UTF-8"?><Response><Message><Body>Sorry, the command is invalid.</Body></Message></Response>'
This is the response I get when I send a request from Postman. There is a quotation and a newline character before the <?xml which appears to be the problem but as you can see in the lambda_handler() above, I don't believe I'm returning any quotations or \n.
"
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<Response>
<Message>
<Body>Sorry, the command is invalid.</Body>
</Message>
</Response>"
Any help with returning XML in python or setting up the Lambda API Gateway would be appreciated as it appears that's where the problem lies.
So it turns out, it was an issue with the API Gateway after all. I had it set up properly, but didn't deploy it correctly so all the changes I was making were not being implemented. Make sure your API Gateway is deployed so your mapping templates actually take effect!
Related
I am pretty sure I am using exactly the same code in the following two cases, as I tested it on Postman first.
The first time I tried to create a task from Postman, it has no issue.
The next time I tried to do the same from my NodeJS server, and it shows this error. I tried the client SDK package and manually calling through Axios, both are not working and throwing the same error.
Is the Asana API not callable from NodeJS server?
It turns out the "Headers" does not indicate the Headers sent with the request, but the "Headers" HTML Element inside the rich text field. Ensure there's no h1-h6 element in your html_notes can solve this issue.
I noticed the Direct Line request url is like this: https://localhost:8011/api/ in the documention. What should replace it with?
I have deployed a todoBot example project from botbuilder Examples folder. And I have created a bot in My bots section, the ending point is: http://www.bigluntan.com:3978/api/messages. I have tested in Test connection to your bot section, it is working when I type something and send it. Right now, I want to give Direct Line a try. So I added Direct Line to Channels. But the most confused part is, how do I call this Direct Line api, cause the ending point is different than my bot's ending point.
The base URL is https://directline.botframework.com, so for instance, the POST request to get a new conversationId should be https://directline.botframework.com/api/conversations/
The request headers should include the Content-Type and also the following:
Authorization: BotConnector < Your secret >
where your secret is the code which was created when you created a Direct Line channel for your registered Bot (see image below). e.g.
Content-Type: application/json; charset=utf-8
Authorization: BotConnector pB7INWcXQjA.cwA.RF4.cglOUNHUOzWVv0Rlk3ovFNhtp1JPz1Zx9jmu8vX7zXs
Once you get a conversationId, you can POST a message using the URL https://directline.botframework.com/api/conversations/< conversationId >/messages
The body of the request should include the message text. You will not get the reply in the POST response. Instead, you need to get it by sending a GET to
https://directline.botframework.com/api/conversations/< conversationId >/messages. From there, you can get the "from" value in your first message, and use it in subsequent calls to the same conversation (otherwise the bot will not recognise the state, and just keep repeating the first reply message), e.g.
{
text: "yes",
from: "EQxvIzZOspA"
}
I found this out by trial and error. If you want to use the direct line api you should try https://directline.botframework.com
as the base URL
I am trying to make a simple REST call to the Set Blob Properties API (http://msdn.microsoft.com/en-us/library/windowsazure/hh452235) to just turn off/on logging. I have gotten the REST API call to successfully work for retrieving Blob Properties, so I know my hashing algorithms, headers-setting, and Authentication signature creation works, but I can't seem to get it working on the Set Properties side of things. I keep getting an error on the Authentication Header, so I know I'm not doing something right there.
I have copied below what is being created and eventually hashed and put into the auth header string. The online documentation (http://msdn.microsoft.com/en-us/library/windowsazure/dd179428) does not really help in determining which of these fields are absolutely required for this particular type of Blob request, so I've tried filling most of them in, but I don't seem to get a difference response regardless of what I fill in. I've also tried the Shared Key Lite authentication, which would be preferred since it's much more lightweight, but that doesn't seem to work either when I fill in all 5 of those fields.
Shared Key Authentication for Blob Services:
PUT\n
\n
\n
130\n
(MD5_CONTENT_HASH)
\n
\n
\n
\n
\n
\n
\n
x-ms-date:Tue, 19 Jun 2012 19:53:58 GMT\n
x-ms-version:2009-09-19\n
/(MY_ACCOUNT)/\n
comp:properties\n
restype:service
Is there anything obvious I'm missing here? The values (MD5_CONTENT_HASH) and (MY_ACCOUNT) are of course filled in when I make the request call, and the similar request call to "GET" the properties works fine when I send it. The only difference between that one and this is that I'm sending the MD5_content, along with the content-length. I may be missing something obvious here, though.
Any advice would be greatly appreciated! Thanks in advance.
-Vincent
EDIT MORE INFO:
Programming Language I'm using: Objective-C (iOS iPhone)
I'm also using ASIHTTPRequest to make the request. I simply define the request, setRequestMethod:#"PUT", then I create the request body and convert it to NSData to calculate the length. I attach the request-body data via the appendPostData method to the request. I then build the auth string above, hash the whole thing, and attach it to the request as a header called "Authorization".
Request Body String I'm using:
<?xml version=\"1.0\" encoding=\"utf-8\"?><StorageServiceProperties><Logging><Version>1</Version></Logging></StorageServiceProperties>
I know this is an incomplete request body, but I was planning on waiting for it to give a failure on "missing request body element" or something similar, until I proceeded on creating the full XML there. (could that be my issue?)
Error I get from the server:
<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:accc4fac-2701-409c-b1a7-b3a528ce7e8a
Time:2012-06-20T14:36:50.5313236Z</Message><AuthenticationErrorDetail>The MAC signature found in the HTTP request '(MY_HASH)' is not the same as any computed signature. Server used following string to sign: 'POST
130
x-ms-date:Wed, 20 Jun 2012 14:36:50 GMT
x-ms-version:2009-09-19
/(MY_ACCOUNT)/
comp:properties
restype:service'.</AuthenticationErrorDetail></Error>
What's odd is that the error I get back from the server seems to look like that, no matter how many parameters I pass into the Authentication signature.
Thanks for any help you can offer!
Comparing your signed string and the error message indicates that you're sending a POST request but signing as though you're sending a PUT.
I am mocking my web service using soapUI.
Now, I also want to test fault. For this, the mock service (=soapUI) should return a HTTP 500.
Does anyone know, how soapUI can do this?
thanks
This can be achieved with the following Groovy code:
mockRequest.getHttpResponse().sendError(500)
Create a mock service.
Create a new mock response.
Open the mock response editor (by double clicking it) and click on the exclamation mark symbol which creates a SOAP Fault response.
If you look at the RAW code of the answer, you see a 500 error code. (HTTP/1.1 500 Internal Server Error)
Btw if you have created two reponses, a successful and a fault response, then when using the mock service service, SOAPUI alternates between the two responses.
Right Click on the MockResponse > Show MockResponse Editor Enter.
Look at MockResponse Properties on the left hand side, bottom
Scroll down to search for "Response HTTP-Status" edit the value to 500.
I'm developing a Web site that, amongst other things, provides blogging via Metaweblog API. I've gotten the API working quite well with several blog clients, but Windows Live Writer is killing me.
I've done a network trace to capture the actual back-and-forth traffic. Here's the results:
WLW asks for my blog URL, user name, and password. The URL is /item/list/type/blog/user/1/bloguser/1, and I provide this.
I see WLW make an HTTP request for that URL. It gets a response. That response includes both RSD and wlwmanifest link tags.
The next request from WLW is for /mwapi/rsd/bloguser/1, which is the correct URL.
The response is the MetaWeblog RSD response:
<?xml version="1.0" encoding="UTF-8"?>
<rsd version="1.0" xmlns="http://archipelago.phrasewise.com/rsd">
<service>
<engineName>Cahoots2</engineName>
<engineLink>http://sourceforge.net/projects/cahoots/</engineLink>
<homePageLink>http://10.0.1.39:8888</homePageLink>
<apis>
<api name="MetaWeblog" blogID="1" preferred="true" apiLink="http://10.0.1.39:8888/mwapi/index" />
</apis>
</service>
</rsd>
The next request from WLW is to /mwapi/index. This is the method call to blogger.getUsersBlogs. The request is:
.<?xml version="1.0" encoding="utf-8"?>..
<methodCall>.. <methodName>blogger.getUsersBlogs</methodName>..
<params>.. <param>.. <value>..
<string>ffffffabffffffce6dffffff93ffffffac29ffffffc9fffffff826ffffffdeffffffc9ffffffe43c0b763036ffffffa0fffffff3ffffffa963377716</string>..
</value>..
</param>..
<param>..
<value>..
<string>CommunityAdmin</string>..
</value>..
</param>..
<param>..
<value>..
<string>password</string>..
</value>..
</param>.. </params>..</methodCall>
Forgive the periods; those are carriage returns. I'm grabbing this from a network trace.
The response from the server is also in XML:
.<?xml version="1.0" encoding="UTF-8"?>.<methodResponse><params><param><value>
<struct><member><name>blogid</name><value><int>1</int>
</value></member><member><name>url</name><value>
<string>http://10.0.1.39:8888/item/list/type/blog/user/1/bloguser/1</string>
</value></member><member><name>blogname</name><value>
<string>CommunityAdmin # Cahoots!</string></value></member></struct></value>
</param></params></methodResponse>.
This looks correct to me. The BlogID is correct, the URL is correct, and the blog name is correct.
WLW then repeats the original getUsersBlogs method call. It gets an identical response.
WLW then displays, "A successful connection was made to your account however the server reported that you do not currently have an active blog. Please ensure that your account with this provider is current before proceeding."
WLW has made no further HTTP requests beyond the ones I've described here.
Any clues whatsoever what I'm doing wrong? I've ensured that a wlwmanifest.xml file is available, and in fact any request for wlwmanifest.xml (e.g., /this/is/not/it/wlwmanifest.xml) will still return the correct file.
EDIT: I realized I wasn't returning an array from my getUsersBlogs method. When I changed that, the HTTP response from the method call was:
.<?xml version="1.0" encoding="UTF-8"?>.<methodResponse><params><param><value><array><data><value>
<struct><member><name>blogid</name><value><int>1</int></value></member>
<member><name>url</name><value>
<string>http://10.0.1.39:8888/item/list/type/blog/user/1/bloguser/1</string>
</value></member><member><name>blogname</name><value>
<string>CommunityAdmin # Cahoots!</string></value></member></struct></value>
</data></array></value></param></params></methodResponse>.
This looks identical to what's described at http://msdn.microsoft.com/en-us/library/aa905665.aspx as a sample response. But, WLW displayed an error - "Object reference not set to an instance of an object." Again, the actual response data doesn't include the periods - that's just how Network Monitor represents carriage returns.
I've done test calls from a test harness and it's working fine with identical responses. And, as I said, it's working with other blogging clients. Help.
WLW, it seems, is VERY picky about the MWA implementation. I was not capitalizing one of the method names correctly.