Skip to content

Commit

Permalink
Merge pull request #171 from GTBitsOfGood/pennon/hours-reminder-cron
Browse files Browse the repository at this point in the history
Pennon/hours reminder cron
  • Loading branch information
SamratSahoo authored Nov 15, 2024
2 parents e2d7128 + 177aa72 commit 7295f7f
Show file tree
Hide file tree
Showing 12 changed files with 1,769 additions and 0 deletions.
36 changes: 36 additions & 0 deletions .github/workflows/hours-email-reminder.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Run Email Reminder on a CRON Schedule

on:
schedule:
- cron: "0 0 1 1 *" # Jan 1st
- cron: "0 0 1 6 *" # Jun 1st
workflow_dispatch:

jobs:
send-hours-email:
runs-on: ubuntu-latest
name: A job to run the email reminder cron twice a year

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Run Email Reminder Action Step
uses: ./hours-email-reminder
id: hours-email
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
DATABASE_NAME: ${{ secrets.DATABASE_NAME }}
JUNO_API_KEY: ${{ secrets.JUNO_API_KEY }}
JUNO_BASE_URL: ${{ secrets.JUNO_BASE_URL }}
JUNO_SENDER_EMAIL: ${{ secrets.JUNO_SENDER_EMAIL }}
JUNO_SENDER_NAME: ${{ secrets.JUNO_SENDER_NAME }}

keepalive-job:
name: Keepalive Workflow
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- uses: actions/checkout@v4
- uses: gautamkrishnar/[email protected]
Binary file added backend/public/healing4heroes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions hours-email-reminder/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
DATABASE_URL=""
DATABASE_NAME=""
JUNO_API_KEY=""
JUNO_BASE_URL=""
JUNO_SENDER_EMAIL=""
JUNO_SENDER_NAME=""
1 change: 1 addition & 0 deletions hours-email-reminder/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
15 changes: 15 additions & 0 deletions hours-email-reminder/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Use the official Node.js image as base
FROM node:latest

# Set working directory
WORKDIR /app

# Copy package.json and package-lock.json to the working directory
COPY ./package*.json ./

# Install dependencies
RUN npm install

COPY . ./

CMD ["npx", "tsx", "/app/send-hour-email.ts"]
5 changes: 5 additions & 0 deletions hours-email-reminder/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: "Run Send Reminder Email"
description: "Executes the script which sends a reminder email to all users with less than 800 hours"
runs:
using: "docker"
image: "Dockerfile"
70 changes: 70 additions & 0 deletions hours-email-reminder/email.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
doctype html
html(lang="en" dir="ltr" xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office")
head
meta(charset="UTF-8")
meta(name="viewport" content="width=device-width, initial-scale=1")
meta(name="x-apple-disable-message-reformatting")
meta(http-equiv="X-UA-Compatible" content="IE=edge")
meta(name="format-detection" content="telephone=no")
title Copy of (2) New Message
style.
.rollover:hover .rollover-first { max-height:0px!important; display:none!important; }
.rollover:hover .rollover-second { max-height:none!important; display:block!important; }
.rollover span { font-size:0px; }
u + .body img ~ div div { display:none; }
#outlook a { padding:0; }
span.MsoHyperlink, span.MsoHyperlinkFollowed { color:inherit; mso-style-priority:99; }
a.es-button { mso-style-priority:100!important; text-decoration:none!important; }
a[x-apple-data-detectors], #MessageViewBody a { color:inherit!important; text-decoration:none!important; font-size:inherit!important; font-family:inherit!important; font-weight:inherit!important; line-height:inherit!important; }
.es-desk-hidden { display:none; float:left; overflow:hidden; width:0; max-height:0; line-height:0; mso-hide:all; }
body(style="width:100%;height:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;padding:0;margin:0")
.es-wrapper-color(style="background-color:#F6F6F6")
table.es-wrapper(role="none" cellspacing="0" cellpadding="0" width="100%" style="border-collapse:collapse;width:100%;height:100%;background-repeat:repeat;background-position:center top;background-color:#F6F6F6")
tr
td(valign="top")
table.es-header(role="none" cellspacing="0" cellpadding="0" align="center" style="width:100%;background-color:transparent")
tr
td(align="center")
table.es-header-body(role="none" cellspacing="0" cellpadding="0" align="center" bgcolor="#ffffff" style="background-color:#FFFFFF;width:600px")
tr
td(align="left" style="padding:20px 150px")
table.es-right(role="none" cellspacing="0" cellpadding="0" align="right" style="float:right")
tr
td(align="left" style="width:300px")
table(role="presentation" width="100%" cellspacing="0" cellpadding="0")
tr
td(align="center" style="font-size:0")
img.adapt-img(src="https://epiujlr.stripocdn.email/content/guids/CABINET_b671897a35158e25b88e73b31b95f12e48ace5edc8e5b734899d083c66476053/images/h4hlogo_zhD.png" alt="" width="150" height="161" style="display:block;border:0")

table.es-content(role="none" cellspacing="0" cellpadding="0" align="center" style="width:100%")
tr
td(align="center")
table.es-content-body(role="none" cellspacing="0" cellpadding="0" align="center" bgcolor="#ffffff" style="background-color:#FFFFFF;width:600px")
tr
td(align="left" style="padding:20px")
table(role="none" width="100%" cellspacing="0" cellpadding="0")
tr
td(align="center" style="width:560px")
table(role="presentation" width="100%" cellspacing="0" cellpadding="0")
tr
td(align="left")
p This is a friendly reminder that completing 800 hours of training is required in order to attend our 4-day advanced training at Camp Grace in Mobile, Alabama! Please make sure to track your progress and work towards the 800-hour goal. This training is essential to help you gain the skills and knowledge needed for success in the program. Thank you for your commitment, and we look forward to seeing you at Camp Grace!

table.es-footer(role="none" cellspacing="0" cellpadding="0" align="center" style="width:100%;background-color:transparent")
tr
td(align="center")
table.es-footer-body(role="none" cellspacing="0" cellpadding="0" align="center" bgcolor="#ffffff" style="background-color:#FFFFFF;width:600px")
tr
td(align="left" style="padding:20px")
table.es-left(role="none" cellspacing="0" cellpadding="0" align="left" style="float:left")
tr
td(align="left" class="es-m-p20b" style="width:270px")
table(role="none" width="100%" cellspacing="0" cellpadding="0")
tr
td(align="center" style="display:none")
table.es-right(role="none" cellspacing="0" cellpadding="0" align="right" style="float:right")
tr
td(align="left" style="width:270px")
table(role="none" width="100%" cellspacing="0" cellpadding="0")
tr
td(align="center" style="display:none")
135 changes: 135 additions & 0 deletions hours-email-reminder/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import mongoose from "mongoose";
import { HandlerType, Role, User, ServiceAnimal } from "./types";
const { Schema } = mongoose;

const UserSchema = new Schema<User>({
email: {
type: String,
required: true,
unique: true,
index: true,
},
firstName: {
type: String,
required: false,
},
lastName: {
type: String,
required: false,
},
annualPetVisitDay: {
type: Date,
required: true,
default: Date.now(),
},
nextPrescriptionReminder: {
type: Date,
required: false,
},
address: {
type: String,
required: true,
default: "",
},
firebaseUid: {
type: String,
required: true,
unique: true,
},
birthday: {
type: Date,
required: false,
},
handlerType: {
type: String,
required: false,
enum: Object.values(HandlerType),
},
roles: {
type: [String],
required: true,
enum: Object.values(Role),
default: [],
},
verifiedByAdmin: {
type: Boolean,
required: true,
default: false,
},
profileImage: {
type: String,
required: false,
},
emailVerified: {
type: Boolean,
required: true,
default: false,
},
});
export const UserModel = mongoose.models.User as mongoose.Model<User> || mongoose.model("User", UserSchema);



const AnimalSchema = new Schema<ServiceAnimal>({
handler: {
type: mongoose.Types.ObjectId,
required: true,
},
name: {
type: String,
required: true,
},
totalHours: {
type: Number,
required: true,
default: 0,
},
subHandler: {
name: {
type: String,
required: false,
},
relation: {
type: String,
required: false,
},
type: {
type: String,
required: false,
enum: Object.values(HandlerType),
},
},
dateOfBirth: {
type: Date,
required: false,
},
dateOfAdoption: {
type: Date,
required: false,
},
dateOfRabiesShot: {
type: Date,
required: false,
},
rabiesShotTimeInterval: {
type: Number,
required: false,
},
dateOfTrainingClass: {
type: Date,
required: false,
},
microchipExpiration: {
type: Date,
required: false,
},
checkUpDate: {
type: Date,
required: false,
},
profileImage: {
type: String,
required: false,
},
});
export const AnimalModel = mongoose.models.Animal as mongoose.Model<ServiceAnimal> || mongoose.model<ServiceAnimal>("Animal", AnimalSchema);
Loading

0 comments on commit 7295f7f

Please sign in to comment.