Skip to content

An appointment system based on Google Calendars, full Kotlin

Notifications You must be signed in to change notification settings

gmazzo/gs.calendar.appointments

Repository files navigation

gs.calendar.appointments

An appointment system based on Google Calendars

Build Status codecov

Overview

This a sample project for demostrate the power of Kotlin language with a simple goal:

Appointments scheduling on pre-given (event based) availaibility

Fullstack Kotlin project demo:

  • KTS for Gradle's scripts (bye bye Groovy)
  • Kotlin's multuplatform for sharing DTO models between Java and JavaScript.
  • KotlinX's Serialization for cross-platform JSON support
  • Dagger for tide everying up
  • RestEasy for API binding (JAX-RS spec)
  • React, Redux and Material-UI in full Kotlin/JS

What to Expect?

See a running example at https://gs-calendar-appointments.herokuapp.com/

screenshot

Modules

  • model: platform agnostic model classes (for JVM and JS)
  • core: main module to interact with Google Calendar API that provides an abstraction with business logic
  • backend: a JAX-RS server which exposes the API
  • frontend: a React application written in pure Kotlin! It relies on well known frameworks like Redux and Material-UI.
  • webapp-bundle: the backend module, bundled with the frontend module as Java resources. This should be your entry point if you want to run the app as a standalone whole

Starting tips

Setup the Google Cloud Project

  1. Go to Google Cloud Platform Console
  2. Sign in and create an API Project
  3. Enable the Google Calendar API
  4. Create a Service Account (for the backend)
    1. Go to Service Accounts
    2. Choose Create Service Account
    3. Enter an ID and confirm
    4. Take note of your Service Account's email address
    5. Create a key-pair credentials for your new service account, in JSON format
    6. Download the credentials and store the Credentials (one of):
      • Encode it as Base64 and set an Environment Variable called GOOGLE_CREDENTIALS with the value
      • Or save it on backend module's resources under src/main/resources with name google_client_secrets.json.
  5. Create an OAuth Client ID
    1. Go to Credentials
    2. Choose Create Credentials and pick OAuth Client ID
    3. Pick Web Application
    4. In allowed origins section add this for dev localhost server:
      • http://localhost:8081 for backend dev server
      • http://localhost:8088 for frontend dev server (optional)
      • (your production servers here)
    5. Confirm it. You can let allowed redirect URIs empty. We will be using Google's own sign in.
    6. Take note of your OAuth Client ID
    7. Store the Client Id (one of):
      • Set an Environment Variable called GOOGLE_CLIENT_ID with the value
      • Save it on model module's root under with name google_client_id.txt.
      • Or replace the buildConfigField:API_CLIENT_ID value on model module's build.gradle.kts file.
  6. Create a new (Google Calendar)[https://calendar.google.com/calendar/r/settings/createcalendar]
    1. Share it with the Service Account's email address you just created. This will make it available at the app
    2. Make sure it has write access to the Calendar's events when you share it
  7. Run the backend or the webapp-bundle module to check if everything is working as expected.

If succeed, you should see something like this at http://localhost:8081/api/agendas:

[
  {
    "id": "fsltp4vi7lcgugho31rdlc56no@group.calendar.google.com",
    "name": "Beneficios (prueba)",
    "description": "Calendario de prueba para la app de citas",
    "foregroundColor": "#000000",
    "backgroundColor": "#a47ae2",
    "available": true
  },
  {
    "id": "fpjlv6afhup6s03v5gt3ljgd74@group.calendar.google.com",
    "name": "Masajes (prueba)",
    "description": "Beneficio de masajes",
    "foregroundColor": "#000000",
    "backgroundColor": "#a47ae2",
    "available": true
  }
]

I encourge you to create new calendars from https://calendar.google.com and add some test events on it!

Running the backend

./gradlew backend:run

Once running:

Running the frontend (as standalone, for dev purposes)

./gradlew frontend:run -t -PapiEndpoint=http://localhost:8081/api

Once running, visit http://localhost:8088/ to open the app

Running the whole webapp (frontend and backend)

./gradlew webapp-bundle:run

Once running:

Note: it may take a while to build, basically because it need to build and bundle the frontend module as well.