From where do I find the dialogflow request payload? - heroku

I have a flask based service hosted in Heroku. The endpoint of which is given as a fulfillment in dialogflow. Now I cannot figure out how to capture the request payload which dialogflow triggers everytime I request something.
I tried capturing and logging the same in heroku itself but that does not seem to be working.
The service code is as follows:
#app.route('/date/currentdate/<date>', methods = ['POST'])
def postJsonHandler():
print (request.is_json)
content = request.get_json()
logging.warning(content)
return 'JSON posted'
The json which i am getting is:
WARNING:root:{'responseId': 'c5115583-e9c5-497a-8a50-1ea07ab02dba-baaf0c1f', 'queryResult': {'queryText': 'send me the asap for 4568999', 'parameters': {'Dashboard': 'ASAP', 'number': 4568999.0}, 'allRequiredParamsPresent': True, 'fulfillmentMessages': [{'text': {'text': ['Hi I can definitely help you out with that.']}, 'platform': 'SKYPE'}, {'text': {'text': ['']}}], 'intent': {'name': 'replaced this', 'displayName': 'ASAP Dashboard'}, 'intentDetectionConfidence': 0.7012109, 'languageCode': 'en'}, 'originalDetectIntentRequest': {'payload': {}}, 'session': 'replaced this'}

There is diagnostic info section in the agent section which has got all the info related to request and response, it is sometimes not visible if there is pop up on the top of page, in my case it was the v2 getting outdated banner; on closing it the diagnostic info became visible.

Related

AWS API Gateway not passing Endpoint request header even after transformation

I'm trying to pass an Authorization header through API Gateway into a Lambda function. I can see the key in the gateway logs. But, even after I transform the input with the standard script (see below), the Authorization head still doesn't make it to the Lambda function.
Any suggestions on what I'm missing?
API Log excerpt
Endpoint request headers:
{
X-Amz-Date=20220419T143450Z,
x-amzn-apigateway-api-id=?????????,
Accept=application/x-www-form-urlencoded,
User-Agent=AmazonAPIGateway_hhompg4,
Host=lambda.us-east-1.amazonaws.com,
X-Amz-Content-Sha256=??????????????????????????????????????????????????,
X-Amzn-Trace-Id=Root=1-????????-???????????????????,
x-amzn-lambda-integration-tag=abcd-4e32-1234-???????????????, Authorization=*********************************************************************************************************************************************************************************************************************************************************************************************************************************************70cc,
X-Amz-Source-Arn=arn:aws:execute-api:us-east-1:-----------------:asfd/test/POST/,
X-Amz-Security-Token=---------------------------------------// [TRUNCATED]
Method Execution / - POST - Integration Request Transformation script:
{
"method": "$context.httpMethod",
"body" : $input.json('$'),
"headers": {
#foreach($param in $input.params().header.keySet())
"$param": "$util.escapeJavaScript($input.params().header.get($param))"
#if($foreach.hasNext),#end
#end
}
}
event keys arriving to lambda function:
2022-04-19T14:29:34.457Z INFO Object.keys(event) [
'resource',
'path',
'httpMethod',
'headers',
'multiValueHeaders',
'queryStringParameters',
'multiValueQueryStringParameters',
'pathParameters',
'stageVariables',
'requestContext',
'body',
'isBase64Encoded'
]
Object.keys(event.headers)
[
'accept',
'accept-encoding',
'accept-language',
'cache-control',
'content-type',
'Host',
'origin',
'referer',
'sec-ch-ua',
'sec-ch-ua-mobile',
'sec-ch-ua-platform',
'sec-fetch-dest',
'sec-fetch-mode',
'sec-fetch-site',
'sec-fetch-user',
'upgrade-insecure-requests',
'User-Agent',
'X-Amzn-Trace-Id',
'X-Forwarded-For',
'X-Forwarded-Port',
'X-Forwarded-Proto'
]
I was able to see my request header (Authorization) in request headers but the same was not visible in the endpoint request headers. Found that you have to enable the 'Use HTTP Proxy integration' option while setting up the integration point.

Couldn't make new request verification for Slack API

I'm trying the new request verification process for Slack API on AWS Lambda but I can't produce a valid signature from a request.
The example showed in https://api.slack.com/docs/verifying-requests-from-slack is for a slash command but I'm using for an event subscription, especially, a subscription to a bot event (app_mention). Does the new process support event subscriptions as well?
If so, am I missing something?
Mapping template for Integration request in API Gateway. I can't get a raw request as the slack documentation says but did my best like this:
{
"body" : $input.body,
"headers": {
#foreach($param in $input.params().header.keySet())
"$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end
#end
}
}
My function for verification:
def is_valid_request(headers, body):
logger.info(f"DECODED_SECRET: {DECODED_SECRET}")
logger.info(f"DECRYPTED_SECRET: {DECRYPTED_SECRET}")
timestamp = headers.get(REQ_KEYS['timestamp'])
logger.info(f"timestamp: {timestamp}")
encoded_body = urlencode(body)
logger.info(f"encoded_body: {encoded_body}")
base_str = f"{SLACK_API_VER}:{timestamp}:{encoded_body}"
logger.info(f"base_str: {base_str}")
base_b = bytes(base_str, 'utf-8')
dgst_str = hmac.new(DECRYPTED_SECRET, base_b, digestmod=sha256).hexdigest()
sig_str = f"{SLACK_API_VER}={dgst_str}"
logger.info(f"signature: {sig_str}")
req_sig = headers.get(REQ_KEYS['sig'])
logger.info(f"req_sig: {req_sig}")
logger.info(f"comparing: {hmac.compare_digest(sig_str, req_sig)}")
return hmac.compare_digest(sig_str, req_sig)
Lambda Log in CloudWatch. I can't show the values for security reasons but it seems like each variable/constant has a reasonable value:
DECODED_SECRET: ...
DECRYPTED_SECRET: ...
timestamp: 1532011621
encoded_body: ...
base_str: v0:1532011621:token= ... &team_id= ... &api_app_id= ...
signature: v0=3 ...
req_sig: v0=1 ...
comparing: False
signature should match with req_sig but it doesn't. I guess there is something wrong with base_str = f"{SLACK_API_VER}:{timestamp}:{encoded_body}". I mean, the concatination or urlencoding of the request body, but I'm not sure. Thank you in advance!

Youtube playlistItems list API sometimes works, sometimes throws 404

I have retrieved upload Id from a channel as shown here(https://www.youtube.com/watch?v=RjUlmco7v2M&t=2s),
and using it as playlitstId here https://developers.google.com/youtube/v3/docs/playlistItems/list#try-it
Sometimes it gives 200, sometimes 404,
Response {_body: "{↵ "error": {↵ "errors": [↵ {↵ "domain":
"yo…003c/code\u003e parameter cannot be found."↵ }↵}↵", status: 404,
ok: false, statusText: "OK", headers: Headers…}
Additional info:
I have selected part as contentDetails,id,snippet
maxResults 50
You may check in this documentation the possible reasons why you got a 404 error in PlaylistItems: list. These methods could also return errors listed in the Common errors section.
notFound (404)
playlistNotFound
The playlist identified with the request's playlistId parameter cannot be found.
notFound (404)
videoNotFound
The video identified with the request's videoId parameter cannot be found.
required (400)
playlistIdRequired
The subscribe request does not specify a value for the required playlistId property.
However, if it doesn't solve your issue and you think that it is a bug, you can file a report here.

How to format signedUserToken for sinch?

I'm trying to integrate Sinch into my ROR webapp, and am having some difficulty formatting the signedUserToken to start the sinchClient.
Here is my view, using haml :
#{#signedUserTicket}
%script{src: "//cdn.sinch.com/latest/sinch.min.js", type: "text/javascript"}
= javascript_tag do
$(function(){
$sinchClient = new SinchClient({
applicationKey: 'APP_KEY',
capabilities: {messaging: true, calling: true},
supportActiveConnection: true,
onLogMessage: function(message) {
console.log(message);
},
});
$sinchClient.start({
'userTicket' : "#{#signedUserTicket}",
});
});
And whatever formatting I try to do in the controller, the closest I get to succeeding is :
DOMException [InvalidCharacterError: "String contains an invalid character"
code: 5
nsresult: 0x80530005
location: http://cdn.sinch.com/latest/sinch.min.js:5]
I'd appreciate a little help and would even build a Rubygem for integrating Sinch in Rails if I get the right info and can spare some time.
Cheers,
James
Edit :
I have tried a few modifications and am getting closer (I think).
The problem of InvalidCharacter came from the trailing '='s which apparently don't decode well in Javascript.
My new controller is now :
class SinchController < ApplicationController
skip_before_filter :verify_authenticity_token
before_filter :authenticate_user!
def client
username = current_user.username
applicationKey = "APP_KEY"
applicationSecret = "APP_SECRET_B64"
userTicket = {
"identity" => {"type" => "username", "endpoint" => username},
"expiresIn" => 3600,
"applicationKey" => applicationKey,
"created" => Time.now.utc.iso8601
}
userTicketJson = userTicket.to_json
userTicketBase64 = Base64.strict_encode64(userTicketJson).chop
digest = Digest::HMAC.digest(Base64.decode64(applicationSecret), userTicketJson, Digest::SHA256)
signature = Base64.strict_encode64(digest).chop
#signedUserTicket = (userTicketBase64 + ':' + signature).remove('=')
end
end
But now I'm facing the following error:
POST https://api.sinch.com/v1/instance 500 (Internal Server Error)
client:1 XMLHttpRequest cannot load https://api.sinch.com/v1/instance. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http:// localhost:3000' is therefore not allowed access. The response had HTTP status code 500.
(the space before localhost is due to new user restrictions on SO)
I added Rack::Cors to my rails server to try and allow Cross-domain requests in case it came from my own requests, but whatever configuration I tried, it seems the request never contains the right headers.
Am I misunderstanding CORS requests? Does the problem come from the requests generated by sinch.min.js?
Regards,
James
Error message is due to Firefox base64 decoder can't decode the token, due to symbols (such as #) that are not in the base64 character set. This suggest that the ticket is actually not passed to start(), and this line may be incorrect;
'userTicket' : "#{#signedUserTicket}",
I dont know HAML but shouldnt
'userTicket' : "#{#signedUserTicket}",
be 'userTicket' : #signedUserTicket,

How to access OAuth2 client_id in django rest framework?

I have my django rest framework API protected by Oauth2 toolkit, but I don't know how to get the client_id of the current authorized requests.
class RequestTransactionView(APIView):
def post(self, request, format=None):
transaction = self.parse_dictionary(request.DATA)
return Response(str(transaction.goid))
I have inspected the request object, which gave:
['DATA', 'FILES', 'QUERY_PARAMS', '_CONTENTTYPE_PARAM', '_CONTENT_PARAM', '_METHOD_PARAM', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_auth', '_authenticate', '_authenticator', '_content_type', '_data', '_default_negotiator', '_files', '_load_data_and_files', '_load_method_and_content_type', '_load_stream', '_method', '_not_authenticated', '_parse', '_perform_form_overloading', '_request', '_stream', '_user', 'accepted_media_type', 'accepted_renderer', 'auth', 'authenticators', 'content_type', 'method', 'negotiator', 'parser_context', 'parsers', 'stream', 'successful_authenticator', 'user']
then I inspected the successful_authenticator I got:
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'authenticate', 'authenticate_header', 'www_authenticate_realm']
I also inspected other obvious hints but no luck.
It's easier than I thought, when I was printing out request.auth I got a string, and I thought it's a string type, but then I figured out it's a AccessToken, so from there I can get the application directly.
print request.auth.application

Resources