This very simple thing does not work for me even though I have practically copy + pasted the example code from here:
https://github.com/Azure/azure-storage-node
It seems that tableService.retrieveEntity never fires at all? The context.log does not print anything. I get a status 200 with no body but this is because that is Azure's default.
It is the same problem if I write a query and use the queryEntities-method as well.
I write these things in the Azure Portal for simplicity's sake.
This is my code:
var azure = require('azure-storage');
module.exports = async function (context, req) {
var tableService = azure.createTableService('myTable', 'GoYVMvN+SXRJhzVERIYWFu6k0/DkZINIerS+YpwmQVy3ppPFJ+8bTavfisHJvsNbo5hjgpw40bWv8XXXXXXXXX==');
tableService.retrieveEntity('myList', 'MyPartitionKey', '1', function(error, result, response) {
context.log("retrieving...")
if(!error){
context.res = {
status: 200,
body: "The entity was retrieved"
}
} else {
context.res = {
status: 500,
body: "The entity was not retrieved"
}
}
});
};
Related
I need the following. Create an azure function that generates qr code. Until then I found a tutorial. HttpTrigger, in javascript, with node -qrcode library
But I need to call this function in a simple html/css I made. how to make?
The azure function looks like this:
//require the module qrcode
const QRCode = require('qrcode');
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
if(req.query.text) {
let code;
try {
code = await QRCode.toDataURL(req.query.text);
} catch (err) {
context.log.error('ERROR', err);
throw err;
}
if (code) {
context.res = {
body: code
}
} else {
context.res = {
body: "Error: QR Code rendering error",
status: 400
}
}
} else {
context.res = {
body: "Error: Missing query string text",
status: 400
}
}
}
After you publish your function, you should get the Function URL from the Azure portal, and then make an HTTP call from inside your html page(for example using jQuery, ajax etc). In your function.json, you should have mentioned which HTTP methods your function supports , example GET, POST. Refer https://learn.microsoft.com/en-us/azure/azure-functions/create-first-function-vs-code-node
I have Lambda Node function behind API Gateway, what I am trying to do is:
Make call to API
Do some logic
Send a message to Slack
Problem:
When I run default test request, the function finishes successfully but it doesn't send a message to Slack (logs only print Slack and not HAHA1/2),however, it does when I run this function from local machine which leads me to believe that AWS stops any none client-server traffic. My function is not in VPC. What can I do to allow outgoing traffic to Slack? Thanks.
const AWS = require('aws-sdk');
const Slack = require('slack-node');
const dynamo = new AWS.DynamoDB.DocumentClient();
/**
* Demonstrates a simple HTTP endpoint using API Gateway. You have full
* access to the request and response payload, including headers and
* status code.
*
* To scan a DynamoDB table, make a GET request with the TableName as a
* query string parameter. To put, update, or delete an item, make a POST,
* PUT, or DELETE request respectively, passing in the payload to the
* DynamoDB API as a JSON body.
*/
sendSlack()
function sendSlack() {
webhookUri = "https://hooks.slack.com/services/....";
slack = new Slack();
slack.setWebhook(webhookUri);
console.log('Slack');
slack.webhook({
channel: "...",
username: "...",
text: "..."
}, function(err, response) {
console.log("HAHA1");
console.log(response);
console.log("HAHA2");
});
}
exports.handler = async (event, context) => {
console.log('Received event:', JSON.stringify(event, null, 2));
sendSlack()
let body;
let statusCode = '200';
const headers = {
'Content-Type': 'application/json',
};
try {
switch (event.httpMethod) {
case 'DELETE':
body = await dynamo.delete(JSON.parse(event.body)).promise();
break;
case 'GET':
body = await dynamo.scan({ TableName: event.queryStringParameters.TableName }).promise();
break;
case 'POST':
body = await dynamo.put(JSON.parse(event.body)).promise();
break;
case 'PUT':
body = await dynamo.update(JSON.parse(event.body)).promise();
break;
default:
throw new Error(`Unsupported method "${event.httpMethod}"`);
}
} catch (err) {
statusCode = '400';
body = err.message;
} finally {
body = JSON.stringify(body);
}
return {
statusCode,
body,
headers,
};
};
You will need to wait for the slack call by either providing a callback or promisifying it:
function sendSlack() {
return new Promise((resolve, reject) => {
webhookUri = "https://hooks.slack.com/services/....";
slack = new Slack();
slack.setWebhook(webhookUri);
console.log('Slack');
slack.webhook({
channel: "...",
username: "...",
text: "..."
}, function(err, response) {
if(err) return reject(err)
resolve(response)
});
})
}
Then in your code
await sendSlack()
It could be that your lambda handler is completing before your call to Slack is successfully executed.
Since the call to Slack is async, I would suggest you try to await its response before your handler returns a response.
I'm not 100% certain, by my guess is that the async Slack call gets scheduled but not run until the main body of the function has completed, at which point the lambda is "spun down" and nothing further is run.
I am new Azure function. I want to call the Azure function which will trigger another Azure function. I have written bellow code but its giving me timeout. The code written in node js.
Please suggest what to do.
module.exports = async function (context, req, callback) {
UtilityAccountNumber=req.body.UtilityAccountNumber.split(',');
if(UtilityAccountNumber=='' || typeof UtilityAccountNumber==='undefined' || !(Array.isArray(UtilityAccountNumber) && UtilityAccountNumber.length) ){
response={
status: 0,
message:"Please provide utility acccount number."
};
else{
if(UtilityAccountNumber.length){
for(let accountNo of UtilityAccountNumber){
try
{
var options = {
host: process.env.API_HOST,
port: process.env.PORT,
path: '/api/'+process.env.WEBSCRAPERMASTER,
method: 'POST'
};
var myreq = http.request(options, function(res) {
});
myreq.end();
}
catch (ex) // if failed
{
await logHTTPErrorResponse(ex, huId);
console.error(ex);
}
}
}
}
context.res = {
status: 200,
body: response
};
};
Your code logic may be stuck at some point, so it gives you timeout.(Azure function has a default timeout limit.) I think the function chain of azure durable function fully meets your requirements, and you are using nodejs, so azure durable function is supported.
Please have a look of this:
https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-sequence?tabs=javascript
I know this is a failing in my knowledge but I can not work it out. I've spent the last couple of hours browsing and trying variations but I can not work out what is wrong.
I have written a success piece of node.js that when run from the command line returns a table, in JSON form, from a local AWS DynamoDB.
I am now trying to turn that into a lamda call. And there's where it goes wrong. I can not get the lamda to return anything and I don't know why. I'm pretty sure it's because I don't understand how the callback mechanism works but reading around that hasn't help and hasn't allowed me to stumble over the answer.
This is the code I've got:
var AWS = require("aws-sdk");
exports.handler = (event, context, callback) => {
let id = (event.pathParameters || {}).division || false;
switch(event.httpMethod){
case "GET":
if(id) {
//callback(null, {body: "Returning Divison " + id});
AWS.config.update({
region: "us-west-2",
endpoint: "http://localhost:8000"
});
var docClient = new AWS.DynamoDB.DocumentClient()
var table = 'League';
var params = {
TableName : table,
KeyConditionExpression: "#division = :division",
ExpressionAttributeNames: {
"#division": "division"
},
ExpressionAttributeValues: {
":division": id
}
};
docClient.query(params, function(err, data) {
if (err)
{
//console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
callback(err, null);
}
else
{
//console.log("GetItem succeeded:", JSON.stringify(data, null, 2));
callback(null, JSON.stringify(data.Item));
}
})
break;
}
callback(null, {body: "Return all divisions"});
break;
default:
// Send HTTP 501: Not Implemented
console.log("Error: unsupported HTTP method (" + event.httpMethod + ")");
callback(null, { statusCode: 501 })
}
}
If I comment out the docClient.query call it works and returns stuff to the browser (just the one line messages though). When I include it fails and I get the following message from SAM:
Function 'TableGetTest' timed out after 3 seconds
Function returned an invalid response (must include one of: body, headers or statusCode in the response object). Response received: b''
Any help or pointers would be appreciated.
Turns out this was a connection error. It would appear that the instance of SAM-Local cannot connect to the local instance of dynamoDB.
I'm now looking at how I get SAM-Local access to the local machine (it can't seem to see outside of its container).
I'm trying to use Azure Mobile Service to process / handle GET and POST requests on an empty data table. (really just using the mobile service as a pass through)
As part of this I'm trying to forward the request to another url and receive the response back and return it via mobile service. I've figured out the GET part shown below but I'm having trouble the POST part.
GET Part:(Which works)
function read(query, user, request)
{
var p = request.parameters;
var httpRequest = require('request');
var url = 'http://someURL/'+ p.ssoid;
httpRequest.get(url, function(err, response, body)
{
if (err)
{
request.respond(500, "INTERNAL SERVER ERROR");
}
else
{
request.respond(200,JSON.parse(body) );
}
});
}
Post Code:(Does not work)
function insert(item, user, request)
{
var p = request.parameters;
require('request').post({
uri:'http://someURL/',
headers:{'content-type': 'application/json'},
body:p.body
},function(err,res,body){
if (err)
{
request.respond(500, "INTERNAL SERVER ERROR");
}
else
{
request.respond(200,"Success");
}
});
}
I know the POST requires a body with the post information, but how to I get it to pass forward?
On an insert, the body of the request will be stored in the item argument (assuming you're passing a JSON object). So your function would look something like this:
function insert(item, user, request)
{
var p = request.parameters;
require('request').post({
uri : 'http://someURL/',
headers : {'Content-Type': 'application/json'},
body : item
}, function(err, res, body){
if (err)
{
request.respond(500, "INTERNAL SERVER ERROR");
}
else
{
request.respond(200,"Success");
}
});
}
On a related note, if you're using the mobile service as a simple pass-through, you can also consider using a custom API instead of a table, where you can also apply your logic without having any (empty) table behind it.
function insert(item, user, request)
{
var p = request.parameters;
require('request').post({
uri : 'http://someURL/',
headers : {'Content-Type': 'application/json'},
body : JSON.stringify(item)
}, function(err, res, body){
if (err)
{
request.respond(500, "INTERNAL SERVER ERROR");
}
else
{
request.respond(200,"Success");
}
});
}