I am implementing a notification service on the server, to push out notifications to both Android and Iphones.
The problem I am having at the moment is that the Android device which I am testing on, is only receiving the default message.
My code is as follows :-
Main Program
string smsMessageString = "{\"default\": \"This is the default message which must be present when publishing a message to a topic. The default message will only be " +
" used if a message is not present for one of the notification platforms.\"," +
"\"APNS\": {\"aps\": {\"alert\": \"Check out these awesome deals!\",\"url\": \"www.amazon.com\"}}," +
"\"GCM\": {\"data\": {\"message\": \"Check out these awesome deals!\",\"url\": \"www.amazon.com\"}}," +
"\"ADM\": {\"data\": {\"message\": \"Check out these awesome deals!\",\"url\": \"www.amazon.com\"}}}";
var smsMessage = new SmsMessageObj
{
smsMessageSubject = "Test Message",
smsMessageBody = smsMessageString
};
snsClient.SendPush(endpointArn, smsMessage);
and the SendPush is as follows :-
public void SendPush(string endpointArn, SmsMessageObj msg)
{
if (string.IsNullOrEmpty(endpointArn))
throw new Exception("Endpoint ARN was null");
var pushMsg = new PublishRequest
{
Message = msg.smsMessageBody,
MessageStructure = "json",
Subject = msg.smsMessageSubject,
TargetArn = endpointArn
};
_client.Publish(pushMsg);
}
Do I need to include anything more so that I can get the "correct" Android notification?
Do I need anything in the app.config?
Thanks for your help and time
I have resolved this question. All I needed to do was to stringify the Json. Maybe it will help someone else in the future. So what I did was :-
var apns_Json = "{\"aps\": {\"alert\": \"Check out these awesome deals_Apple!\",\"url\": \"www.amazon.com\"}}";
var gcm_Json = "{\"data\": {\"message\": \"Check out these awesome deals_Google!\",\"url\": \"www.amazon.com\"}}";
var adm_Json = "{\"data\": {\"message\": \"Check out these awesome deals!\",\"url\": \"www.amazon.com\"}}";
string smsMessageString = "{\"default\": \"This is the default message which must be present when publishing a message to a topic. The default message will only be " +
" used if a message is not present for one of the notification platforms.\"," +
"\"APNS\": " + JsonConvert.ToString(apns_Json) + "," +
"\"GCM\": " + JsonConvert.ToString(gcm_Json) + "," +
"\"ADM\": " + JsonConvert.ToString(adm_Json) + "}";
Related
I am trying to use the Rest Api with temporary credentials to download images stored in an S3 bucket in AWS from my Android App. I need to use the rest API instead of the TransferUtility method included in the Android AWS SDK, because I want to use an image downloader for better performance. According to the official AWS docs, I need to add an Authorization header to the HTTP Get request, that is conform like this:
Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature;
Signature = Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of( StringToSign ) ) );
StringToSign = HTTP-Verb + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedAmzHeaders +
CanonicalizedResource;
https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationConstructingCanonicalizedAmzHeaders
So, I obtain the Authorization header like this:
public String AuthorizationHeader (String dirToImageInBucket) throws UnsupportedEncodingException {
final AWSMobileClient mobileClient = AWSMobileClient.defaultMobileClient();
IdentityManager iM = mobileClient.getIdentityManager();
AWSCredentialsProvider sCredProvider= iM.getCredentialsProvider();
String secretKey = sCredProvider.getCredentials().getAWSSecretKey();
String awsAccessKeyId = sCredProvider.getCredentials().getAWSAccessKeyId();
Mac hmac = null;
hmac = Mac.getInstance("HmacSHA1");
hmac.init(new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA1"));
Date dateT = new Date();
#SuppressLint("SimpleDateFormat") DateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
String date = dateFormat.format(dateT);
String token = "x-amz-security-token:" + Login_Related.geToken(activity) +"\nx-amz-date:" +date+"\n";
String stringToSign = "GET" + "\n\n\n" + date + "\n" + token + "/" + dirToImageInBucket;
String signature = ( Base64.encodeToString(hmac.doFinal(stringToSign.getBytes("UTF-8")), Base64.DEFAULT)).replaceAll("\n", "");
return "AWS" + " " + awsAccessKeyId + ":" + signature;
}
Then I add the "Authorization" header returned by the previous method to the HTTP GET request, and also I include the headers x-amz-date and x-amz-security-token in the request (with the values of date and temporary access token respectively). I am currently testing the request on Postman to test if I can download the image by adding the mentioned headers to GET request of the image URL, and every time I send it, I get the response :
<Error>
<Code>InvalidToken</Code>
<Message>The provided token is malformed or otherwise invalid.</Message>
<Token-0>eyJraWQiOiJ4TFYxcVZiNG1IY3IrSWUxS....
I am sure I am using the right token, since the others http requests in my app are working properly with that token. Can anyone please help me realize what am I missing or doing wrong? Thanks.
Edited to include the token method:
static public String geToken(Activity act) {
AWSMobileClient.initializeMobileClientIfNecessary(act.getApplicationContext());
final AWSMobileClient mobileClient = AWSMobileClient.defaultMobileClient();
IdentityManager iM = mobileClient.getIdentityManager();
IdentityProvider iP = iM.getCurrentIdentityProvider();
token = iP.refreshToken();
System.out.println("x-amz-security-token check this token: " + token);
return token;
}
I have integrated payu into my android app through official docs at
https://www.payumoney.com/dev-guide/mobilecheckout/android.html#prereq .
The problem i'm facing is that my code works perfectly with test credentials, and fails when i use credentials of my live account that i want to integrate in the app.
public void makePayment(View view) {
String phone = "8882434664";
String productName = "product_name";
String firstName = "piyush";
String txnId = "0nf7" + System.currentTimeMillis();
String email = "piyush.jain#payu.in";
String sUrl = "https://test.payumoney.com/mobileapp/payumoney/success.php";
String fUrl = "https://test.payumoney.com/mobileapp/payumoney/failure.php";
String udf1 = "";
String udf2 = "";
String udf3 = "";
String udf4 = "";
String udf5 = "";
boolean isDebug = true;
String key = "2fcU3pmI";
String merchantId = "4947182";// These credentials are from https://test.payumoney.com/
String salt = "BxA24L2F7Z"; // THIS WORKS
/* String key = "yX8OvWy1"; //These credentials are from https://www.payumoney.com/
String merchantId = "5826688"; //THIS DOESN'T WORK
String salt = "0vciMJBbaa"; //ERROR: "some error occurred, Try again"
*/
PayUmoneySdkInitilizer.PaymentParam.Builder builder = new PayUmoneySdkInitilizer.PaymentParam.Builder();
builder.setAmount(getAmount())
.setTnxId(txnId)
.setPhone(phone)
.setProductName(productName)
.setFirstName(firstName)
.setEmail(email)
.setsUrl(sUrl)
.setfUrl(fUrl)
.setUdf1(udf1)
.setUdf2(udf2)
.setUdf3(udf3)
.setUdf4(udf4)
.setUdf5(udf5)
.setIsDebug(isDebug) //Also can someone clarify if this should be true/false for live mode
.setKey(key)
.setMerchantId(merchantId);
PayUmoneySdkInitilizer.PaymentParam paymentParam = builder.build();
String hash = hashCal(key + "|" + txnId + "|" + getAmount() + "|" + productName + "|"
+ firstName + "|" + email + "|" + udf1 + "|" + udf2 + "|" + udf3 + "|" + udf4 + "|" + udf5 + "|" + salt);
Log.d("app_activity123", hash);
paymentParam.setMerchantHash(hash);
PayUmoneySdkInitilizer.startPaymentActivityForResult(MyActivity.this, paymentParam);
}
Extra Info: Test credentials weren't working initially. I had to contact the payu support team to activate the account after which the code was working fine. My employer said he has activated the live account so i don't know what is the issue here.
There are no other issues like mine here, the closest one is here PayuMoney Integration in Android : Some error occured! Try again and it is unanswered.
setIsDebug(boolean) you need to pass false as parameter in this method to use live payment and true when testing in live mode.
I've set it to false and used Real Merchant id,salt and key and it worked, no errors.
Hope this helps someone.
Debug into PayUmoneyActivity
ErrorResponse contains the actual error.
It may be hash mismatch or wrong key.
#override
public void onFailureResponse(ErrorResponse response, String tag) {
mProgressDialog.dismiss();
Toast.makeText(context, "Some error occured",
Toast.LENGTH_SHORT).show();
finish();
}
this method in PayUmoneyActivity does not show error from errorresponse. just the general error. which is very problematic to debug.
I think your problem is in the line
'PayUmoneySdkInitilizer.startPaymentActivityForResult(MyActivity.this, paymentParam);'.
The official document states that you have to start transaction by using
'PayUmoneyFlowManager.startPayUMoneyFlow(paymentParam,this, R.style.AppTheme_default, false);'
I'm trying to implement firebase notifications. But I have trouble finding any documentation on how to retrieve custom data from firebase notification.
But in in code how to get the custom key.
I'm using FirebaseMessagingService.onMessageReceived to get the message data.
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO(developer): Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
}
You can check your custom data using:
for (Map.Entry<String, String> entry : remoteMessage.getData().entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
Log.d(TAG, "key, " + key + " value " + value);
}
To get specific key:
String value = remoteMessage.getData().get("<YOUR_KEY>");
Let A be your key, then you can easily parse this value by using the following code.
JSONObject json = new JSONObject(remoteMessage.getData());
Iterator itr = json.keys();
while (itr.hasNext()) {
String key = (String) itr.next();
if (key.equals("A")) {
flag = json.getString(key);
}
Log.d(TAG, "..." + key + " => " + json.getString(key));
}
Now I simplify the problem.
I try to directly copy and paste the query to confrim it use %3D instead of '='
var xhrSNS = Ti.Network.createHTTPClient({
onload :function(e) {
Ti.API.info("test Post query:" + JSON.stringify(e));
Ti.API.info(this.responseText);
},
onerror : function(e){
Ti.API.debug("test Create PlatForm Endpoint registerPush error:" + e.error);
Ti.API.info(this.responseText);
}
});
getUrl = "http://sns.ap-northeast-1.amazonaws.com?AWSAccessKeyId=AAAAAAAAAAAAAAA&Action=CreatePlatformEndpoint&PlatformApplicationArn=arn%3Aaws%3Asns%3Aap-northeast-1%3A776188326341%3Aapp%2FGCM%2Fmyapp&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-04-03T15%3A05%3A51.465Z&Token=APA91bEiaB-902cRmwwgCwoqi2jRIJzzTIZNB7XduELuBKit_WF29tN5twrVW5t1BHpj07ARgwjzoc-I5xVur5K6I6ZQcnoErguUyi-VBHvuI5eY9HS4jq1J6KbIC05Etoe8indjpY9X&Version=2010-03-31&Signature=DzxQpP%2BcALS91C53eia6ZkBhxg3lQ32ctqiEmqKwwLA%3D";
xhrSNS.open('GET',getUrl);
xhrSNS.send();
Please see the last letter of getUrl, it surely use '%3D'.
But return is the same.
It makes a complaint that sentence include '=' delimiter.
[DEBUG] test Create PlatForm Endpoint registerPush error:400 : Bad Request
[INFO] <ErrorResponse xmlns="http://webservices.amazon.com/AWSFault/2005-15-09">
[INFO] <Error>
[INFO] <Type>Sender</Type>
[INFO] <Code>MalformedQueryString</Code>
[INFO] <Message>AWSAccessKeyId=AAAAAAAAAAAAAAA&Action=CreatePlatformEndpoint&PlatformApplicationArn=arn%3Aaws%3Asns%3Aap-northeast-1%3A776188326341%3Aapp%2FGCM%2Fmyapp&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-04-03T15%3A05%3A51.465Z&Token=APA91bEiaB-902cRmwwgCwoqi2jRIJzzTIZNB7XduELuBKit_WF29tN5twrVW5t1BHpj07ARgwjzoc-I5xVur5K6I6ZQcnoErguUyi-VBHvuI5eY9HS4jq1J6KbIC05Etoe8indjpY9X&Version=2010-03-31&Signature=DzxQpP%2BcALS91C53eia6ZkBhxg3lQ32ctqiEmqKwwLA= is not valid; the value of a query string parameter may not contain a '=' delimiter</Message>
-----------------------------adding until here-----------------
I am using Amazon SNS API
I made url like this it works well on browser.
http://sns.ap-northeast-1.amazonaws.com?AWSAccessKeyId=AAAAAAAAAAAAA&Action=CreatePlatformEndpoint&PlatformApplicationArn=arn%3Aaws%3Asns%3Aap-northeast-1%3A776188326341%3Aapp%2FGCM%2Fmyapp&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-04-01T21%3A06%3A29.861Z&Token=APA91bEiaB-902cRmwwgCwoqi2jRIJzzTIZNB7XduELuBKit_WF29tN5twrVW5t1BHpj07ARgwjzoc-I5xVur5K6I6ZQcnoErguUyi-VBHvuI5eY9HS4jq1J6KbIC05Etoe8indjpY9X&Version=2010-03-31&Signature=Dt9tXa0Rjl%2Ff6YxZ4JaPfsm%2BT%2BMX03gS712nIKKekAI%3D
However if I try from Android.
This returns 400 bad request.
<ErrorResponse xmlns="http://webservices.amazon.com/AWSFault/2005-15-09">
<Error>
<Type>Sender</Type>
<Code>MalformedQueryString</Code>
<Message>AWSAccessKeyId=AAAAAAAAAAAAA&Action=CreatePlatformEndpoint&PlatformApplicationArn=arn%3Aaws%3Asns%3Aap-northeast-1%3A776188326341%3Aapp%2FGCM%2Fmyapp&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-04-01T21%3A06%3A29.861Z&Token=APA91bEiaB-902cRmwwgCwoqi2jRIJzzTIZNB7XduELuBKit_WF29tN5twrVW5t1BHpj07ARgwjzoc-I5xVur5K6I6ZQcnoErguUyi-VBHvuI5eY9HS4jq1J6KbIC05Etoe8indjpY9X&Version=2010-03-31&Signature=Dt9tXa0Rjl%2Ff6YxZ4JaPfsm%2BT%2BMX03gS712nIWUekAI=
is not valid; the value of a query string parameter may not contain a '=' delimiter</Message>
</Error>
<RequestId>5b40d988-af34-577a-8839-96f04a217dec</RequestId>
</ErrorResponse>
I think
the value of a query string parameter may not contain a '=' delimiter
is the cause of problem though, I cant figure out how to fix it.
The same code works on iPhone.
it doesn't work only from android.
I made URL strings from this function
var array = {
PlatformApplicationArn : Ti.App.global.androidArn
};
awsObj = getSignature("CreatePlatformEndpoint",date,awsUrl,event.registrationId,array);
var getUrl = "http://" + awsUrl + '?' + awsObj.str_para + "&Signature=" + awsObj.encodedString;
Ti.API.info('GETurl :' + getUrl);
xhrSNS.open('GET',getUrl);
function getSignature(action,date,awsUrl,token,array){
Ti.include('/jssha/jssha256.js');
var base = {
Action:action,
AWSAccessKeyId : Ti.App.global.awsAccessKey,
SignatureMethod : "HmacSHA256",
SignatureVersion :2,
Token: token,
Timestamp : date,
Version : "2010-03-31",
};
para = arrayMerge(array,base);
var para_array = [];
for(var pname in para){
para_array.push(pname + "=" + encodeURIComponent(para[pname]));
}
para_array.sort();
var str_para = para_array.join('&');
var str_signature = "GET" + "\n" + awsUrl + "\n" + "/" + "\n" + str_para;
console.log("str_signature:" + str_signature);
HMAC_SHA256_init(Ti.App.global.awsSecretKey);
HMAC_SHA256_write(str_signature);
var array_hash = HMAC_SHA256_finalize();
var str_hash = "";
for (var i = 0; i < array_hash.length; i++) {
str_hash += String.fromCharCode(array_hash[i]);
}
var awsObj = new Object();
awsObj.encodedString = encodeURIComponent(base64encode(str_hash));
Ti.API.info("awsObj.encodedString:" + awsObj.encodedString); // I have confirmed encodedString is correct here.
awsObj.str_para = str_para;
return awsObj;
}
URL in browser: Signature=Dt9tXa0Rjl%2Ff6YxZ4JaPfsm%2BT%2BMX03gS712nIKKekAI%3D
URL in Android: Signature=Dt9tXa0Rjl%2Ff6YxZ4JaPfsm%2BT%2BMX03gS712nIWUekAI=
Now I simplify the problem.
I try to directly copy and paste the query to confrim it use %3D instead of '='
var xhrSNS = Ti.Network.createHTTPClient({
onload :function(e) {
Ti.API.info("test Post query:" + JSON.stringify(e));
Ti.API.info(this.responseText);
},
onerror : function(e){
Ti.API.debug("test Create PlatForm Endpoint registerPush error:" + e.error);
Ti.API.info(this.responseText);
}
});
getUrl = "http://sns.ap-northeast-1.amazonaws.com?AWSAccessKeyId=AAAAAAAAAAAAAAA&Action=CreatePlatformEndpoint&PlatformApplicationArn=arn%3Aaws%3Asns%3Aap-northeast-1%3A776188326341%3Aapp%2FGCM%2Fmyapp&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-04-03T15%3A05%3A51.465Z&Token=APA91bEiaB-902cRmwwgCwoqi2jRIJzzTIZNB7XduELuBKit_WF29tN5twrVW5t1BHpj07ARgwjzoc-I5xVur5K6I6ZQcnoErguUyi-VBHvuI5eY9HS4jq1J6KbIC05Etoe8indjpY9X&Version=2010-03-31&Signature=DzxQpP%2BcALS91C53eia6ZkBhxg3lQ32ctqiEmqKwwLA%3D";
xhrSNS.open('GET',getUrl);
xhrSNS.send();
Please see the last letter of getUrl, it surely use '%3D'.
But return is the same.
It makes a complaint that sentence include '=' delimiter.
[DEBUG] test Create PlatForm Endpoint registerPush error:400 : Bad Request
[INFO] <ErrorResponse xmlns="http://webservices.amazon.com/AWSFault/2005-15-09">
[INFO] <Error>
[INFO] <Type>Sender</Type>
[INFO] <Code>MalformedQueryString</Code>
[INFO] <Message>AWSAccessKeyId=AAAAAAAAAAAAAAA&Action=CreatePlatformEndpoint&PlatformApplicationArn=arn%3Aaws%3Asns%3Aap-northeast-1%3A776188326341%3Aapp%2FGCM%2Fmyapp&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-04-03T15%3A05%3A51.465Z&Token=APA91bEiaB-902cRmwwgCwoqi2jRIJzzTIZNB7XduELuBKit_WF29tN5twrVW5t1BHpj07ARgwjzoc-I5xVur5K6I6ZQcnoErguUyi-VBHvuI5eY9HS4jq1J6KbIC05Etoe8indjpY9X&Version=2010-03-31&Signature=DzxQpP%2BcALS91C53eia6ZkBhxg3lQ32ctqiEmqKwwLA= is not valid; the value of a query string parameter may not contain a '=' delimiter</Message>
-----------------------------adding until here-----------------
I am using Amazon SNS API
I made url like this it works well on browser.
http://sns.ap-northeast-1.amazonaws.com?AWSAccessKeyId=AAAAAAAAAAAAA&Action=CreatePlatformEndpoint&PlatformApplicationArn=arn%3Aaws%3Asns%3Aap-northeast-1%3A776188326341%3Aapp%2FGCM%2Fmyapp&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-04-01T21%3A06%3A29.861Z&Token=APA91bEiaB-902cRmwwgCwoqi2jRIJzzTIZNB7XduELuBKit_WF29tN5twrVW5t1BHpj07ARgwjzoc-I5xVur5K6I6ZQcnoErguUyi-VBHvuI5eY9HS4jq1J6KbIC05Etoe8indjpY9X&Version=2010-03-31&Signature=Dt9tXa0Rjl%2Ff6YxZ4JaPfsm%2BT%2BMX03gS712nIKKekAI%3D
However if I try from Android.
This returns 400 bad request.
<ErrorResponse xmlns="http://webservices.amazon.com/AWSFault/2005-15-09">
<Error>
<Type>Sender</Type>
<Code>MalformedQueryString</Code>
<Message>AWSAccessKeyId=AAAAAAAAAAAAA&Action=CreatePlatformEndpoint&PlatformApplicationArn=arn%3Aaws%3Asns%3Aap-northeast-1%3A776188326341%3Aapp%2FGCM%2Fmyapp&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2016-04-01T21%3A06%3A29.861Z&Token=APA91bEiaB-902cRmwwgCwoqi2jRIJzzTIZNB7XduELuBKit_WF29tN5twrVW5t1BHpj07ARgwjzoc-I5xVur5K6I6ZQcnoErguUyi-VBHvuI5eY9HS4jq1J6KbIC05Etoe8indjpY9X&Version=2010-03-31&Signature=Dt9tXa0Rjl%2Ff6YxZ4JaPfsm%2BT%2BMX03gS712nIWUekAI=
is not valid; the value of a query string parameter may not contain a '=' delimiter</Message>
</Error>
<RequestId>5b40d988-af34-577a-8839-96f04a217dec</RequestId>
</ErrorResponse>
I think
the value of a query string parameter may not contain a '=' delimiter
is the cause of problem though, I cant figure out how to fix it.
The same code works on iPhone.
it doesn't work only from android.
I made URL strings from this function
var array = {
PlatformApplicationArn : Ti.App.global.androidArn
};
awsObj = getSignature("CreatePlatformEndpoint",date,awsUrl,event.registrationId,array);
var getUrl = "http://" + awsUrl + '?' + awsObj.str_para + "&Signature=" + awsObj.encodedString;
Ti.API.info('GETurl :' + getUrl);
xhrSNS.open('GET',getUrl);
function getSignature(action,date,awsUrl,token,array){
Ti.include('/jssha/jssha256.js');
var base = {
Action:action,
AWSAccessKeyId : Ti.App.global.awsAccessKey,
SignatureMethod : "HmacSHA256",
SignatureVersion :2,
Token: token,
Timestamp : date,
Version : "2010-03-31",
};
para = arrayMerge(array,base);
var para_array = [];
for(var pname in para){
para_array.push(pname + "=" + encodeURIComponent(para[pname]));
}
para_array.sort();
var str_para = para_array.join('&');
var str_signature = "GET" + "\n" + awsUrl + "\n" + "/" + "\n" + str_para;
console.log("str_signature:" + str_signature);
HMAC_SHA256_init(Ti.App.global.awsSecretKey);
HMAC_SHA256_write(str_signature);
var array_hash = HMAC_SHA256_finalize();
var str_hash = "";
for (var i = 0; i < array_hash.length; i++) {
str_hash += String.fromCharCode(array_hash[i]);
}
var awsObj = new Object();
awsObj.encodedString = encodeURIComponent(base64encode(str_hash));
Ti.API.info("awsObj.encodedString:" + awsObj.encodedString); // I have confirmed encodedString is correct here.
awsObj.str_para = str_para;
return awsObj;
}
URL in browser: Signature=Dt9tXa0Rjl%2Ff6YxZ4JaPfsm%2BT%2BMX03gS712nIKKekAI%3D
URL in Android: Signature=Dt9tXa0Rjl%2Ff6YxZ4JaPfsm%2BT%2BMX03gS712nIWUekAI=