Invoking a webpage using Lambda with node.js - aws-lambda

I am learning AWS and as part of that I am trying to create a Lambda using node.js.
I am trying to invoke a webpage using the following, please correct me. What I am missing?
const opn = require('opn');
opn('http://google.com', {app: 'firefox'});

I wrote up a post detailing how to set this up if you only want to hit URLs with Lambda. You can find it here.
If you already know how to setup IAM permissions and scheduling with CloudWatch, the code I used accomplished this with Node.js 6.10 runtime:
exports.handler = (event, context, callback) => {
var urls = event.urls;
var http = require("http");
var https = require("https");
for (var i = 0; i < urls.length; i++) {
var protocol = urls[i].Protocol;
var domain = urls[i].Domain;
var queryString = urls[i].QueryString;
var url = protocol + "://" + domain + queryString;
if (protocol.toLowerCase() === "http") {
var j = i;
http.get(url, function(res) {
// Get around async.
var requestUrl = urls[j].Protocol + "://" + urls[j].Domain + urls[j].QueryString;
console.log("Response from " + requestUrl + ": ");
console.log(res.statusCode);
console.log(res.statusMessage);
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
} else if (protocol.toLowerCase() === "https") {
https.get(url, function(res) {
var j = i;
// Get around async.
var requestUrl = urls[j].Protocol + "://" + urls[j].Domain + urls[j].QueryString;
console.log("Response from " + requestUrl + ": ");
console.log(res.statusCode);
console.log(res.statusMessage);
}).on('error', function(e) {
console.log("Encountered error: " + e.message);
});
}
// Force break due to async -> output.
if ((i+1) == urls.length) {
break;
}
}
};
You would define the URLs you would like to invoke by passing an event object that is similar to the following:
{"urls": [{
"Protocol": "HTTP",
"Domain": "www.aaronmedacco.com",
"QueryString": ""}, {
"Protocol": "HTTPS",
"Domain": "www.google.com",
"QueryString": "?key=value"}]}
Again, if you want a step by step, check out this post. Simple to set up.

Related

nativescript-background-http issue

I tried implementing image upload page for my app, but unfortunately the request is not reaching the server. I double checked this using tcpdump on the server side. The code doesnt seem to process beyond session.uploadFile in sendImages function
Please let me know if there is any issue with the code
var imageSource = require("image-source");
var frameModule = require("ui/frame");
var Observable = require("data/observable").Observable;
var fromObject = require("data/observable").fromObject;
var ObservableArray = require("data/observable-array").ObservableArray;
var platformModule = require("platform");
var permissions = require("nativescript-permissions");
var imagepickerModule = require("nativescript-imagepicker");
var bghttpModule = require("nativescript-background-http");
var session = bghttpModule.session("image-upload");
var fs = require("file-system");
var page;
var imageName;
var counter = 0;
function pageLoaded(args) {
page = args.object;
}
function onSelectSingleTap(args) {
var context = imagepickerModule.create({
mode: "single"
});
if (platformModule.device.os === "Android" && platformModule.device.sdkVersion >= 23) {
permissions.requestPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE, "I need these permissions to read from storage")
.then(function () {
console.log("Permissions granted!");
startSelection(context);
})
.catch(function () {
console.log("Uh oh, no permissions - plan B time!");
});
} else {
startSelection(context);
}
}
function sendImages(uri, fileUri) {
imageName = extractImageName(fileUri);
var request = {
url: "http://maskingIpForPost:8081/mobilepic/ctk/uploadpic",
method: "POST",
headers: {
"Content-Type": "application/octet-stream",
"file-Name": imageName,
"uid": 30
},
description: "{ 'uploading': " + imageName + " }"
};
var task = session.uploadFile(fileUri, request);
task.on("progress", progress);
task.on("error", error);
task.on("complete", complete);
task.on("responded", responded);
function responded(e) {
console.log("eventName: " + e.eventName);
console.log("data: " + e.data);
}
function progress(e) {
console.log("currentBytes: " + e.currentBytes);
console.log("totalBytes: " + e.totalBytes);
console.log("eventName: " + e.eventName);
}
function error(e) {
console.log("eventName: " + e.eventName);
console.log("eventName: " + e.responseCode);
console.log("eventName: " + e.response);
}
function complete(e) {
console.log("eventName: " + e.eventName);
console.log("response: " + e.responseCode);
}
return task;
}
function startSelection(context) {
context
.authorize()
.then(function () {
return context.present();
})
.then(function (selection) {
selection.forEach(function (selected_item) {
var localPath = null;
if (platformModule.device.os === "Android") {
localPath = selected_item._android;
} else {
// selected_item.ios for iOS is PHAsset and not path - so we are creating own path
let folder = fs.knownFolders.documents();
let path = fs.path.join(folder.path, "Test" + counter + ".png");
//let saved = imagesource.saveToFile(path, "png");
localPath = path;
}
alert("final path " + localPath);
if (localPath) {
var task = sendImages("Image" + counter + ".png", localPath);
//mainViewModel.get("items").push(fromObject({ thumb: imagesource, uri: "Image" + counter + ".png", uploadTask: task }));
}
counter++;
});
}).catch(function (e) {
console.log(e.eventName);
});
}
function extractImageName(fileUri) {
var pattern = /[^/]*$/;
var imageName = fileUri.match(pattern);
return imageName;
}
exports.pageLoaded = pageLoaded;
exports.onSelectSingleTap = onSelectSingleTap;
On Further research found the following
net.gotev.uploadservice.UploadService is undefined in background-http.android.js. At this moment i am not sure what this means. Would appreciate if anyone has idea about this
You need to change the following line in your code.
var session = bghttpModule.session("image-upload");
It has to be file upload
var session = bghttpModule.session("file-upload");
Just tested your code by using Azure Blob Storage PUT url at my side and got the below response.
ActivityManager: START u0 {act=android.intent.action.OPEN_DOCUMENT typ=image/* cmp=com.android.documentsui/.DocumentsActivity (has extras)} from pid 2835
JS: currentBytes: 4096
JS: totalBytes: 25220
JS: eventName: progress
JS: currentBytes: 25220
JS: totalBytes: 25220
JS: eventName: progress
JS: currentBytes: 25220
JS: totalBytes: 25220
JS: eventName: progress
JS: eventName: responded
JS: data:
JS: eventName: complete
JS: response: 201
thanks for the quick response, i tried running it on a emulator and i faced the above mentioned issue, i tried the same by connecting a device and it worked just fine.

My jquery and ajax call is not responding and showing unexpected error in console

I don't know why my code is giving error while making the ajax call and not responding or working at all. I ran this on an html file. I took this function - getParameterByName() from another stackoverflow answer.tweet-container tag is down the code below outside this script and an empty division.I tried some jquery also.
<script>
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
$(document).ready(function(){
console.log("working");
var query = getParameterByName("q")
// console.log("query");
var tweetList = [];
function parseTweets(){
if (tweetList == 0){
$("#tweet-container").text("No tweets currently found.")
} else {
//tweets are existing, so parse and display them
$.each(parseTweets, function(key, value){
//console.log(key)
// console.log(value.user)
// console.log(value.content)
var tweetKey = value.key;
var tweetUser = value.user;
var tweetContent = value.content;
$("#tweet-container").append(
"<div class=\"media\"><div class=\"media-body\">" + tweetContent + "</br> via " + tweetUser.username + " | " + View + "</div></div><hr/>"
)
})
}
}
$.ajax({
url:"/api/tweet/",
data:{
"q": query
},
method: "GET",
success:function(data){
//console.log(data)
tweetList = data
parseTweets()
},
error:
function(data){
console.log("error")
console.log(data)
}
})
});
</script>
strong text
Fix the quotes to resolve your syntax error:
$("#tweet-container").append("<div class=\"media\"><div class=\"media-body\">" + tweetContent + " </br> via " + tweetUser.username + " | " + "View</div></div><hr/>")

Execute multiple http request - Parse Cloud Code

i have an array of stores, where the address and some other things are stored.
Now I want to iterate through this array and geocode the lat / lng coords and save them to the database.
With the code below I get double or triple entries of the same store. Do I miss something with the scope here?
Thanks!
var promises = [];
data.forEach(function (element, index)
{
var addressString = element.plz + " " + element.stadt + "," + element.adresse;
var url = encodeURI("https://maps.googleapis.com/maps/api/geocode/json?address=" +
addressString);
var promise = Parse.Cloud.httpRequest({
method: "GET",
url:url
}).then(function (http) //SUCCESS
{
var geocodedObject = new Parse.Object("GeocodedStores");
geocodedObject.set("storeID", element.id);
geocodedObject.set("Latitude", http.data.results[0].geometry.location.lat);
geocodedObject.set("Longitude", http.data.results[0].geometry.location.lng);
return geocodedObject.save(null, {
useMasterKey: true
});
},
function (http, error)
{
response.error(error);
});
promises.push(promise);
});
return Parse.Promise.when(promises);
Finally found a working solution. It looked like it was a problem with the scope. I put the code in a seperate function and added this returned promise to an array.
var fn = function(element, geocodedObject)
{
var addressString = element.plz + " " + element.stadt + "," + element.adresse;
var url = encodeURI("https://maps.googleapis.com/maps/api/geocode/json?address=" +
addressString);
Parse.Cloud.httpRequest({
method: "GET",
url: url
}).then(function(http)
{
geocodedObject.set("storeID", element.id);
geocodedObject.set("Latitude", http.data.results[0].geometry.location.lat);
geocodedObject.set("Longitude", http.data.results[0].geometry.location.lng);
geocodedObject.set("address", addressString);
return geocodedObject.save(null, {
useMasterKey: true
});
});
}
var promises = [];
for (var k = 0;k<data.length;k++)
{
var geocodedObject = new Parse.Object("GeocodedStores");
promises.push(fn(data[k], geocodedObject));
}
Parse.Promise.when(promises).then(function () {
response.success("DONE");
});

Sending Data to a Server using JavaScript (Firefox Addon)

I would like to send some data to an external server within an Firefox extension.
I tried this code snippet but it doesn’t work, due to Same-Origin-Policy.
$.ajax({
type: "POST",
url: 'https://127.0.0.1:54321',
data: ({foo: "bar"}),
crossDomain: true,
dataType: 'json'
}).done(function () {
alert("done");
}).fail(function(xhr, status, error) {
// var err = eval("(" + xhr.responseText + ")");
alert((xhr.responseText));
});
Since this does not work, I tried this tutorial:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
That got me this piece of code:
var invocation = new XMLHttpRequest(); var url = 'https://127.0.0.1:54321';
invocation.open('POST', url, true);
invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
invocation.setRequestHeader('Content-Type', 'application/xml');
invocation.onreadystatechange = handler;
invocation.send(document.body);
This code also doesn't work and Firefox prompts that I should use CORS.
The weird thing is that it works if I don't use HTTPS (on non-HTTPS sites).
Note: On https://127.0.0.1:54321 runs a Java SSLServerSocket.
Copy paste this:
var {Cu, Cc, Ci} = require('chrome'); //addon-sdk way
//var {Cu: utils, Cc: classes, Ci: instances} = Components; //non addon-sdk
Cu.import('resource://gre/modules/Services.jsm');
function xhr(url, cb) {
let xhr = Cc["#mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
let handler = ev => {
evf(m => xhr.removeEventListener(m, handler, !1));
switch (ev.type) {
case 'load':
if (xhr.status == 200) {
cb(xhr.response);
break;
}
default:
Services.prompt.alert(null, 'XHR Error', 'Error Fetching Package: ' + xhr.statusText + ' [' + ev.type + ':' + xhr.status + ']');
break;
}
};
let evf = f => ['load', 'error', 'abort'].forEach(f);
evf(m => xhr.addEventListener(m, handler, false));
xhr.mozBackgroundRequest = true;
xhr.open('GET', url, true);
xhr.channel.loadFlags |= Ci.nsIRequest.LOAD_ANONYMOUS | Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_PERSISTENT_CACHING;
//xhr.responseType = "arraybuffer"; //dont set it, so it returns string, you dont want arraybuffer. you only want this if your url is to a zip file or some file you want to download and make a nsIArrayBufferInputStream out of it or something
xhr.send(null);
}
xhr('https://www.gravatar.com/avatar/eb9895ade1bd6627e054429d1e18b576?s=24&d=identicon&r=PG&f=1', data => {
Services.prompt.alert(null, 'XHR Success', data);
var file = OS.Path.join(OS.Constants.Path.desktopDir, "test.png");
var promised = OS.File.writeAtomic(file, data);
promised.then(
function() {
alert('succesfully saved image to desktop')
},
function(ex) {
alert('FAILED in saving image to desktop')
}
);
});

docpad plugins server.extend argument options not containing any express middleware with last version of docpad

I faced problems using minicms docpad plugin with last version of docpad. This plugin implements server.extend function which is being passed an opts object containing the express module used by docpad (during its plugin initialisation process). Minicms plugin is making use of a bunch of expressJS middleware :
express.static()
express.cookieParser()
express.cookieSession()
Unfortunately none of those middleware functions are available in the opts.express object and i'm wondering if there's been some changes in the recent docpad versions. Is there any workaround or docpad configuration i should be aware of ?
minicms.plugin.js code
// Generated by IcedCoffeeScript 1.3.3g
(function() {
var YAML, applyContext, cc, deepCopy, exec, fs, gm, sessionBridge, shellEscape, slugify, uuid,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
slugify = require('./utils/slugify');
cc = require('coffeecup');
uuid = require('node-uuid');
gm = require('gm');
fs = require('fs');
exec = require('child_process').exec;
shellEscape = require('./utils/shellEscape');
deepCopy = require('owl-deepcopy').deepCopy;
YAML = require('yamljs');
applyContext = require('./utils/applyContext');
sessionBridge = require('./utils/sessionBridge');
module.exports = function(BasePlugin) {
var MinicmsPlugin;
return MinicmsPlugin = (function(_super) {
__extends(MinicmsPlugin, _super);
function MinicmsPlugin() {
return MinicmsPlugin.__super__.constructor.apply(this, arguments);
}
MinicmsPlugin.prototype.name = 'minicms';
MinicmsPlugin.prototype.config = {
prefix: {
url: 'cms',
meta: 'cms'
},
validate: require('./utils/validate'),
sanitize: require('./utils/sanitize')
};
MinicmsPlugin.prototype.docpadReady = function(opts) {
return this.docpad.action('watch', {}, function(err) {
var _ref;
if (err) {
process.stderr.write(("" + ((_ref = err.message) != null ? _ref : err)).trim() + "\n");
}
return this.docpad.log("Force watching file for minicms.");
});
};
MinicmsPlugin.prototype.serverExtend = function(opts) {
var app, config, docpad, express;
app = opts.server;
express = opts.express; // express module
console.log(opts.express._router.middleware);
docpad = this.docpad;
config = this.config;
exec("rm -rf " + (shellEscape(docpad.config.srcPath + '/files/tmp')), function() {});
app.use('/' + this.config.prefix.url, express["static"](__dirname + '/static')); // express.static middleware
if (!(this.config.secret != null)) {
throw "Secret is required for cookie sessions (minicms)";
}
app.use(express.cookieParser()); // express.cookieParser middleware
app.use(express.cookieSession({ // express.cookieSession middleware
secret: this.config.secret
}));
app.get('/' + this.config.prefix.url + '/logout', require('./routes/logout').bind(this));
app.get('/' + this.config.prefix.url + '/login', require('./routes/login').bind(this));
app.post('/' + this.config.prefix.url + '/login', require('./routes/loginSubmit').bind(this));
app.get('/' + this.config.prefix.url, require('./routes/root').bind(this));
app.get('/' + this.config.prefix.url + '/:content/list', require('./routes/list').bind(this));
app.get('/' + this.config.prefix.url + '/:content/edit', require('./routes/edit').bind(this));
app.post('/' + this.config.prefix.url + '/:content/edit', require('./routes/edit').bind(this));
app.post('/' + this.config.prefix.url + '/generate', require('./routes/generate').bind(this));
console.log('/' + this.config.prefix.url + '/:content/:field/upload');
app.post('/' + this.config.prefix.url + '/:content/:field/upload', require('./routes/upload').bind(this));
};
return MinicmsPlugin;
})(BasePlugin);
};
}).call(this);

Resources