I started with AWS Lambda today and I can't succeed in passing a payload to the function. On the server side I try to read all the event data but it is empty. What am I doing wrong here?
$client = LambdaClient::factory(array(
'profile' => 'default',
'key' => AWS_ACCESS_KEY_ID,
'secret' => AWS_SECRET_ACCESS_KEY,
'region' => 'eu-west-1'
));
$payload = array('key1' => '1');
$result = $client->invoke(array(
'FunctionName' => 'hello',
'InvocationType' => 'RequestResponse',
'LogType' => 'Tail',
'Payload' => json_encode($payload)
));
Returns:
Received event: {}
Function code on AWS:
console.log('Loading function');
exports.handler = function(event, context) {
console.log('Received event:', JSON.stringify(event, null, 2));
};
In python I send the payload like this:
from boto3 import client as botoClient
import json
lambdas = botoClient("lambda")
def lambda_handler(event, context):
response = lambdas.invoke(FunctionName="myLambdaFunct", InvocationType="RequestResponse", Payload=json.dumps(event));
where event is a dictionary and, json.dumps serialize event to a JSON formatted string
Related
I am trying to invoke AWS Lambda function using AWS SDK for PHP V3.
My source code:
require '../vendor/autoload.php';
use Aws\Lambda\LambdaClient;
use Aws\Exception\AwsException;
$lambdaClient = new Aws\Lambda\LambdaClient([
'version' => 'latest',
'region' => 'us-east-1',
'credentials' => [
'key' => 'MY_ACCESS_KEY',
'secret' => 'MY_SECRET_KEY'
]
]);
$strArrTemp = array('key1' => 'Hello', 'key2' => 'World');
$result = $lambdaClient->invoke([
'FunctionName' => 'testFunc',
'Payload' => json_encode($strArrTemp)
]);
echo $result->get('Payload')->getBody();
This results below:
Fatal error: Call to undefined method GuzzleHttp\Psr7\Stream::getBody() in C:\Apache24\htdocs\FirewallChecker\php\main.php on line xx
The result of var_dump($result->get('Payload')) is below:
object(GuzzleHttp\Psr7\Stream)[116]
private 'stream' => resource(158, stream)
private 'size' => null
private 'seekable' => boolean true
private 'readable' => boolean true
private 'writable' => boolean true
private 'uri' => string 'php://temp' (length=10)
private 'customMetadata' =>
array (size=0)
empty
And the result of 'echo $result->get('Payload')' is below:
{"statusCode": 777, "body": {"key1": "Hello", "key2": "World"}}
I find the link below but it didn't help because getBody() and getContents doesn't work to me at all.
https://stackoverflow.com/a/30549372/6192555
The python code on AWS LAMBDA is below:
import json
import socket
from contextlib import closing
def lambda_handler(event, context):
return {
'statusCode': 777,
'body': event
}
What should I do?
I'm integrating Amazon Pay php SDK from documentation, but getting this error.
Here's my php implementation code:
$amazonpay_config = array(
'public_key_id' => 'XXXXXXXX',
'private_key' => 'my_private_key_path',
'region' => 'US',
'sandbox' => true
);
$payload = array(
'webCheckoutDetails' => array(
'checkoutReviewReturnUrl' => 'https://www.example.com/review',
'checkoutResultReturnUrl' => 'https://www.example.com/result'
),
'storeId' => 'amzn1.application-oa2-client.XXXXXXXXX'
);
$headers = array('x-amz-pay-Idempotency-Key' => uniqid());
$requestResult = [
'error' => 1,
'msg' => 'Error. Can not create checkout session.',
'checkoutSession' => null,
'payloadSign' => null
];
$client = new Client($amazonpay_config);
$resultCheckOut = $client->createCheckoutSession($payload, $headers);
$resultSignPayload = $client->generateButtonSignature($payload);
if($resultCheckOut['status'] !== 201) {
return json_encode($requestResult, true);
}
else {
$requestResult = [
'error' => 0,
'msg' => null,
'checkoutSession' => json_decode($resultCheckOut['response']),
'payloadSign' => $resultSignPayload
];
return $requestResult;
}
Here's JS implementation code for generating Amazon Pay button.
amazon.Pay.renderButton('#amazon-pay-btn', {
// set checkout environment
merchantId: 'XXXXXXXX',
ledgerCurrency: 'USD',
sandbox: true,
checkoutLanguage: 'en_US',
productType: 'PayOnly',
placement: 'Cart',
buttonColor: 'Gold',
createCheckoutSessionConfig: {
payloadJSON: jsonResult['checkoutSession'],
signature: jsonResult['payloadSign'],
publicKeyId: 'XXXXXXXXXXX'
}
});
Couple of problems with the code, mainly that you aren't passing the payload and signature to the front-end correctly. For the payload, you're using jsonResult['checkoutSession'], while it should be jsonResult['payloadSign']. This doesn't contain the payload though but from the PHP code it's apparently the signature that you have put in there. The full code sample should more like this (not tested).
Back-end:
$headers = array('x-amz-pay-Idempotency-Key' => uniqid());
$requestResult = [
'error' => 1,
'msg' => 'Error. Can not create checkout session.',
'signature' => null,
'payload' => null
];
$client = new Client($amazonpay_config);
$resultCheckOut = $client->createCheckoutSession($payload, $headers);
$resultSignature = $client->generateButtonSignature($payload);
if($resultCheckOut['status'] !== 201) {
return json_encode($requestResult, true);
}
else {
$requestResult = [
'error' => 0,
'msg' => null,
'signature' => $resultSignature,
'payload' => $payload
];
return json_encode($requestResult);
}
Front-end:
amazon.Pay.renderButton('#amazon-pay-btn', {
// set checkout environment
merchantId: 'XXXXXXXX',
ledgerCurrency: 'USD',
sandbox: true,
checkoutLanguage: 'en_US',
productType: 'PayOnly',
placement: 'Cart',
buttonColor: 'Gold',
createCheckoutSessionConfig: {
payloadJSON: JSON.stringify(jsonResult['payload']),
signature: jsonResult['signature'],
publicKeyId: 'XXXXXXXXXXX'
}
});
I'm not sure how you're passing $requestResult back to the front-end, potentially there's some additional JSON encoding/decoding required to get the right string. To prevent a signature mismatch error, please make sure that the payload string used for the signature generation in the backend, and the payload string assigned to the 'payloadJSON' parameter match exactly (especially pay attention to whitespaces, escape characters, line breaks, etc.).
Two comments about this issue:
I have defined the payload as an string (that's the way current AmazonPay doc states - Link).
$payload = '{
"webCheckoutDetails": {
"checkoutReviewReturnUrl": "https://www.example.com/review",
"checkoutResultReturnUrl": "https://www.example.com/result"
},
"storeId": "amzn1.application-oa2-client.XXXXXXXXX"
}';
instead of array
$payload = array(
'webCheckoutDetails' => array(
'checkoutReviewReturnUrl' => 'https://www.example.com/review',
'checkoutResultReturnUrl' => 'https://www.example.com/result'
),
'storeId' => 'amzn1.application-oa2-client.XXXXXXXXX'
);
The signature was created, but when rendering the button and clicking on it I get the following error.
Error Message: Signature Dk4qznkoiTVqjcY8Yn1l0iLbsoIj2pEAHWVtgYrphLtFXR9BKhJJPD53It4qYOswS1T/STYMHRy5jtCHGqvLntDjuy0MrhkpoHTpYEtwdOqGHA2qk+QnSGV5LoYldQ/UkAxSG7m8s2iOr11q2sWxUjrk2M3fgzAIxDeZRjJYeAr97eGANYva3jtGDfM6cJdieInBM4dEWWxKqGIh6HxOrY5K/ga26494vAwZAGvXRhZG48FOVp/XCr0mbu6V5pkEOzRJSc+hN5WKAs/c49UsfKPx75Ce7QbaBCZZT1UiczfyYx/mBuZuysUlGmnXPhLOLTPw4+SIizH/pOQyClOQyw== does not match signedString AMZN-PAY-RSASSA-PSS dfff7a87b93cfa78685a233f2dd59e18ad0451b2e3a90af11e500fcc0ceee924 for merchant XXXXXXXX
I was some time till I realized that this was the reason of the error. Actually, while writing this, the new lines in the string were the reason. If string is only in one line, it works.
The button only needs the payload and the signed payload. The $client->createCheckoutSession is not needed. More over, the checkoutSessionId of the resultCheckOut is different from the one obtained when the checkoutReviewReturnUrl is called.
I have a simple POST request using Guzzle from Laravel to send. I tested the request with Postman but it keeps sending request until timeout without returning any response data. I set up some URLs to return sample data and they work fine when testing separately. But when bring the URLs to the request to call from Guzzle, then this sending-request-till-forever happened. Hope you guys can help me shed some light on this problem.
Here is my request code:
$client = new Client();
$req = new Request('POST', 'http://13.114.233.87/api/ocr');
$reqData = $client->send($req, ['timeout' => 5]);
return $reqData;
Here are the handlers for each sample URL:
(1) http://13.114.233.87/api/ocr
Route::post('ocr', 'OcrController#postOcrData'); // routing
public function postOcrData()
{
return response()->json(collect([
'request_id' => rand(0, 9),
'result' => 0,
'error_code' => '',
'error_message' => ''
]));
}
(2) http://13.114.233.87/api/ocr/getResult/{id}
Route::get('ocr/getResult/{id}', 'OcrController#getOcrData'); // routing
public function getOcrData($id)
{
return response()->json(collect([
'request_id' => $id,
'result' => 0,
'error_code' => '',
'error_message' => '',
'fields' => []
]));
}
I am attempting to connect my webpage to my Lex bot using postContent from the AWS SDK for PHP.
I set the credentials and arguments then attempt postContent. Here is the relevant code:
$credentials = new \Aws\Credentials\Credentials('XXXXXXXX', 'XXXXXXXXXXXXXXXXXXXXXXXXXX');
$args = array(
'region' => 'us-east-1',
'version' => 'latest',
'debug' => true,
'credentials' => $credentials
);
$lex_client = new Aws\LexRuntimeService\LexRuntimeServiceClient($args);
$lex_response = $lex_client->postContent([
'accept' => 'text/plain; charset=utf-8',
'botAlias' => 'XXXX',
'botName' => 'XXXX',
'contentType' => 'text/plain; charset=utf-8',
'inputStream' => $userInput,
'requestAttributes' => "{}",
'sessionAttributes' => "{}",
'userId' => 'XXXXXXXXXXXX',
]);
This errors with:
'Error executing "PostContent" on "https://runtime.lex.us-east-1.amazonaws.com/bot/XXXX/alias/XXXX/user/XXXXXXXXXX/content";
AWS HTTP error: Client error: POST https://runtime.lex.us-east-1.amazonaws.com/bot/XXXX/alias/XXXX/user/XXXXXXXXXX/content resulted in a 400 Bad Request response:
{"message":"Invalid Request: Failed to decode Session attributes. Session Attributes should be a Base64 encoded json map of String to String"}' (length=142)
I have attempted using all kinds of JSON strings, JSON encoded strings, and Base64 encoded strings in the sessionAttributes but I continue to get this same error.
The LexRuntimeService in the AWS SDK automatically JSON encodes and Base64 encodes the postContent array. By passing it a JSON string, the json encoding in the SDK will place double quotes around the {} making it "{}" and that causes the error.
So simply pass the sessionAttributes and requestAttributes as PHP arrays.
$lex_response = $lex_client->postContent([
'accept' => 'text/plain; charset=utf-8',
'botAlias' => 'XXXX',
'botName' => 'XXXX',
'contentType' => 'text/plain; charset=utf-8',
'inputStream' => $userInput,
'requestAttributes' => array(),
'sessionAttributes' => array(), // <---- PHP Array not JSON
'userId' => 'XXXXXXXXXXXX',
]);
$accessKey = 'XZA...';
$accessSecret = 'YKW...';
$credentials = new Aws\Credentials\Credentials($accessKey, $accessSecret);
$sharedConfig = [
'region' => 'us-east-1',
'version' => 'latest',
'credentials' => $credentials
];
$sdk = new Aws\Sdk($sharedConfig);
$sns = new SnsClient($sharedConfig);
$payload = [
'PhoneNumber' => '+999999999', // E.164 format
'Message' => md5(time()),
'MessageAttributes' => [
'DefaultSenderID' => ['DataType'=>'String','StringValue'=>'MyBrandName'],
'DefaultSMSType' => ['DataType'=>'String','StringValue'=>'Transactional']
]
];
try {
$data = $sns->publish( $payload );
$MessageId = $data->get('MessageId');
} catch ( Exception $e ) { }
I'm using the AWS SDK for PHP - Version 3.
The code above works well when i'm sending a single SMS message except the attribute DefaultSenderID wich is not working when i send a SMS to a mobile device.
Amazon documentation says that DefaultSenderID – A string, such as your business brand, that is displayed as the sender on the receiving device. Support for sender IDs varies by country. The sender ID can be 1 - 11 alphanumeric characters, and it must contain at least one letter.
Anyone has experienced this problem using the Amazon SNS?
For anybody still struggling with this.
If you look at the documentation here, you will find that you need to add the key AWS.SNS.SMS.SenderID to the payload's MessageAttributes.
The following should work:
$payload = [
'PhoneNumber' => '+999999999', // E.164 format
'Message' => md5(time()),
'MessageAttributes' => [
'AWS.SNS.SMS.SenderID' => [
'DataType' => 'String',
'StringValue' => 'YourSenderID',
]
]
];
try {
$data = $sns->publish($payload);
$MessageId = $data->get('MessageId');
} catch (Exception $e) { }