Skip to main content
Version: 1.0.0

licenseHasExpired

Email Templatesโ€‹

License ExpiredGrace Period Expired
License Expired TemplateGrace License Expired Template
30 Days Warning60 Days Warning
30 Days Warning Template60 Days Warning Template

Function Names: licenseHasExpired / testLicenseHasExpired

Trigger: Scheduler (onSchedule - daily at 18:00) / HTTPS (onRequest)

Purpose: Daily notification system for license management in ARShades Subscription System. This Cloud Function checks licenses daily and sends notifications to clients at key moments. It uses ZeptoMail as the primary email system and Nodemailer as fallback with specific templates for different notification types.

Detailed Functionalityโ€‹

1. TRIGGER AND SCHEDULINGโ€‹

  • Automatic execution daily at 18:00 (Europe/Rome timezone)
  • Can be executed manually via HTTP endpoint for testing
  • Execution region: europe-central2

2. LICENSE RETRIEVAL AND ANALYSISโ€‹

  • Queries 'ARShadesSubscriptions' collection for all licenses
  • Filters only licenses with "Active" or "Expired" status
  • Verifies presence of valid expiration date
  • Handles different timestamp formats for expiration date
  • Calculates remaining days until expiration

3. PRELIMINARY OPTIMIZATIONโ€‹

  • Checks if notifications need to be sent BEFORE expensive database queries
  • Verifies if license is at 60 days, 30 days from expiration, just expired, or 15 days after expiration
  • Skips processing if no notification is needed

4. NOTIFICATION TYPESโ€‹

a. 60 Days Warning (SixtyDaysWarning)

  • Sent when exactly 60 days remain until expiration
  • Template: SIXTY_DAYS

b. 30 Days Warning (ThirtyDaysWarning)

  • Sent when exactly 30 days remain until expiration
  • Template: THIRTY_DAYS

c. Expiration Notification (Expired)

  • Sent when license expires (endDate reached)
  • Updates license status to 'Expired'
  • Template: EXPIRED

d. Grace Period End Notification (GracePeriodEnd)

  • Sent 15 days after expiration
  • Verifies that status is 'Expired'
  • Template: GRACE_PERIOD_END

5. PRELIMINARY CHECKSโ€‹

  • Verifies if email sending is blocked (blockSendMail = true)
  • Checks if notification of same type was already sent
  • Verifies presence of client reference (clientRef)

6. CLIENT DATA AND PROFILES RETRIEVALโ€‹

  • Retrieves client document from 'Client' collection
  • Gets list of catalogs associated with license (supports different storage formats)
  • Extracts associated profiles (allProfileList and mainProfileList)

7. EMAIL RECIPIENTS SELECTION (UPDATED LOGIC)โ€‹

  • For each profile in allProfileList, verifies access to license catalogs
  • IMPORTANT: Selects ONLY profiles with 'Cliente' role (excludes Admin, etc.)
  • Verifies intersection between profile catalogs and license catalogs
  • NEW LOGIC: If no profile has specific access BUT profiles exist in mainProfileList, email is still sent
  • SKIPS ONLY if: profilesWithAccess.length === 0 AND mainProfileList.length === 0
  • Logs debug details for each analyzed profile
  • Handles errors for profiles not found or not accessible

8. EMAIL DATA PREPARATIONโ€‹

  • Formats expiration and grace period dates in Italian format
  • Retrieves main profile information for personalization
  • Prepares TO (profiles with access), CC (main profiles) and BCC (admin) recipients
  • FIX APPLIED: Resolved licenseName/formattedLicenseName variable scoping conflict

9. EMAIL SENDING WITH ZEPTOMAILโ€‹

  • Uses appropriate template for each notification type
  • Passes necessary variables to template (license name, main profile, dates)
  • Handles TO, CC and BCC with full names when available

10. IMPROVED FALLBACK HANDLINGโ€‹

  • In case of ZeptoMail error, uses Nodemailer with specific templates for each notification type
  • NEW FALLBACK TEMPLATES:
    • SixtyDaysWarning: "Warning: License will expire in 60 days" (orange)
    • ThirtyDaysWarning: "Urgent: License will expire in 30 days" (dark orange)
    • Expired: "EXPIRED: License expired today" (red, with grace period info)
    • GracePeriodEnd: "CRITICAL: Grace period ended" (dark red, service suspended)
  • Professional HTML templates with appropriate colors and clean layout
  • Correct dates and content for each scenario (future expiration vs already expired)
  • Sent only to profiles in mainProfileList
  • Logs errors from both main system and fallback

11. LICENSE DOCUMENT UPDATEโ€‹

  • After successful sending, updates 'notifications' array
  • Adds new object with specific notification type and sendDate
  • If expiration notification, also updates status to 'Expired'

12. ADVANCED LOGGING AND MONITORINGโ€‹

  • Logs complete details of each process phase
  • Tracks successes, errors and fallback attempts
  • Produces categorized final summary (emails sent, no action, skipped, etc.)
  • Provides aggregate statistics by result type

Input (Payload)โ€‹

Scheduler Function (licenseHasExpired)โ€‹

  • Automatic trigger: No input required (scheduled execution)
  • Schedule: Daily at 18:00 Europe/Rome timezone

HTTP Function (testLicenseHasExpired)โ€‹

  • Method: GET
  • Headers: None required
  • Body: None required
  • Parameters: None required

Output (Success)โ€‹

Scheduler Functionโ€‹

{
"success": true,
"processed": true,
"results": [
{
"licenseId": "license123",
"licenseName": "ARShades Pro - Standard",
"recipients": ["user@example.com"],
"success": true
}
]
}

HTTP Functionโ€‹

{
"success": true,
"message": "Controllo licenze scadute completato con successo",
"results": [
{
"licenseId": "license123",
"licenseName": "ARShades Pro - Standard",
"recipients": ["user@example.com"],
"success": true,
"fallback": false
}
]
}

Response Properties:

  • success (boolean): Indicates if the operation was completed successfully
  • message (string): Descriptive message about the operation result
  • results (array): Array of processed licenses with details
  • licenseId (string): Unique identifier of the processed license
  • licenseName (string): Name and type of the license
  • recipients (array): List of email addresses that received the notification
  • fallback (boolean): Indicates if Nodemailer fallback was used

Testingโ€‹

URL (if HTTPS)โ€‹

Development: http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired

Test with Emulatorโ€‹

  1. Start Firebase emulators:

    firebase emulators:start --only functions
  2. Set Node.js version:

    nvm use 20
  3. Test with curl:

    curl "http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired"

Postman Testingโ€‹

  • Method: GET
  • URL: http://127.0.0.1:5001/arshadesstaging/us-central1/testLicenseHasExpired
  • Headers: None required
  • Body: None required

Deploy Commandโ€‹

firebase deploy --only functions:licenseHasExpired,functions:testLicenseHasExpired

Production URLโ€‹

Scheduled Function: https://europe-central2-arshades-7e18a.cloudfunctions.net/licenseHasExpired (Reference only - not directly callable)

Test Function: https://europe-central2-arshades-7e18a.cloudfunctions.net/testLicenseHasExpired

MAIL_TEMPLATE_KEYSโ€‹

  • EXPIRED: 13ef.8598f19fbcc5adb.k1.9902c130-46a8-11f0-900d-dad70ff08860.1975e5ffcc38
  • SIXTY_DAYS: 13ef.8598f19fbcc5adb.k1.c7e1eee0-46d0-11f0-900d-dad70ff08860.1975f6754ce
  • THIRTY_DAYS: 13ef.8598f19fbcc5adb.k1.dec244d1-46d4-11f0-900d-dad70ff08860.1975f82218d
  • GRACE_PERIOD_END: 13ef.8598f19fbcc5adb.k1.13d51510-46d7-11f0-900d-dad70ff08860.1975f9098e1