Files
Facilitor/UTILS/Exchange/exchange_graph.js
Jos Groot Lipman 1295a57761 KFSG#72139 Exchange webhook beter @removed gedrag
svn path=/Website/branches/v2022.1/; revision=55593
2022-04-14 12:08:45 +00:00

337 lines
13 KiB
JavaScript

/*
$Revision$
$Id$
File: Exchange_Graph.js
Description: Exchange MS Graph koppeling
Dit bestand maakt voor een ruimte-mailbox Arguments(0) de csv
met calenderitems aan sinds de laatste sync-actie, Arguments(1)
Result: Errorlevel 10 betekent alles goed
Errorlevel 1 betekent dat we een foutsituatie hebben ontdekt
Errorlevel 0 betekent dat er iets is fout gegaan wat we niet hebben onderkend
Parameters (0) e-mail adres van de zaal
(1) "EXCHFULL" calendarview-import (in de toekomst tot config.fullfuture)
alle andere waarden: synchronisatie-import (voorheen werd hier de syncstate in meegegeven)
*/
// polyfills
// End polyfills
var fso = new ActiveXObject("Scripting.FileSystemObject");
/// FROM HERE THE ADDED CODE STARTS
// get user calendar items based on token and userid
function getGraphUserCalendarItems(user_id, skiptoken, deltatoken) {
var response = null;
var parms;
// set parameters to read the next batch of events
if (skiptoken) {
parms = "$skiptoken=" + skiptoken;
// set parameters to read first batch of changed events
} else if (deltatoken) {
parms = "$deltatoken=" + deltatoken;
// set parameters to read the first batch of all events for the next 90 days
} else {
var dateFrom = new Date();
dateFrom.setHours(0, 0, 0, 0);
dateFrom.setDate(dateFrom.getDate() - config.fullpast);
var dateTo = new Date(dateFrom);
dateTo.setDate(dateTo.getDate() + config.fullfuture);
__Log("Full syncing from " + dateFrom.toISOString() + " to " + dateTo.toISOString() + " (" + (config.fullfuture + config.fullpast) + " days)");
parms = 'startDateTime=' + dateFrom.toISOString() + '&endDateTime=' + dateTo.toISOString();
}
var xhr = doHTTP("GET", 'https://graph.microsoft.com/v1.0/users/' + user_id + '/calendarView/delta?' + parms, null, { "Accept": "application/json", "Authorization": "Bearer " + token });
if (xhr != null) {
var response = JSON.parse(xhr.responseText, internal_parsedate);
if (response["@odata.deltaLink"] && response["@odata.deltaLink"].indexOf("$deltatoken=") != -1) {
response.deltatoken = response["@odata.deltaLink"].split("$deltatoken=")[1];
} else if (response["@odata.nextLink"] && response["@odata.nextLink"].indexOf("$skiptoken=") != -1) {
response.skiptoken = response["@odata.nextLink"].split("$skiptoken=")[1];
}
}
return response;
}
///
function csv_for_room(zaalemail, import_app_code, as_stream)
{
__Log("Connecting to Graph API")
// ---
// kunnen we niets mee doExchange(config.endpointurl, "<m:GetRoomLists />", "roomlist.xml");
var room_id = safefilename(zaalemail);
var sync_key;
var res_ruimte_key;
var deltatoken;
var oRs;
// determine files wild card
var import_app_files = "sync_*.csv";
var import_app_files_pre = "sync_";
var sql = "SELECT i.fac_import_app_files "
+ " FROM fac_import_app i"
+ " WHERE i.fac_import_app_code = " + safe.quoted_sql(import_app_code);
var oRs = Oracle.Execute(sql);
if (!oRs.EOF)
{
import_app_files = oRs("fac_import_app_files").Value;
import_app_files_pre = import_app_files.split("*")[0].split(".")[0];
}
oRs.Close();
// vanaf hier alleen wijzigingen ophalen
var sql = "SELECT s.res_ruimte_key sync_key, r.res_ruimte_key, s.res_ruimte_syncstate" // syncstate is deltatoken
+ " FROM res_ruimte r"
+ " , res_ruimte_sync s"
+ " WHERE r.res_ruimte_key = s.res_ruimte_key(+)"
+ " AND r.res_ruimte_verwijder IS NULL"
+ " AND res_ruimte_extern_id = '" + zaalemail + "'";
oRs = Oracle.Execute(sql);
sync_key = oRs("sync_key").Value; // value null means not there
res_ruimte_key = oRs("sync_key").Value || oRs("res_ruimte_key").Value || "";
__Log("\n\n==== Room: " + zaalemail);
if (import_app_code != "EXCHFULL") {
deltatoken = oRs("res_ruimte_syncstate").Value || "";
}
else {
// no skiptoken and no deltatoken means retrieve all events
}
oRs.Close();
var csvname = config.xmlfolder + import_app_files_pre + room_id + ".csv";
// Verwijderen : het verwijderen van onze oude sync_*.csv
try
{
fso.DeleteFile(csvname);
// Als hierboven geen files gevonden zijn komen we in de exception
// en niet in onderstaande echo.
__Log("Oude syncfile is verwijderd.");
}
catch(e)
{
// Neem aan dat gelukkig geen files zijn gevonden
}
var response = getGraphOtherCalendarItems(zaalemail, "", deltatoken);
if (response)
{
var results = response.value;
var index;
while (response.skiptoken) {
response = (response.other ? getGraphOtherCalendarItems(zaalemail, response.skiptoken, null) : getMeGraphSharedCalendarItems(response.calendar_id, response.skiptoken, null));
for (index = 0; index < response.value.length; index++) {
results.push(response.value[index]);
}
}
deltatoken = response.deltatoken;
var csvFileText = makeCSV(results, zaalemail);
// save the CSV file to disc here
fileStream = new ActiveXObject("ADODB.Stream");
fileStream.Type = 2; // adTypeBinary eerst nog
fileStream.Open();
fileStream.CharSet = "utf-8";
// save only if records are found
if (!!csvFileText)
{
fileStream.WriteText(csvFileText);
if (as_stream)
{
// Leveren we die zo op en gaat die rechtstreeks impReadStream in
}
else
{
fileStream.SaveToFile(csvname, 2); // overwrite
}
}
// deltatoken needs to be saved to retrieve changes during a future run
if (sync_key)
{
var sql = "UPDATE res_ruimte_sync s"
+ " SET s.res_ruimte_syncstate = " + safe.quoted_sql(deltatoken)
+ " , s.res_ruimte_syncdate = SYSDATE"
+ " WHERE s.res_ruimte_key = " + sync_key;
}
else
{
var sql = "INSERT INTO res_ruimte_sync"
+ " (res_ruimte_key, res_ruimte_syncstate, res_ruimte_syncdate)"
+ " VALUES"
+ "(" + res_ruimte_key
+ "," + safe.quoted_sql(deltatoken)
+ ", SYSDATE"
+ ")";
}
__Log(sql);
oRs = Oracle.Execute(sql);
// Als we hier komen is alles goed
return fileStream;
}
else
{
__Log("User for email address " + zaalemail + " not found");
return false;
}
}
function getMasterEvent(data, id) {
var index;
var result = null;
for (index = 0; index < data.length; index++) {
if (data[index].id == id) {
result = data[index];
break;
}
}
__Log(JSON.stringify(result));
return result;
}
function eventFound(_id, _occurrence, _email)
{
var eventSql = "SELECT 1"
+ " FROM res_rsv_ruimte rr,"
+ " res_ruimte_opstelling ro,"
+ " res_ruimte r"
+ " WHERE rr.res_rsv_ruimte_externnr IS NOT NULL"
+ " AND rr.res_rsv_ruimte_externnr LIKE " + safe.quoted_sql(_id) + "||'|'||" + safe.quoted_sql(_occurrence) + "||'|%'"
+ " AND rr.res_rsv_ruimte_verwijder IS NULL"
+ " AND ro.res_ruimte_opstel_key = rr.res_ruimte_opstel_key"
+ " AND r.res_ruimte_key = ro.res_ruimte_key"
+ " AND r.res_ruimte_verwijder IS NULL"
+ " AND r.res_ruimte_extern_id = " + safe.quoted_sql(_email);
var eventoRs = Oracle.Execute(eventSql);
var _returnValue = !eventoRs.eof;
eventoRs.Close();
return _returnValue;
}
function makeCSV(data, zaalemail)
{
var trs = [];
var tds = [];
var index;
var masterEvent;
var curDate = new Date();
var seqNbr = curDate.getTime();
// Header
tds = [
"Subject",
"StartTime",
"EndTime",
"Organizer",
"Email",
"Name",
"Modifier",
"ApptId",
"RecurId",
"SeqNr"
];
// rows in data
/* types description
=============== ===============================
singleInstance: stand alone event
seriesMaster: definition of a repeating event
occurence: repeating event occurrence
exception: changed repeating event
*/
for (index = 0; index < data.length; index++)
{
__Log(JSON.stringify(data[index]));
if (index == 0)
{
trs.push(tds.join(";")); // header row first
}
// deleted event
if (data[index]["@removed"] || data[index].isCancelled)
{ // {"@odata.type":"#microsoft.graph.event","id":"AAMkAGQ1Yz.......","@removed":{"reason":"deleted"}}
tds = [
"",
"",
"",
"",
"",
"",
"D", // cancelled or deleted
data[index].id,
"",
++seqNbr
];
trs.push(tds.join(";"));
}
else
{
var _startDate = internal_parsedate(null, data[index].start.dateTime);
var _endDate = internal_parsedate(null, data[index].end.dateTime);
if (_startDate.getTime() >= curDate.getTime())
{
{
// repeating event
if (data[index].type == "occurrence")
{
masterEvent = getMasterEvent(data, data[index].seriesMasterId) || {};
tds = [
masterEvent.subject,
_startDate.toISOString(),
_endDate.toISOString(),
masterEvent.organizer.emailAddress.address,
masterEvent.organizer.emailAddress.address,
masterEvent.organizer.emailAddress.name,
eventFound(data[index].id, data[index].OccurrenceId, zaalemail) ? "U" : "C", // C or U here
data[index].id,
data[index].OccurrenceId,
++seqNbr
];
}
// singleInstance / seriesMaster / exception
else if (inArray(data[index].type, ["singleInstance","seriesMaster","exception"]))
{
tds = [
data[index].subject,
_startDate.toISOString(),
_endDate.toISOString(),
data[index].organizer.emailAddress.address,
data[index].organizer.emailAddress.address,
data[index].organizer.emailAddress.name,
eventFound(data[index].id, data[index].OccurrenceId, zaalemail) ? "U" : "C", // C or U here
data[index].id,
inArray(data[index].type, ["seriesMaster","exception"]) ? data[index].OccurrenceId : "",
++seqNbr
];
}
trs.push(tds.join(";"));
// attendees
if ("attendees" in data[index])
{
var attendee;
for (attendee in data[index].attendees)
{
tds = [
data[index].subject,
_startDate.toISOString(),
_endDate.toISOString(),
data[index].organizer.emailAddress.address,
data[index].attendees[attendee].emailAddress.address,
data[index].attendees[attendee].emailAddress.name,
eventFound(data[index].id, data[index].OccurrenceId, zaalemail) ? "U" : "C", // C or U here
data[index].id,
inArray(data[index].type, ["seriesMaster","exception"]) ? data[index].OccurrenceId : "",
seqNbr
];
trs.push(tds.join(";"));
}
}
}
}
}
}
return trs.join("\r\n");
}