diff --git a/package.json b/package.json index 192337c..56fce7b 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "googleapis": "^113.0.0" }, "scripts": { - "dev": "nodemon public/index.js" + "dev": "nodemon --watch insted --ignore tmp/ public/index.js" }, "devDependencies": { "@types/node": "^18.15.5" diff --git a/src/GameSource.ts b/src/GameSource.ts index 8387a6e..ee7be65 100644 --- a/src/GameSource.ts +++ b/src/GameSource.ts @@ -4,14 +4,11 @@ import axios from "axios"; // search for upcomming games export default class GameSource { + constructor() {} - constructor() { - - } - async getGames() { const sourceUrl = `https://serpapi.com/search.json?q=maccabi+haifa+next+games&api_key=${process.env.SERPAPI_KEY}&location=austin,+texas,+united+states`; const result = await axios.get(sourceUrl) - return result.data; + return result; } } \ No newline at end of file diff --git a/src/GoogleCalendar.ts b/src/GoogleCalendar.ts index 0ea8502..7496c78 100644 --- a/src/GoogleCalendar.ts +++ b/src/GoogleCalendar.ts @@ -1,52 +1,59 @@ +import { JWT } from 'google-auth-library'; +import { google } from 'googleapis'; +import { GoogleCalendarEvent } from './types/index'; + require('dotenv').config(); const env = process.env; -import { google } from 'googleapis'; + export default class GoogleCalendar { - connected: boolean; + client_secret: string; + client_id: string; + calender_id: string; calendar: any; - googlePrivateKey = env.GOOGLE_PRIVATE_KEY - googleClientEmail = env.GOOGLE_CLIENT_EMAIL - googleProjectNumber = env.GOOGLE_PROJECT_NUMBER - googleCalendarId = env.GOOGLE_CALENDAR_ID - projectScope = 'https://www.googleapis.com/auth/calendar.readonly' - connection: any; - - - + clientEmail: string; + googlePrivateKey: string; + token: any; constructor() { - const SCOPES = this.projectScope; - const jwtClient = new google.auth.JWT( - this.googleClientEmail, - null, - this.googlePrivateKey, - SCOPES - ); - this.connection = jwtClient; - if(this.connection) { - this.connected = true; - } else { - this.connected = false; - } + this.client_secret = env.GOOGLE_CLIENT_SECRET; + this.client_id = env.GOOGLE_CLIENT_ID; + this.calender_id = env.GOOGLE_CALENDAR_ID; + this.clientEmail = env.GOOGLE_CLIENT_EMAIL + this.googlePrivateKey = env.GOOGLE_PRIVATE_KEY.replace(/\\n/g, '\n'); + // this.redirect_uris = env.GOOGLE_REDIRECT_URIS; } - insert_new_event_in_calender(event: any) { - const calendar = google.calendar({ version: 'v3', auth: this.connection }); - const options = { - auth: this.connection, - calendarId: this.googleCalendarId, - date: event.date, - // resource: event, - }; + async init() { + const jwtClient = await this.authorize(); + this.calendar = google.calendar({ version: 'v3', auth: jwtClient }); + } - const callback = (err: any, res: any) => { + async authorize() { + const client = new JWT({ + email: this.clientEmail, + key: this.googlePrivateKey, + scopes: 'https://www.googleapis.com/auth/calendar.events' + }); + const { access_token } = await client.authorize(); + this.token = access_token; + if(!this.token) { + throw new Error('Failed to connect to google calendar'); + } + return client; + } + + updateNewEvent(upcomingEvents: GoogleCalendarEvent[]) { + this.calendar.event.insert({ + auth: this.token, + calendarId: this.calender_id, + resource: upcomingEvents[0], + }, function (err: any, event: any) { if (err) { - console.log(err); + console.log('There was an error contacting the Calendar service: ' + err); + return; } - console.log(res); - } - calendar.events.insert(options, callback); - console.log("Successfully Inserted Event To Google Calendar") + console.log('Event created: %s', event.htmlLink); + }); } -} \ No newline at end of file +} diff --git a/src/index.ts b/src/index.ts index 0bd21c3..9e0979d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,35 +1,63 @@ -import GameSource from "./GameSource"; -import GoogleCalendar from './GoogleCalendar' +import GoogleCalendar from './GoogleCalendar'; +import GameSource from './GameSource'; +import { GoogleCalendarEvent } from './types/index'; -const gameSource = new GameSource(); -const googleCalendar = new GoogleCalendar(); -if(googleCalendar.connected) { - console.log("Successfully Connected To Google API"); -} else { - console.log("Failed To Connect To Google API"); -} +// crete App class +// app class will be the main class of our application +// it will be collecting macabi haifa events from GameSource class +// it will be responsible for update GameSource events in google calendar +// it will be responsible for update GameSource events in local file + + + +class App { + googleCalendar: GoogleCalendar; + gameSource: any; + googleToken: any; -// create an app that scan the output gameSource and add events to google calendar -export default class App { constructor() { - this.run(); + this.googleCalendar = new GoogleCalendar(); + this.gameSource = new GameSource(); } - async run() { - const games = await gameSource.getGames(); - this.dropOutputToTmpFIle(games); + async init() { + this.googleToken = this.googleCalendar.init(); } - dropOutputToTmpFIle(games: any) { - const fs = require('fs'); - fs.writeFile("tmp/output.json", JSON.stringify(games), function(err: any) { - if(err) { - return console.log(err); - } - console.log("The file was saved!"); + getNewGamesAndUpdateCalendar() { + const upcomingEvents: GoogleCalendarEvent[] = []; + this.gameSource.getGames().then((games: any) => { + const rootGames = games.data.sports_results; + upcomingEvents.push({ + summary: rootGames.title, + location: rootGames.game_spotlight.stadium, + description: "Haifa vs. " + rootGames.game_spotlight.teams[this.getHaifaIndex(rootGames.game_spotlight.teams)].name, + start: { + dateTime: '2023-03-22T09:00:00-07:00', + timeZone: 'Israel' + }, + end: { + dateTime: '2023-03-22T09:00:00-07:00', + timeZone: 'Israel' + }, + recurrence: [] + }); + console.log("Updaing new event: " + upcomingEvents[0].summary) + console.log(upcomingEvents[0]) + this.googleCalendar.updateNewEvent(upcomingEvents); }); } + + getHaifaIndex(teams: any) { + for (let i = 0; i < teams.length; i++) { + if (teams[i].name === "Maccabi Haifa") { + return i; + } + } + } } const app = new App(); +app.init(); +app.getNewGamesAndUpdateCalendar(); diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..51b1b78 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,14 @@ +export interface GoogleCalendarEvent { + summary: string; + location: string; + description: string; + start: { + dateTime: string; + timeZone: string; + }; + end: { + dateTime: string; + timeZone: string; + }; + recurrence: string[]; +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 3b44a81..0c778a3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,9 +3,8 @@ "module": "CommonJS", "allowSyntheticDefaultImports": true, "esModuleInterop": true, - "target": "ES6", + "target": "ES2019", "moduleResolution": "node", - "sourceMap": true, "outDir": "./public", "rootDir": "./src" }