Newbie to sharepoint , I have a sharepoint list with Date(Calender) field. Iam looking at a way to restrict only 4 entries per day in the list.
Example:
Date desc
01/01/2018 entry1
01/01/2018 entry2
01/01/2018 entry3
01/01/2018 entry4
or
Date start end desc
01/01/2018 10:00 10:15 entry1
01/01/2018 10:15 10:30 entry2
01/01/2018 10:30 10:45 entry3
01/01/2018 10:45 11:00 entry4
Any suggestions or leads will be helpful.
For SharePoint 2013 or online classic view, you could use PreSaveAction.
Sample code:
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
<script type="text/javascript">
function PreSaveAction() {
var check = false;
var listid = _spPageContextInfo.pageListId.replace('{', '').replace('}', '');
var today = new Date();
var nextday = moment(today).add(1, 'days');
today = moment(today).format("YYYY-MM-DD");
var currentDate = today + 'T00:00:00.000Z';
nextday = moment(nextday).format("YYYY-MM-DD");
var nextDate = nextday + 'T00:00:00.000Z';
var url = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists(guid'" + listid + "')/items?$filter=Created ge datetime'" + currentDate + "' and Created le datetime'" + nextDate + "'";
console.log(url);
$.ajax({
url: url,
type: 'GET',
async: false,
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
},
success: function (data, textStatus, jqXHR) {
var count = data.d.results.length;
if (count < 4) {
check = true;
} else {
alert('Over Max items');
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert(textStatus);
}
})
return check;
}
</script>
Related
Update: I successfully got it to post events between two dates. The problem is I set the two dates to year-month-dayT00:00:00.000Z and year-month-dayT23:59:59.999Z. but it sends events from the previous day and the day I set it to. See code snippets after everything else.
Original:
I use discord a lot in communications and now I am part of a robotics team that would like to use it as well. The only problem is, it doesn't work with Google calendar. So I looked around a bit to see if i could find a bot that i could use. There are a few out there but non of them are that great. So I decided to make my own. I am using node.js and the google calendar api.
So far I have gotten the authentication of the calendar down so that works. But now I am trying to figure out how to get daily updates in a discord channel. This is the default example Google gives you on doing this. Only problem is all it does is just give the next 10 events on your calendar, not just for the day.
if anyone could help me figure out how to go about doing this it would be much apreciated.
function getEvents(auth) {
var calendar = google.calendar('v3');
calendar.events.list({
auth: auth,
calendarId: 'primary',
timeMin: (new Date()).toISOString(),
maxResults: 10,
singleEvents: true,
orderBy: 'startTime'
}, , function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
var events = response.items;
if (events.length == 0) {
console.log('No upcoming events found.');
} else {
console.log('Upcoming 10 events:');
for (var i = 0; i < events.length; i++) {
var event = events[i];
var start = event.start.dateTime || event.start.date;
console.log('%s - %s', start, event.summary);
}
}
});
}
Here is what I have to run it everyday:
var datetime = new Date();
datetime.getHours('newlistener', (event, addEventListener) => {
if (datetime.getHours == 24) {
getEventsForDay();
}
else {
return;
}
});
Updated code:
var datetime = new Date();
function getCurrentDayList() {
var year = ('0' + datetime.getUTCFullYear()).slice(-4);
var month = ('0' + (datetime.getUTCMonth() + 1)).slice(-2);
var day = ('0' + (datetime.getUTCDate())).slice(-2);
return (year + '-' + month + '-' + day + 'T00:00:00.000Z');
}
function getNextDayList() {
var year = ('0' + datetime.getUTCFullYear()).slice(-4);
var month = ('0' + (datetime.getUTCMonth() + 1)).slice(-2);
var day = ('0' + (datetime.getUTCDate())).slice(-2);
return (year + '-' + month + '-' + day + 'T23:59:59.999Z');
}
function listEvents(auth) {
var calendar = google.calendar('v3');
calendar.events.list({
auth: auth,
calendarId: 'primary',
timeMin: getCurrentDayList(),
timeMax: getNextDayList(),
maxResults: 10,
singleEvents: true,
orderBy: 'startTime'
}, function(err, response) {
if (err) {
console.log('The API returned an error: ' + err);
return;
}
var events = response.items;
if (events.length == 0) {
console.log('No upcoming events found.');
} else {
console.log('Upcoming 10 events:');
for (var i = 0; i < events.length; i++) {
var event = events[i];
var start = event.start.dateTime || event.start.date;
console.log('%s - %s', start, event.summary);
}
}
});
}
Try adding timeMax and timeMin.
timeMax
Upper bound (exclusive) for an event's start time to filter by. Optional. The default is not to filter by start time. Must be an RFC3339 timestamp with mandatory time zone offset, e.g., 2011-06-03T10:00:00-07:00, 2011-06-03T10:00:00Z. Milliseconds may be provided but will be ignored. If timeMin is set, timeMax must be greater than timeMin.
TimeMin
Lower bound (inclusive) for an event's end time to filter by. Optional. The default is not to filter by end time. Must be an RFC3339 timestamp with mandatory time zone offset, e.g., 2011-06-03T10:00:00-07:00, 2011-06-03T10:00:00Z. Milliseconds may be provided but will be ignored. If timeMax is set, timeMin must be smaller than timeMax.
timeMax 2018-01-06T00:00:00-08:00
timeMin 2018-01-05T00:00:00-08:00
Also there is a tutorial on "Retrieve events occuring between a date range."
Hope this helps.
My problem was that I couldn´t upload files bigger than 4MB so I used the createuploadsession according to createuploadsession
I successfully get the uploadUrl value from the createuploadsession response. Now I try to make a PUT request with this code
var file = 'C:\\files\\box.zip'
fs.readFile(file, function read(e, f) {
request.put({
url: 'https://api.onedrive.com/rup/545d583xxxxxxxxxxxxxxxxxxxxxxxxx',
headers: {
'Content-Type': mime.lookup(file),
'Content-Length': f.length,
'Content-Range': 'bytes ' + f.length
}
}, function(er, re, bo) {
console.log('#324324', bo);
});
});
But I will get as response "Invalid Content-Range header value" also if I would try
'Content-Range': 'bytes 0-' + f.length
//or
'Content-Range': 'bytes 0-' + f.length + '/' + f.length
I will get the same response.
Also I don´t want to chunk my file I just want to upload my file complete in 1run. Does anybody have sample code for upload a file to the uploadUrl from the createuploadsession response. Also do I really need to get first this uploadurl before i can upload files bigger than 4mb or is there an alternative way?
How about following sample script?
The flow of this script is as follows.
Retrieve access token from refresh token.
Create sesssion.
Upload file by every chunk. Current chunk size is max which is 60 * 1024 * 1024 bytes. You can change freely.
The detail information is https://dev.onedrive.com/items/upload_large_files.htm.
Sample script :
var fs = require('fs');
var request = require('request');
var async = require('async');
var client_id = "#####";
var redirect_uri = "#####";
var client_secret = "#####";
var refresh_token = "#####";
var file = "./sample.zip"; // Filename you want to upload.
var onedrive_folder = 'SampleFolder'; // Folder on OneDrive
var onedrive_filename = file; // If you want to change the filename on OneDrive, please set this.
function resUpload(){
request.post({
url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
form: {
client_id: client_id,
redirect_uri: redirect_uri,
client_secret: client_secret,
grant_type: "refresh_token",
refresh_token: refresh_token,
},
}, function(error, response, body) { // Here, it creates the session.
request.post({
url: 'https://graph.microsoft.com/v1.0/drive/root:/' + onedrive_folder + '/' + onedrive_filename + ':/createUploadSession',
headers: {
'Authorization': "Bearer " + JSON.parse(body).access_token,
'Content-Type': "application/json",
},
body: '{"item": {"#microsoft.graph.conflictBehavior": "rename", "name": "' + onedrive_filename + '"}}',
}, function(er, re, bo) {
uploadFile(JSON.parse(bo).uploadUrl);
});
});
}
function uploadFile(uploadUrl) { // Here, it uploads the file by every chunk.
async.eachSeries(getparams(), function(st, callback){
setTimeout(function() {
fs.readFile(file, function read(e, f) {
request.put({
url: uploadUrl,
headers: {
'Content-Length': st.clen,
'Content-Range': st.cr,
},
body: f.slice(st.bstart, st.bend + 1),
}, function(er, re, bo) {
console.log(bo);
});
});
callback();
}, st.stime);
});
}
function getparams(){
var allsize = fs.statSync(file).size;
var sep = allsize < (60 * 1024 * 1024) ? allsize : (60 * 1024 * 1024) - 1;
var ar = [];
for (var i = 0; i < allsize; i += sep) {
var bstart = i;
var bend = i + sep - 1 < allsize ? i + sep - 1 : allsize - 1;
var cr = 'bytes ' + bstart + '-' + bend + '/' + allsize;
var clen = bend != allsize - 1 ? sep : allsize - i;
var stime = allsize < (60 * 1024 * 1024) ? 5000 : 10000;
ar.push({
bstart : bstart,
bend : bend,
cr : cr,
clen : clen,
stime: stime,
});
}
return ar;
}
resUpload();
In my environment, this works fine. I could upload a 100 MB file to OneDrive using this script. If this doesn't work at your environment, feel free to tell me.
This is the ES6 version of Tanaike's solution.
const fs = require('fs')
const promisify = require('promisify')
const readFile = promisify(fs.readFile)
const uploader = async function(messageId) {
// const client = <setup your microsoft-client-here>
const address = '/path/to/file_name.jpg'
const name = 'file_name.jpg'
const stats = fs.statSync(address)
const size = stats['size']
const uploadSession = { AttachmentItem: { attachmentType: 'file', name, size } }
let location = ''
function getparams() {
const chSize = 10
const mega = 1024 * 1024
const sep = size < (chSize * mega) ? size : (chSize * mega) - 1
const arr = []
for (let i = 0; i < size; i += sep) {
const bstart = i
const bend = ((i + sep - 1) < size) ? (i + sep - 1) : (size - 1)
const cr = 'bytes ' + bstart + '-' + bend + '/' + size
const clen = (bend != (size - 1)) ? sep : (size - i)
const stime = size < (chSize * mega) ? 5000 : 10000
arr.push({ bstart, bend, cr, clen, stime })
}
return arr
}
async function uploadFile(url) {
const params = getparams()
for await (const record of params) {
const file = await readFile(address)
const result = await request({
url,
method: 'PUT',
headers: {
'Content-Length': record.clen,
'Content-Range': record.cr,
},
body: file.slice(record.bstart, record.bend + 1),
resolveWithFullResponse: true
})
location = (result.headers && result.headers.location) ? result.headers.location : null
// await new Promise(r => setTimeout(r, record.stime)) // If you need to add delay
}
}
const result = await client.api(`/me/messages/${messageId}/attachments/createUploadSession`).version('beta').post(uploadSession)
try {
await uploadFile(result.uploadUrl)
} catch (ex) {
console.log('ex.error:', ex.error)
console.log('ex.statusCode:', ex.statusCode)
await request.delete(result.uploadUrl)
}
return location
}
Please i need help on how to fetch data from twitter api for a week.
i'm using nodeJs to write the code and it doesn't seem to work well.
I'm using the twit module in nodeJs btw.
var today = new Date();
var day = today.getDate();
var month = today.getMonth() + 1; //January is 0!
var year = today.getFullYear();
let months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
for (let i = 0; i < 7; i++) {
if (day > 0) {
day--;
}
if (day == 0) {
month = month - 1;
day = months[month - 1];
}
console.log(day, month, year);
}
let params = {
q: `to:${firstBrand} since:${year}-${month}-${day-1} until:${year}-${month}-${currentDay}`,
count: 5000,
language: 'en',
entities: false
};
let param = {
q: `to:${secondBrand} since:${year}-${month}-${day-1} until:${year}-${month}-${currentDay}`,
count: 5000,
language: 'en',
entities: false
};
t.get('search/tweets', params, dataGotten);
Assuming all your setup is done correctly:
const Twit = require('twit')
const T = new Twit({
consumer_key: '...',
consumer_secret: '...',
access_token: '...',
access_token_secret: '...',
timeout_ms: 60*1000, // optional HTTP request timeout to apply to all requests.
});
I would try this:
t.get('search/tweets', params, function(err, data) {
console.log(data);
});
By the way, params is optional argument, so first of all try how it works without them:
t.get('search/tweets', function(err, data) {
console.log(data);
});
I have to send an SMS 15 minutes before the appointment is there. I have written the code, but it is called at the time of execution itself. Is there any other method or how do I solve this?
"RP.remindePatient" is the function that has to be called 15 minutes before the appointment time.
sendApptConf(s) {
var number = Phone;
var msg = urlencode("Hello " );
var smsData = 'username=' + username + '&hash=' + hash + '&sender=' + sender + '&numbers=' + number + '&message=' + msg;
var options = {
host: 'api.textlocal.in',
path: '/send?' + smsData
};
var callback;
console.log(options);
callback = function (response) {
var str = '';
// Another chunk of data has been recieved, so append it to `str`
response.on('data', function (chunk) {
console.log("new Data received")
str += chunk;
console.log(str);
});
// The whole response has been received, so we just print it out here.
response.on('end', function () {
console.log(str);
});
}
http.request(options, callback).end();
// Send SMS using Textlocal DONE
const convertTime = consultDate + ' ' + consultTime;
var d = new Date(convertTime);
var ms = d.getTime();
var milliLess15 = ms - (15 * 60 * 1000);
console.log(milliLess15);
setTimeout(function () {
console.log("I should be called after some delay")
RP.remindePatient(userPhone, patientName, drName, consultMode, consultDate, consultTime, transId, email, paymentDetails);
}, milliLess15);
I think there is a small issue in your logic. As you would already know, setTimeout(function () {}, milliseconds) will fork the function() after milliseconds you have specified.
Now let's focus on the below snippet of code:
const convertTime = consultDate + ' ' + consultTime;
var d = new Date(convertTime);
var ms = d.getTime();
var milliLess15 = ms - (15 * 60 * 1000);
Let's say your appointment is at 12:00 pm today (in millisec let's say 1492776423) and current execution time is 10:00 am (in millisec 1485576423). By your logic, you are calling the function() after: var milliLess15 = ms - (15 * 60 * 1000) which is 1492776423 - (15 * 60 * 1000) = 1491876423. Note here that, you don't want to call function() after 1491876423 millisec. Rather you want to call it after millisec equivalent of 12:00 - 10:00 - 00:15. So your logic should look something like:
const convertTime = consultDate + ' ' + consultTime;
var d = new Date(convertTime);
var ms = d.getTime();
var currentTime = new Date();
var currentTimeMilli = currentTime.getTime();
var milliLess15 = ms - (15 * 60 * 1000) - currentTimeMilli;
Rest of the code will remain the same. Hope this answer helps you!
Don't call the variable after timeout. Just put in:
setTimeout(function () {
console.log("I should be called after some delay")
RP.remindePatient(userPhone, patientName, drName, consultMode, consultDate, consultTime, transId, email, paymentDetails);
}, 900000);
There is a scenario where I need to send event meeting invites to end users. I am able to generate the ICS file and send it as attachment. But the ICS files are not readable or added in User Calander.
Code to generate and send email is as below:
var transport = require('nodemailer-smtp-transport'),
transporter = nodemailer.createTransport(transport(config.mailer)),
sendMail = function(mailOptions) {
transporter.sendMail(mailOptions, function(err, response) {
if (err) return err;
return response;
});
},
eventEmailToUser = function(user, events, createdBy, mailOptions) {
var ical = require('ical-generator');
var cal = ical();
var username = user.username ? user.username : ' ';
var eventName = events.title ? events.title : ' ';
var eventDate = moment.tz(events.date, 'Asia/Kolkata');
eventDate = eventDate.format('YYYY-MM-DD h:mm a');
cal.addEvent({
start: new Date(),
end: new Date(new Date().getTime() + 3600000),
summary: events.title,
uid: events._id, // Some unique identifier
sequence: 0,
description: events.description,
location: events.location,
organizer: {
name: createdBy.username,
email: createdBy.email
},
method: 'request'
});
var path = '/files/' + events._id + '.ics';
cal.save(path, function(err, file) {
if (err) return err;
});
mailOptions.alternatives = [{
contentType: "text/calendar",
contents: new Buffer(cal).toString()
}];
mailOptions.attachments = [{
filename: events.title + '.ics',
filePath: path
}];
mailOptions.html = [
'<div>',
'<div>Hi <b>' + username + '</b><br/<br/>',
' You have just confirmed to attend <b>' + eventName + '</b> on <b>' + eventDate + '</b>',
' <br/><br/>',
'Thanks',
' <br/>',
'</div>',
'<br/>',
'</div>'
].join('\n\n');
mailOptions.subject = 'Invitation for' + eventName;
return mailOptions;
};
exports.sendInvite = function(req, res) {
var userMailOptions = {
to: 'abc#gmail.com',
from: 'xyz#gmail.com',
};
userMailOptions = eventEmailToUser(user, events, eventCreator, userMailOptions);
var userEmailresult = sendMail(userMailOptions);
};
The first issue that strikes me is that you are missing an ATTENDEE property which is required in any iMIP REQUEST.
There might be other issues but we would need to see your full MIME message instead of your code to really spot those. As a starter, you might want to doublecheck Multipart email with text and calendar: Outlook doesn't recognize ics