1
+ const appwrite = require ( 'node-appwrite' ) ;
2
+ const admin = require ( 'firebase-admin' ) ;
3
+ const axios = require ( 'axios' ) ;
4
+
5
+ // Firebase service account
6
+ const serviceAccount = require ( "../service-account.json" ) ;
7
+
8
+ // Initialize firebase
9
+ admin . initializeApp ( {
10
+ credential : admin . credential . cert ( serviceAccount )
11
+ } ) ;
12
+
13
+ // Function to split array into chunks
14
+ function chunk ( array , chunkSize ) {
15
+ var arr = [ ] ;
16
+ for ( let i = 0 ; i < array . length ; i += chunkSize ) {
17
+ const chunk = array . slice ( i , i + chunkSize ) ;
18
+ arr . push ( chunk ) ;
19
+ }
20
+ return arr ;
21
+ }
22
+
23
+ module . exports = async ( req , res ) => {
24
+ // Set appwrite endpoint
25
+ const client = new appwrite . Client ( )
26
+ . setEndpoint ( 'https://api.app.asta-bochum.de/v1' )
27
+ . setProject ( 'campus_app' )
28
+ . setKey ( req . variables . API_KEY ) ;
29
+
30
+ const db = new appwrite . Databases ( client ) ;
31
+
32
+ // Get all events from the asta calendar
33
+ let astaEvents ;
34
+ try {
35
+ astaEvents = ( await axios ( 'https://asta-bochum.de/wp-json/tribe/events/v1/events/' ) ) . data . events ;
36
+
37
+ } catch ( e ) {
38
+ console . log ( '[ERROR] Could not fetch AStA Events.' ) ;
39
+ return res . json ( "Error" ) ;
40
+ }
41
+
42
+ // Get all events without duplicates
43
+ const events = ( await db . listDocuments ( 'push_notifications' , 'saved_events' ) ) . documents ;
44
+ const uniqueEvents = [ ...new Map ( events . map ( item => [ item [ 'eventId' ] , item ] ) ) . values ( ) ] ;
45
+
46
+ const today = new Date ( Date . now ( ) ) ;
47
+
48
+ // Get all events that happen today
49
+ const eventsToday = uniqueEvents . filter ( ( item ) => {
50
+ const date = new Date ( Date . parse ( item . startDate ) ) ;
51
+
52
+ return date . getFullYear ( ) == today . getFullYear ( ) && date . getMonth ( ) == today . getMonth ( ) && date . getDate ( ) == today . getDate ( ) ;
53
+ } ) ;
54
+
55
+ // Go through all events
56
+ for ( const eventToday of eventsToday ) {
57
+ // Find the corresponding event of the AStA calendar
58
+ const astaEvent = astaEvents . find ( event => event . id == eventToday . eventId ) ;
59
+ if ( astaEvent == undefined ) continue ;
60
+
61
+ // Adjust the notification body based on the existence of an end date
62
+ const time = ( astaEvent . start_date_details . hour == astaEvent . end_date_details . hour &&
63
+ astaEvent . start_date_details . minutes == astaEvent . end_date_details . minutes ) ?
64
+ `Heute ${ astaEvent . start_date_details . hour } :${ astaEvent . start_date_details . minutes } Uhr`
65
+ : `Heute ${ astaEvent . start_date_details . hour } :${ astaEvent . start_date_details . minutes } bis ${ astaEvent . end_date_details . hour } :${ astaEvent . end_date_details . minutes } Uhr`
66
+ ;
67
+
68
+ // Send the message
69
+ await admin . messaging ( ) . send (
70
+ {
71
+ notification : {
72
+ title : `Erinnerung ${ astaEvent . title } !` ,
73
+ body : `${ time } ${ astaEvent . venue . venue != undefined ? `
74
+ Ort: ${ astaEvent . venue . venue } ` : '' } `,
75
+ } ,
76
+ data : {
77
+ "interaction" : String ( JSON . stringify ( {
78
+ "destination" : 'calendar' ,
79
+ "data" : [
80
+ {
81
+ "event" : {
82
+ "id" : eventToday . eventId
83
+ }
84
+ }
85
+ ]
86
+ } ) )
87
+ } ,
88
+ topic : eventToday . eventId . toString ( )
89
+ }
90
+ ) ;
91
+
92
+ console . log ( '[INFO] Notifications sent.' ) ;
93
+
94
+ // Remove all documents with the corresponding event id
95
+ const eventDocuments = events . filter ( item => item . eventId == eventToday . eventId ) ;
96
+ for ( const eventDocument of eventDocuments ) {
97
+ try {
98
+ await db . deleteDocument ( 'push_notifications' , 'saved_events' , eventDocument . $id ) ;
99
+ } catch ( e ) {
100
+ console . log ( '[ERROR] Error while deleting saved events:' + e ) ;
101
+ continue ;
102
+ }
103
+ }
104
+
105
+ console . log ( '[INFO] Documents deleted.' ) ;
106
+
107
+ // Get all fcm tokens of the documents with the corresponding event id
108
+ const fcmTokens = eventDocuments . map ( item => item . fcmToken ) ;
109
+ const tokenChunks = chunk ( fcmTokens , 1000 ) ;
110
+
111
+ // Unsubscribe all devices from the topic to delete it
112
+ for ( const chunk of tokenChunks ) {
113
+ try {
114
+ await admin . messaging ( ) . unsubscribeFromTopic ( chunk , eventToday . eventId . toString ( ) ) ;
115
+ } catch ( e ) {
116
+ console . log ( '[ERROR] Error while unsubscribing tokens: ' + e ) ;
117
+ }
118
+ }
119
+
120
+ console . log ( '[INFO] Topic deleted.' ) ;
121
+ }
122
+ console . log ( '[INFO] All operations concluded. Closing...' )
123
+ return res . json ( "Function executed!" ) ;
124
+ } ;
0 commit comments