123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- //edit webdav config
- let config = {
- davUrl: 'https://example.com/dav.php',
- davUsername: 'username',
- davPassword: 'password',
- davAddressBook: ''
- }
- //and delete this line:
- config = require('./secrets')
- //or create secrets.js:
- /*
- module.exports = {
- davUrl: 'https://example.com/dav.php',
- davUsername: 'username',
- davPassword: 'password',
- davAddressBook: ''
- }
- */
- const WebSocket = require('ws');
- var dav = require('dav');
- var VCard = require('vcard');
- var VCF = require('vcf');
-
- const wss = new WebSocket.Server({
- port: 23845,
- perMessageDeflate: false
- });
- var xhr = new dav.transport.Basic(
- new dav.Credentials({
- username: config.davUsername,
- password: config.davPassword
- })
- );
- let davClient = new dav.Client(xhr);
- let usedAddressBook = null;
- davClient.createAccount({
- server: config.davUrl,
- accountType: 'carddav'
- }).then(function(account) {
- let addressBook = null;
- account.addressBooks.forEach(function(ab) {
- console.log('Found address book name ' + ab.displayName);
- addressBook = ab;
- if(ab.displayName === config.davAddressBook) return;
- });
- console.log('Using ' + addressBook.displayName);
- usedAddressBook = addressBook;
- });
- wss.on('connection', function connection(ws) {
- console.log('new ws connection');
- ws.on('message', function incoming(message) {
- const bDays = JSON.parse(message);
- console.log('received: ', bDays);
- syncDavAddressBook(ws, bDays);
- });
-
- });
- var oldRemoteBDays = {};
- function syncDavAddressBook(ws, bDays) {
- if(!usedAddressBook)
- return;
-
- davClient.syncAddressBook(usedAddressBook).then(function(x) {
- let remoteBDays = {};
- let hasUpdates = false;
- for(const vcard of x.objects) {
- VCF.parse(vcard.addressData, function(card) {
- if(!isNaN(card.bday) && card.note && card.note.length > 0) {
- const uid = card.note[0]
- remoteBDays[uid] = [card.fn, card.bday, card.rev];
- if(!bDays[uid] && !oldRemoteBDays[uid]) {
- //create local
- console.log('new birthday from dav')
- bDays[uid] = remoteBDays[uid];
- hasUpdates = true;
- } else if(bDays[uid].count < 3 || new Date(bDays[uid][2]) < card.rev) {
- //pull from dav
- console.log('updated birthday from dav')
- bDays[uid] = remoteBDays[uid];
- hasUpdates = true;
- } else if(new Date(bDays[uid][2]) > card.rev && !isNaN(card.rev)) {
- //push to dav
- console.log('synced birthday to dav')
- card.fn = bDays[uid][0];
- card.bday = new Date(bDays[uid][1]);
- card.rev = new Date(bDays[uid][2]);
- card.validate();
- vcard.addressData = vCardToString(card);
- davClient.updateCard(vcard);
- }
- }
- })
- }
- for(const uid in bDays) {
- if(!oldRemoteBDays[uid] && !remoteBDays[uid] && bDays[uid][1]) {
- //create in dav
- console.log('created birthday in dav')
- const card = new VCard({
- fn: bDays[uid][0],
- bday: new Date(bDays[uid][1]),
- rev: bDays[uid].length > 2 ? new Date(bDays[uid][2]) : new Date(),
- note: uid});
- card.validate();
- davClient.createCard(usedAddressBook, {
- data: vCardToString(card),
- filename: `${card.uid}.vcf`,
- xhr: xhr
- });
- remoteBDays[uid] = bDays[uid];
- } else if(oldRemoteBDays[uid] && !remoteBDays[uid] && bDays[uid][1]) {
- // delete local
- delete bDays[uid];
- hasUpdates = true;
- }
- }
- oldRemoteBDays = remoteBDays;
- //send ws
- if(hasUpdates) {
- console.log('send: ', bDays);
- ws.send(JSON.stringify(bDays))
- }
- })
- }
- function vCardToString(vCard) {
- return `BEGIN:VCARD
- VERSION:3.0
- UID:${vCard.uid}
- N:;${vCard.fn};;;
- FN:${vCard.fn}
- NOTE:${vCard.note && vCard.note[0] ? vCard.note[0] : ""}
- REV:${(vCard.rev instanceof Date ? vCard.rev.toISOString().replace(/[-:]|\.000/g, '') : vCard.rev)}
- BDAY;VALUE=date:${vCard.bday.toISOString().substring(0, 10).replace(/-/g, '')}
- PRODID:-//birthday-script//EN
- END:VCARD
- `;
- }
|