I've integrated HTTP API Gateway with SQS and have some problem with MessageAttributes. The main goal is to pass parameter in URL, attach it to message attribute and send to SQS.
I've created HTTP API with RouteKey = "$default" with the following RequestParameters:
RequestParameters =
{
{"MessageBody", "$request.body"},
{"QueueUrl", Output.Format($"{config.SqsPath}")},
{"MessageAttributes", #"{
""SubscriptionId"": {
""DataType"": ""String"",
""StringValue"": ""abc123""
}
}"}
}
for test purpose I've hardcoded value, but at the end I'll use $request.querystring.SubscriptionId
What I have now, is the following:
AWS Console printscreen
It looks good, however all post requests which I made didn't contains any attributes:
CloudWatch printscreen
What have I missed?
Update
I figured out what happened - I had to pass parameters template with invalid format (however, no error was thrown).
Finally I have a working version, message attribute in AWS Console:
{ "SubscriptionId": { "DataType": "String", "StringValue": "${request.querystring.SubscriptionId}" } }
and my integration code:
RequestParameters =
{
{"MessageBody", "$request.body"},
{"QueueUrl", Output.Format($"{config.SqsPath}")},
{"MessageAttributes", #"{ ""SubscriptionId"": { ""DataType"": ""String"", ""StringValue"": ""${request.querystring.SubscriptionId}"" } }"}
},
Related
After 3 days I am finished configurations pub/sub push notification from my android app, now my backend server catch every subscription notification made from android app, but now I'm stuck in this stage, all I need is how read full subscription details like(Who make this payment, expire date, ...etc)
I don't know how to do it and what necessary steps to make it happen.
this is what notification look like from my backend server:
{
"message" :
{
"attributes":{ "key": null },
"data": "JSON_CODE",
"messageId": "6542662753109422",
"message_id": "6546652753109422",
"publishTime": "2023-01-01T15:53:42.962Z",
"publish_time": "2023-01-01T15:53:42.962Z"
},
"subscription": "projects/{api_id}/subscriptions/{service_name}-sub"
}
message.data (JSON_CODE) decoded into this:
{
"version": "1.0",
"packageName": "com.expamle.android",
"eventTimeMillis": "1672588422635",
"subscriptionNotification":
{
"version": "1.0",
"notificationType": 4,
"purchaseToken": "lkgkfeofbmfnnalianjdppej.AO-J1OxNcztkkzntpvQk4nttaBiqHJ5WMD58tb_KxCdsyPooE_QPvqXdtnoEpqD0t96j5V4lxol3_FfpuRNDvBeRTYKo_ixJtw",
"subscriptionId": "12_month_plan"
}
}
I have a keys.json file.
And I made all permission required in my pub/sub service accounts.
How to read the full subscription details?
I solved it, to any new coming users this is how to solve it .
first I've used simple .NET library "Google.Apis.Auth.OAuth2" to get access token to any query request.
by this simple code I can get token using key.json i've downloaded from my google cloud console from "**https://console.cloud.google.com/iam-admin/serviceaccounts**" and by manage keys you can generate json secret key.
Auth:
string keyFile = HttpContext.Server.MapPath("~/bin/key.json");
var credential = GoogleCredential.FromFile(keyFile).CreateScoped(new[] { "https://www.googleapis.com/auth/androidpublisher" });
string token = await credential.UnderlyingCredential.GetAccessTokenForRequestAsync();
}
Now you can request google query GET url to get full purchased subscription info .
https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{PACKAGE_NAME}/purchases/subscriptionsv2/tokens/{purchaseTokenComesWithMessage.data}
any requests must be included with Authorization Bearer accessToken we'ave generated from Auth. section above.
the result:
{
"kind": "androidpublisher#subscriptionPurchaseV2",
"startTime": "2023-01-03T14:56:24.940Z",
"regionCode": "US",
"subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
"latestOrderId": "GPA.3394-8372-7793-03673",
"testPurchase": {},
"acknowledgementState": "ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED",
"externalAccountIdentifiers": {
"obfuscatedExternalAccountId": "92d8f330-8d2a-45ab-b6a1-6720b3d15999"
},
"lineItems": [
{
"productId": "12_month_plan",
"expiryTime": "2023-01-03T15:28:21.928Z",
"autoRenewingPlan": {
"autoRenewEnabled": true
},
"offerDetails": {
"basePlanId": "360day",
"offerTags": [
"tools"
]
}
}
] }
Thanks
According to the V3 Sendgrid documentation, I can create segment (on a contact list) using API:
https://docs.sendgrid.com/api-reference/contacts-api-segments/create-a-segment#teconsent
My code is as follows:
public static async void addSegment(SendGridClient client, string list_Id)
{
var data = #"{
""name"": ""location1"",
""list_id"": ""[MY_LIST_ID]"",
""conditions"": [
{
""field"": ""Location"",
""value"": ""location_1"",
""operator"": ""eq"",
""and_or"": """"
},
],
}";
var response = await client.RequestAsync(
method: SendGridClient.Method.POST,
urlPath: "contactdb/segments",
requestBody: data
);
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Body.ReadAsStringAsync().Result);
Console.WriteLine(response.Headers.ToString());
}
However, I got the following error message:
Forbidden
{"errors":[{"field":null,"message":"access forbidden"}]}
What am I doing incorrectly?
Twilio SendGrid developer evangelist here.
SendGrid API keys can be scoped to only permit certain actions against the API. My guess here is that the API key you are using does not have permission to create a segment on the contact list.
You could either use an API key with full access or ensure the key you are using has access to (I think) the marketing APIs.
i need to pass dynamic data in body in POST method od web activity using azure data factory.
My data source point is in Blob Storage from i am storing json data .I need to pass ID in body.
I am doing this inside for each loop.
I have also created linkedservices.
I am passing like this as shown below in body.But i am not getting proper value.
{
"data":{"date":#formatDateTime(convertTimeZone(utcnow(), 'UTC', 'GMT Standard Time'),'yyyy-MM-dd'),"id":#item},
"meta": {
"pagination": {
"page_size": 200
}
}
}
Please use this expression to have a try:
{ "data":{"date":#{formatDateTime(convertTimeZone(utcnow(), 'UTC', 'GMT Standard Time'),'yyyy-MM-dd')},"id":#{item()}}, "meta": { "pagination": { "page_size": 200 } } }
Result in my web application:
I'm new to dialogflow and trying to use permission handler to ask for location permission using .NET core webapi. I've created intent, entities and event(google.assistent.permission) in dialogflow console. Now I want to send a request from my webapi to send the request to access location.
Can somebody please provide a code sample how to send request to access location from my webhook?
You need to include the helper intent DialogFlow JSON as part of the payload:
WebhookResponse response;
Struct payload;
response.Payload = payload;
Alternatively, it can be added as a fulfillment message with the payload type1.
The payload struct can be parsed from JSON:
response.Payload = Struct.Parser.ParseJson(#"{
""google"": {
""expectUserResponse"": true,
""systemIntent"": {
""intent"": ""actions.intent.PLACE"",
""data"": {
""#type"": ""type.googleapis.com/google.actions.v2.PlaceValueSpec"",
""dialogSpec"": {
""extension"": {
""#type"": ""type.googleapis.com/google.actions.v2.PlaceValueSpec.PlaceDialogSpec"",
""permissionContext"": ""To find a location"",
""requestPrompt"": ""Where would you like to go?""
}
}
}
}
}
}");
Or created using the Protobuf API (slightly faster due to skipping the parsing step and type safe, but incredibly ugly):
response.Payload = new Struct
{
Fields =
{
["google"] = Value.ForStruct(new Struct
{
Fields =
{
["expectUserResponse"] = Value.ForBool(true),
["systemIntent"] = Value.ForStruct(new Struct
{
// ... and so on
})
}
})
}
};
Keep in mind that including any message in the payload (which is necessary to call the helper) will override any other messages you added previously and ignore anything added afterwards (they are still part of the returned object, but stripped out by DialogFlow). That means: If you want any other rich response, it currently also needs to be manually added to the payload. At that point, you might as well create the entire JSON response from scratch.
Short version
Logged in as a Facebook user, I use my oAuth token to assume an IAM role on AWS. It returns what looks to be valid credentials, e.g. there is an AccessKeyId, SecretAccessKey that are similar length to our master keys.
When I try to use these credentials to access a DynamoDB table, I get one of two exceptions:
"The remote server returned an error: (400) Bad Request."; or
"The security token included in the request is invalid.".
I'm using the AWS C# SDK version 1.5.25.0
Long version
As I said above, I'm trying to access a DynamoDB table on AWS using credentials supplied by AmazonSecurityTokenServiceClient authorized by Facebook Identity as described in this AWS guide.
The policy for the IAM role that I've created is:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"dynamodb:BatchGetItem",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:UpdateItem"
],
"Sid": "Stmt1372350145000",
"Resource": [
"*"
],
"Effect": "Allow"
}
]
}
How I get the credentials:
The user logs in with Facebook using oAuth.
Using the access token, I assume the IAM role using a AmazonSecurityTokenServiceClient.AssumeRoleWithWebIdentity with a request.
This returns what looks like to be valid credentials, e.g. a AccessKeyId, SecretAccessKey that are similar length to our master keys.
using (var tokenServiceClient = new AmazonSecurityTokenServiceClient(RegionEndpoint.USEast1))
{
var request = new AssumeRoleWithWebIdentityRequest
{
DurationSeconds = (int)TimeSpan.FromHours(1).TotalSeconds,
ProviderId = "graph.facebook.com",
RoleArn = "arn:aws:iam::193557284355:role/Facebook-OAuth",
RoleSessionName = result.id,
WebIdentityToken = FBClient.AccessToken
};
var response = tokenServiceClient.AssumeRoleWithWebIdentity(request);
AWSAssumedRoleUser = response.AssumeRoleWithWebIdentityResult.AssumedRoleUser;
AWSCredentials = response.AssumeRoleWithWebIdentityResult.Credentials;
}
How I use these credentials:
Using the returned credentials, I then try to access a AWS DynamoDB resource.
using (var client = new AmazonDynamoDBClient(AWSCredentials.AccessKeyId, AWSCredentials.SecretAccessKey, AWSCredentials.SessionToken, RegionEndpoint.USEast1))
{
var context = new DynamoDBContext(client);
var data = context.Scan<SomeData>();
}
This returns "The remote server returned an error: (400) Bad Request." when trying to Scan the table.
This is where the variation in the exception message is; if I omit the AWSCredentials.SessionToken from the above AmazonDynamoDBClient
using (var client = new AmazonDynamoDBClient(AWSCredentials.AccessKeyId, AWSCredentials.SecretAccessKey, RegionEndpoint.USEast1))
{
var context = new DynamoDBContext(client);
var data = context.Scan<SomeData>();
}
This returns "The security token included in the request is invalid." when trying to Scan the table.
Question
At this point I cannot tell what is wrong, are the credentials invalid or that I'm not passing everything through that is needed to AWS.
Can anyone offer any insight to what is wrong or how I could debug this further?
I cross-posted my question to the AWS forums and received an answer from an Amazon engineer.
https://forums.aws.amazon.com/message.jspa?messageID=465057
DynamoDBContext object invokes DescribeTable on the target table (and caches this data, so for optimal performance you would want to keep the context object around for as long as possible, so this call is only done once per target table). Modify your policy as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"dynamodb:BatchGetItem",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:UpdateItem",
"dynamodb:DescribeTable"
],
"Sid": "Stmt1372350145000",
"Resource": [
"*"
],
"Effect": "Allow"
}
]
}