I am trying to create HTTP API in Cloud Function - that eventually published a message t PubSub. Understood, that there is PubSub REST API - but it enforced me to set up the authentication (in client side) - that I would like to skip and move it to the server side.
Below code is deployed as Google Cloud Function with this command gcloud functions deploy helloGET --runtime nodejs8 --trigger-http
But while tested in browser, it is errored out Error: could not handle the request
Any suggestion is appreciated, thanks!
"use strict";
// [START functions_pubsub_setup]
const { PubSub } = require("#google-cloud/pubsub");
// Instantiates a client
const pubsub = new PubSub();
// [END functions_pubsub_setup]
const Buffer = require("safe-buffer").Buffer;
exports.helloGET = (req, res) => {
const topic = pubsub.topic("projects/myproject/topics/openit");
const message = {
data: {
message: "req.body.message"
}
};
// Publishes a message
res.send(
topic
.publish(message)
.then(() => res.status(200).send("Message published."))
.catch(err => {
err = `Catch block ... ${err}`;
console.error(err);
res.status(500).send(err);
return Promise.reject(err);
})
);
};
Below code will work. But it will take around 30 seconds or plus for the subscriber to receive the event - it is way too slow for my used case :S
"use strict";
const { PubSub } = require("#google-cloud/pubsub");
const pubsub = new PubSub();
const Buffer = require("safe-buffer").Buffer;
exports.helloGET = async (req, res) => {
var toPublish = `hello ${Date.now()}`;
publishMessage("_REPLACE_WITH_TOPIC_NAME_", toPublish);
res.send(`Published ${toPublish}`);
};
async function publishMessage(topicName, data) {
console.log("=> publishMessage, data = ", data);
const dataBuffer = Buffer.from(data);
const topic = pubsub.topic(topicName);
const publisher = topic.publisher();
publisher.publish(dataBuffer, { a: "XYZ" }, function() {
console.log("Published eventually ...");
});
}
Related
I've been trying to solve this problem all day, looking everywhere on the web, even in the official AWS documentation, why does this error keep appearing when I try to send a message to the client through this code?
PS. i use SDK v3 with node.js 18
import {
ApiGatewayManagementApiClient,
PostToConnectionCommand,
} from "#aws-sdk/client-apigatewaymanagementapi";
export const handler = async (event) => {
const domain = event.requestContext.domainName;
const stage = event.requestContext.stage;
const connectionId = event.requestContext.connectionId;
const callbackUrl = `https://${domain}/${stage}`;
const client = new ApiGatewayManagementApiClient({ endpoint: callbackUrl });
const requestParams = {
ConnectionId: connectionId,
Data: "Hello!",
};
const command = new PostToConnectionCommand(requestParams);
try {
await client.send(command);
} catch (error) {
console.log(error);
}
return {
statusCode: 200,
};
};
fef17825-58ce-4ca7-8f38-85857f1aef0a Task timed out after 3.01 seconds
i tried any online guide or video, can anyone help me?
I am using the API Gateway Websocket.
When I send a message to the client from a Lambda function, it sometimes doesn't send a message and other times it sends 2-3 messages.
const AWS = require("aws-sdk")
const api = new AWS.ApiGatewayManagementApi({
endpoint : process.env.API_ENDPOINT
})
exports.handler = async (event) => {
console.log(event)
const body = JSON.parse(event.body)
const connectionId = event.requestContext.connectionId
sendMessage(connectionId, "My Message")
return {}
};
const sendMessage = (connectionId, response) => {
const data = { message : response }
const params = {
ConnectionId : connectionId,
Data : Buffer.from(JSON.stringify(data))
}
return api.postToConnection(params).promise()
}
Actually i had to await the sendMessage function. This solved my problem.
I tried every possible solution on the internet with no hope
What I am trying to do is simply use aws lambda functions (through the aws console) to fetch user fcm token from lets say DynamoDB (not included in the question), use that token to create endpointArn, send push to that specific device
I tested to send Using SNS console and the push gets to the device successfully but I failed to get it to the device using Lambda functions although it gives success status and message ID
Here is the code I used
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set region
AWS.config.update({region: 'us-east-1'});
const sns = new AWS.SNS()
const sampleMessage = {
"GCM": {
"notification": {
"body": "Sample message for Android endpoints",
"title":"Title Test"
}
}
}
exports.handler = async (event) => {
const snsPayload = JSON.stringify(sampleMessage);
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
const params = {
PlatformApplicationArn: '<Platform Arn>',
Token: '<FCM Token>'
};
try {
const endpointData = await sns.createPlatformEndpoint(params).promise();
const paramsMessage = {
Message: snsPayload,
TargetArn: endpointData.EndpointArn
};
var publishTextPromise = await sns.publish(paramsMessage).promise();
response.MessageId = publishTextPromise.MessageId;
response.result = 'Success';
}
catch (e) {
console.log(e.stack)
response.result = 'Error'
}
return response;
};
After some trials and errors I figured out the solution for my own question
1- The GCM part of the payload should be a string not a json
2- The message parameter should have an attribute that explicitly sets the mime type of the payload to Json
Taking all that into consideration
const GCM_data = {
'notification': {
'body': 'Hellow from lambda function',
'title': 'Notification Title'
}
}
const data = {
"GCM": JSON.stringify(GCM_data)
}
const snsPayload = JSON.stringify(data)
and the params should look like
const paramsMessage = {
Message: snsPayload,
TargetArn: endpointData.EndpointArn,
MessageStructure: 'json'
};
and this will work :)
Using AWS SNS, I wanna set filter policy when I subscribe the sms endpoint to the topic. But I get this error : "Delivery protocol SMS does not support message filtering"
I will share the code here...
const AWS = require("aws-sdk")
module.exports.main = async (event) => {
try {
const sns = new AWS.SNS()
const requestBody = event;
var params = {
Protocol: 'SMS', /* required */
TopicArn: 'arn:aws:sns:us-east-1:XXXXXXXX:notification_system', /* required */
Endpoint: requestBody.phoneNumber,
Attributes: {
"FilterPolicy": "{\`number`: [\`Filter1\`]}"
}
};
var subscribePromise = await sns.subscribe(params).promise();
I am not sure why I am getting this error. I checked that I can set filter policy on AWS Console but not on sdk. Please help me to find out the solution. Thanks
I am sorry, I found a solution. Protocol parameter should be lowercase "sms". The code should be like this.
const AWS = require("aws-sdk")
module.exports.main = async (event) => {
try {
const sns = new AWS.SNS()
const requestBody = event;
var params = {
Protocol: 'sms', /* required */
TopicArn: 'arn:aws:sns:us-east-1:XXXXXXXX:notification_system', /* required */
Endpoint: requestBody.phoneNumber,
Attributes: {
"FilterPolicy": "{\`number`: [\`Filter1\`]}"
}
};
var subscribePromise = await sns.subscribe(params).promise();
I am starting a step function from Lambda and the Lambda function is tied to an API Gateway. For some reason, when I try to test the Lambda function, I see hundreds of executions failed and running in loop. I just triggered the step function once. I am missing something here. Can you please advise.
const AWS = require("aws-sdk");
const uuidv4 = require("uuid/v4");
/*----------------------------------------------------------------------- */
/* Implementation */
/*----------------------------------------------------------------------- */
exports.handler = async event => {
var _dt = await ExecuteStepFunction()
return _dt;
}
function ExecuteStepFunction() {
const stepFunctions = new AWS.StepFunctions();
return new Promise((res, rej) => {
var params = {
stateMachineArn: 'arn:aws:states:us-east-1:xxxxxxxxxxxxx:stateMachine:xxTestSateMachine',
input: JSON.stringify(''),
name: uuidv4()
};
stepFunctions.startExecution(params, function (err, data) {
if (err) {
rej(err);
}
else {
res(data);
}
});
});
}
I tried thIS approach provided in the this link (https://docs.aws.amazon.com/step-functions/latest/dg/tutorial-api-gateway.html) where the API gateway directly triggers the step function but I am receiving the following error. After trying to fix this, I move to the above option of starting the function using the API.
{
"__type": "com.amazon.coral.service#UnrecognizedClientException",
"message": "The security token included in the request is invalid"
}