Aws JSON Lambda function, 'date-holiday' package - json

I am building an AWS Lambda function that emails the S3 location of call recordings to a mailbox if the office is out of hours. I can get it to send emails if any call is made but when I enter the conditions I fall down. I want the function to only operate on holidays and outside office hours(Christmas, bank holiday.....). I haven't tried weekends yet but I know how to go about doing that. I want to use the 'date-holidays' package but I am having trouble getting it to work. I can get the emails to send if it is not between 9 & 5 but I cannot get them to send if it is say Christmas day.
Or if there is an easier way, please suggest
var aws = require('aws-sdk');
var ses = new aws.SES({
region: 'us-west-2'
});
var time = new Date().getHours();
var td = new Date().getDate();
const s3 = new aws.S3({
apiVersion: '2006-03-01'
});
if (time > 17 || time < 9){
if (td == hd){
exports.handler = function(event, context, callback) {
console.log("Incoming: ", event);
const bucket = event.Records[0].s3.bucket.name;
const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
const now = new Date();
const news = `Event took place in https://s3.console.aws.amazon.com/s3/object/${bucket}/${key}`;
const params = {
Bucket: bucket,
Key: key,
};
var eParams = {
Destination: {
ToAddresses: ["***********.com"]
},
Message: {
Body: {
Text: {
Data: `${news}`
}
},
Subject: {
Data: `Voicemail notification for ${now}`
}
},
Source: "*************.com"
};
console.log('===SENDING EMAIL===');
var email = ses.sendEmail(eParams, function(err, data) {
if (err) console.log(err);
else {
console.log("===EMAIL SENT===");
// console.log(data);
console.log("EMAIL CODE END");
console.log('EMAIL: ', email);
context.succeed(event);
}
});
}
}
};

I'm not sure what trouble you have it with 'date-holidays', you could try uploading node_modules folder also with Lambda and test (there is a data/holidays.json file)
var Holidays = require('date-holidays')
hd = new Holidays('US', 'la', 'no')
if(hd.isHoliday(--now--)) {
}

Related

How to hand an object from backend to frontend

I try to create a Web App. Therefor I have to pass an Object from the backend to the HTML-Script. I tried a lot of possibilites but nothing worked.
Backend
function searchMain (allSeaVal) {
var headCon = DbSheet.getRange(1, 1, 1, DbSheet.getLastColumn()).getValues();
var bodyCon = DbSheet.getRange(valRow, typesCol, 1, DbSheet.getLastColumn()).getValues();
var Con = {
headline: headCon,
values: bodyCon
};
var tmp = HtmlService.createTemplateFromFile('page_js');
tmp.Con = Con.map(function(r){ return r; });
return tmp.evaluate();
}
HTML
<script>
function searchValues() {
var allSeaVal = {};
allSeaVal.seaType = document.getElementById('valSearchTyp').value;
allSeaVal.seaVal = document.getElementById('HSearchVal').value;
google.script.run.searchMain(allSeaVal);
Logger.log(Con);
}
<script/>
I want to use the information in "Con" in the Website. The script-code is stored in the file "page_js.
I don´t know why but I can´t pass the information into the frontend.
In your html interface you have to use the success and failure handler in your google.script.run.
Code will looks like
google.script.run
.withSuccessHandler(
function(msg) {
// Respond to success conditions here.
console.log('Execution successful.');
})
.withFailureHandler(
function(msg) {
// Respond to failure conditions here.
console.log('Execution failed: ' + msg, 'error');
})
.searchMain(allSeaVal);
Do not hesitate to check the documentation : https://developers.google.com/apps-script/guides/html/communication
Stéphane
I solved my problem with your help. Thank you so much. I struggled with this many days.
My solution is the code below.
Backend
function searchMain (allSeaVal) {
var typesCol = searchTypesCol(allSeaVal.seaType);
var valRow = searchRow(allSeaVal.seaVal, typesCol);
var headCon = DbSheet.getRange(1, 1, 1, DbSheet.getLastColumn()).getValues();
var bodyCon = DbSheet.getRange(valRow, typesCol, 1, DbSheet.getLastColumn()).getValues();
var Con = {
headline: headCon,
values: bodyCon
};
return Con;
}
HTML
function searchValues() {
var allSeaVal = {};
allSeaVal.seaType = document.getElementById('valSearchTyp').value;
allSeaVal.seaVal = document.getElementById('HSearchVal').value;
google.script.run
.withSuccessHandler(
function(Con) {
console.log(Con + 'success');
})
.withFailureHandler(
function(Con) {
console.log(Con + 'failure');
})
.searchMain(allSeaVal);
}

Loopback unable to create and do operations on related models in model JS file

Unable to create relation in model.js file while through model.json file, it's working fine. I want to update booking table field on any updation in bidding table but my relation is not working in model.js file.
Bidding.belongsTo(Booking, {foreignKey: 'bookingId'});
^
ReferenceError: Booking is not defined
{
"error": {
"statusCode": 500,
"name": "TypeError",
"message": "Bidding.booking is not a function",
"stack": "TypeError: Bidding.booking is not a function\n.."
}
}
'use strict';
//var loopback = require('loopback');
//var boot = require('loopback-boot');
//var app = module.exports = loopback();
module.exports = function(Bidding) {
// var app = require('../../server/server');
// var Booking = app.models.Booking;
//Bidding.belongsTo(Myuser, {foreignKey: 'driver_id'});
Bidding.belongsTo(Booking, {foreignKey: 'bookingId'});
Bidding.observe('before save', function beforeSave(ctx, next) {
if (ctx.instance) {
//on create
ctx.instance.created = new Date();
ctx.instance.modified = new Date();
} else {
// on edit
// ctx.instance.lastUpdated = new Date();
console.log('updatesdd');
//Bidding.Booking.upsertWithWhere({id: ctx.instance.id},{ 'username': username}, function(err, results) {});
Bidding.booking(function(err, booking) {
console.log(ctx.booking);
});
}
next();
});
Bidding.observe('loaded', function beforeaccess(ctx, next) {
console.log(ctx.data);
next();
});
};
By following way you can perform the operations on your relates tables. I go through inbuilt user.js file where they have relation with AccessToken table and find the following solution for my problem.
Query which load you related table -
Here "booking" model has belongs to relation define in bidding.json
var booking = ctx.Model.relations.booking.modelTo;
Update Query call through StrongLoop API Explorer:
http://0.0.0.0/api/Biddings/update?where=%7B%22id%22%3A%2211%22%2C%22bookingId%22%3A6%7D
Where: {"id":"11","bookingId":6}
data: {"bid_status":"Accept"}
Bidding.observe('before save', function beforeSave(ctx, next) {
if (ctx.instance) {
//on create
ctx.instance.created = new Date();
ctx.instance.modified = new Date();
} else {
//on update
if(ctx.data.bid_status == "Accept");
{
if (ctx.where && ctx.where.bookingId && ctx.where.id) {
var bookingId = ctx.where.bookingId;
var booking = ctx.Model.relations.booking.modelTo;
booking.upsertWithWhere({id: bookingId},{ 'booking_status': 'Confirmed'}, function(err, results) {});
}
}
}
next();
});

sensor data is not uploading on artik cloud

I am trying to send sensor data to artik cloud via node.js. (using web socket and serial port). But its sending null. Anyone knows the reason? I just copied the code from tutorial so there is no syntax error.
var webSocketUrl = "wss://api.artik.cloud/v1.1/websocket?ack=true";
var device_id = "####";
var device_token = "#####";
var isWebSocketReady = false;
var ws = null;
var serialport = require("serialport");
var portName = 'COM5';
var sp= new serialport.SerialPort(portName, {
baudRate: 9600,
parser: serialport.parsers.readline("\r\n")
});
var WebSocket = require('ws');
/**
* Gets the current time in millis
*/
function getTimeMillis(){
return parseInt(Date.now().toString());
}
/**
* Create a /websocket bi-directional connection
*/
function start() {
//Create the websocket connection
isWebSocketReady = false;
ws = new WebSocket(webSocketUrl);
ws.on('open', function() {
console.log("Websocket connection is open ....");
register();
});
ws.on('message', function(data, flags) {
console.log("Received message: " + data + '\n');
});
ws.on('close', function() {
console.log("Websocket connection is closed ....");
});
}
/**
* Sends a register message to the websocket and starts the message flooder
*/
function register(){
console.log("Registering device on the websocket connection");
try{
var registerMessage = '{"type":"register", "sdid":"'+device_id+'", "Authorization":"bearer '+device_token+'", "cid":"'+getTimeMillis()+'"}';
console.log('Sending register message ' + registerMessage + '\n');
ws.send(registerMessage, {mask: true});
isWebSocketReady = true;
}
catch (e) {
console.error('Failed to register messages. Error in registering message: ' + e.toString());
}
}
/**
* Send one message to ARTIK Cloud
*/
function sendData(temperature){
try{
// ts = ', "ts": '+getTimeMillis();
var data = {
"temp": temperature
};
var payload = '{"sdid":"'+device_id+'", "data": '+JSON.stringify(data)+', "cid":"'+getTimeMillis()+'"}';
console.log('Sending payload ' + payload);
ws.send(payload, {mask: true});
} catch (e) {
console.error('Error in sending a message: ' + e.toString());
}
}
/**
* All start here
*/
start(); // create websocket connection
sp.on("open", function () {
sp.on('data', function(data) {
if (!isWebSocketReady){
console.log("WebSocket is not ready. Skip sending data to ARTIK Cloud (data:" + data +")");
return;
}
console.log("Serial port received data:" + data);
//var parsedStrs = data.split(",");
var temperature = parseInt(data);
sendData(temperature);
});
});
If you reference our First IoT Sample:
https://developer.artik.cloud/documentation/tutorials/your-first-iot-device.html
The node.js sample sends the value from the temperature sensor. As a dependency it requires a connected Arduino, Raspberry Pi, and a DHT temperature sensor located at the right pin. If you are seeing null "before" sending the data to ARTIK Cloud, you are not getting any value from the sensor.
In particular, output and print to console the "temperature" value from the following function in case of any parsing errors:
function sendData(temperature) //...
Email us at developer#artik.cloud if you need additional information.
Thanks!
In this line:
var temperature = parseInt(data);
If you're getting empty or non numeric data (you can verify this in the previous line where you're logging the variable's content), then temperature will be NaN (not a number). Then, when you build the JSON payload for Artik Cloud, you'll end up with something like:
{
"sdid": "cbd3f844967d464da3c4f4989f80f86c",
"data": {
"temp":null
},
"cid":"1495817841624"
}
Because the JSON.stringify of:
{"temp":NaN}
would be translated to:
{"temp":null}

Jawbone API Paginated Results with 'page_token'

The Jawbone API returns paginated results of 10 json objects per result set. How does one obtain the rest of the paginated results?
The API documentation for the sleeps method indicates the existence of a page_token argument in the next object of the result set. My output below is missing this. Furthermore,the FAQ indicates this page_token takes an INT (presumably epoch) timestamp.
2nd: "page_token" parameter: if the request contains the "page_token" parameter, the API will return all the workouts, in
reverse order, (capped by "limit" or default of 10) that were
completed before that page_token. The page_token is a timestamp, and
there's a special case, when the request comes with page_token=0 which
is interpreted as passing page_token = CURRENT_TIMESTAMP, ie, give all
the workouts (with a limit)
I am able to authenticate with the API and return a set of 10 results (first paginated page)... but no page_token.
...snip json...
"links": {
"next": "/nudge/api/v.1.0/users/jMdCUPXZ-InYXo1kcdOkvA/sleeps?start_time=1424699101&updated_after=0&limit=10&end_time=1438723789"
},
"size": 10
Have I misunderstood the documentation? Could it be the documentation is out of date (wrong)? Or more likely, I'm completely misunderstanding this and writing horrible JS for my node.js ...
Can someone set me straight and show me how I can retrieve ALL results, not just the first page?
var express = require('express');
var app = express();
var port = process.env.PORT || 5000;
var passport = require('passport');
var config = require('./config.json');
var ejs = require('ejs');
var https = require('https');
var fs = require('fs');
var bodyParser = require('body-parser');
var jbStrategy = require('passport-oauth').OAuth2Strategy;
var jsonfile = require('jsonfile');
var util = require('util');
var path = require('path');
/* Calculate date range */
var $today = new Date()
var $start = new Date($today); $start.setDate($today.getDate() - 180);
var $end = new Date($today);
var $startDate = Math.floor(($start).getTime()/1000);
var $endDate = Math.floor(($end).getTime()/1000);
app.use(express.logger('dev')); // log every request to the console
app.use(bodyParser.json()); // read cookies (needed for auth)
app.use(express.static(__dirname + '/public'));
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
app.use(passport.initialize());
/* Default Authentication Path */
app.get('/',
passport.authorize('jawbone', {
scope : config.jawboneAuth.scope,
failureRedirect: '/'
})
);
/* oauth callback from jawbone */
app.get('/done', passport.authorize('jawbone', {
scope : config.jawboneAuth.scope,
failureRedirect: '/'
}), function(req, res) {
var result = JSON.parse(body); console.log(result);
res.redirect('/sleeps');
}
);
app.get('/sleeps', function(req, res) {
var options = {
access_token : config.jawboneAuth.accessToken,
refresh_token : config.jawboneAuth.refreshToken,
client_id : config.jawboneAuth.clientID,
client_secret : config.jawboneAuth.clientSecret
};
if (!config.jawboneAuth.accessToken) {
// if there's no accessToken, go get one
res.redirect('/');
} else {
var up = require('jawbone-up')(options);
var page_token = [];
do {
up.sleeps.get({
page_token : page_token,
start_time : $startDate,
end_time : $endDate
}, function(err, body) {
if (err) {
console.log('Error receiving Jawbone UP data');
res.send(err);
} else {
try {
var result = JSON.parse(body);
var next_page_path = result.data.links.next;
//var next_page_token = next_page_path.split(path.sep);
//var page_token = next_page_token[5];
//page_token = result.data.links.next
console.log(result.data);
res.json(result);
} // end try
catch(err) {
console.log(err);
res.render('userdata', {
requestTime: 0,
jawboneData: 'Unknown result'
});
} // end catch(err)
} // end else
} //end callback fun
); // end up.sleeps.get()
} // end do
while(page_token[0] > 1);
} // end if
}); // end sleeps route
// Setup the passport jawbone authorization strategy
passport.use('jawbone', new jbStrategy({
clientID : config.jawboneAuth.clientID,
clientSecret : config.jawboneAuth.clientSecret,
authorizationURL: config.jawboneAuth.authorizationURL,
tokenURL : config.jawboneAuth.tokenURL,
callbackURL : config.jawboneAuth.callbackURL,
scope : config.jawboneAuth.scope,
passReqToCallback : true
}, function(req, accessToken, refreshToken, profile, done) {
// establish a pseudo user session.
var user = {};
// If there's no preexisting accessToken,
// write one to the config file.
if (!config.jawboneAuth.accessToken){
config.jawboneAuth.accessToken = accessToken;
config.jawboneAuth.refreshToken = refreshToken;
jsonfile.writeFile('./config.json', config, {spaces: 2}, function(err) {
console.error(err);
})
}
done(null, user);
}));
// HTTPS
var sslOptions = {
key : fs.readFileSync('./.server.key'),
cert : fs.readFileSync('./.server.crt')
};
var secureServer = https.createServer(sslOptions, app).listen(port, function(){
console.log('Listening on ' + port);
});
Turns out there is an undocumented limit parameter that has replaced the page_token.
The Jawbone Developer documentation is currently out of date. As is their FAQ (API section Question# 12).
A GET request like this seems to do the trick
https://jawbone.com/nudge/api/v.1.1/users/#me/sleeps?start_time=1388603458&end_time=1420139458&limit=1000

Connect existing MySql table with Strongloop

I am trying to create an REST API which should connect to an existing table in mysql database and return the data with respective to the parameter we send.
Actually nodejs and strongloop is new to me, this is first time am working with them. I have followed their docs and created a table in mysql my running a file like below
I have followed the commands to create model, properties etc from the below github docs
https://github.com/strongloop/loopback-example-database
create-test-data.js
var server = require('./server');
var dataSource = server.dataSources.accountDB;
var Account = server.models.account;
var accounts = [
{ email: 'foo#bar.com',
created: new Date(),
modified: new Date()
}, {
email: 'bar#bar.com',
created: new Date(),
modified: new Date()
} ];
var count = accounts.length;
dataSource.automigrate('account', function(er) {
if (er) throw er;
accounts.forEach(function(account) {
Account.create(account, function(er, result) {
if (er) return;
console.log('Record created:', result);
count--;
if(count === 0) {
console.log('done');
dataSource.disconnect();
}
});
});
});
This automatically creating table and records in my database, I don't want this.
Actually I already have a different table, which I want to connect with strongloop.
I am completely clueless, any help would be appreciated.
I found this trying to do the same thing. I fixed it so it would end gracefully. Works great for me.
Original: https://gist.github.com/serkanserttop/64fc2d4465fb154066db#file-discover-js
var path = require('path');
var app = require(path.resolve(__dirname, '../server'));
var fs = require('fs');
var loopback = require('loopback');
var app_dir = './';
require('node-babel')();
var dataSource = app.dataSources.accountDs;
var db = 'myDB',
owner = 'root';
function capitaliseFirstLetter(string) {
return string.charAt(0)
.toUpperCase() + string.slice(1);
}
function jsFileString(model_name) {
return '' + 'module.exports = function(' + capitaliseFirstLetter(model_name) + ') {\n' + '\t\n' + '};';
}
function autoGenerateModelFiles() {
dataSource.discoverModelDefinitions({
schema: db
}, function(err, models) {
var count = models.length;
console.log(models.length);
models.forEach(function(model) {
dataSource.discoverSchema(model.name, {
associations: true
}, function(err, schema) {
if (schema.options.mysql.schema !== db) {
console.log('options.mysql.schema !== db', schema);
}
fs.writeFile(app_dir + 'common/models/' + model.name + '.json', JSON.stringify(
schema, null, ' '), function(err) {
if (err) throw err;
console.log('Saved ' + model.name);
});
fs.writeFile(app_dir + 'common/models/' + model.name + '.js', jsFileString(
model.name), function(err) {
if (err) throw err;
console.log('Created ' + model.name + '.json file');
});
count = count - 1;
if (len === 0) {
console.log("DONE!", count);
dataSource.disconnect();
return;
}
});
});
});
}
What you actually need is to discover model from database. There is a documentation available on a strongloop page.
http://docs.strongloop.com/display/public/LB/Discovering+models+from+relational+databases;jsessionid=1FC0E473B7F589F4F1EFC0F25D269E3E
http://docs.strongloop.com/display/public/LB/Database+discovery+API
Here is a working example:
var ds = app.dataSources.accountDB;
ds.discoverModelDefinitions(function (err, models) {
models.forEach(function (model) {
ds.discoverSchema( model.name, function (err, schema){
console.log(schema);
});
});
});
Put this code somewhere inside server.js (i.e. inside boot method). I assume that you have setup datasource correctly and also have loppback mysql connector installed.This will loop through all tables and "schema" will contain model definition discovered from database.
You can use slc arc to generate the models based on your MySQL tables, after that you should be able to use the API to perform the basic CRUD operations. In the following link you can find more information about it:
https://strongloop.com/node-js/arc/