Skip to main content

Overview

Hub integrates with several third-party services to provide media storage, email notifications, and authentication. This guide covers configuration for all external integrations.

Cloudinary (Media Storage)

Cloudinary provides cloud-based image and video management for venue photos and user profile pictures.

Features

  • Image upload and storage
  • Automatic image optimization
  • Responsive image transformations
  • CDN delivery
  • Image format conversion (WebP, AVIF)

Setup

1

Create Cloudinary account

  1. Sign up at cloudinary.com
  2. Choose the free tier (includes 25GB storage and 25GB bandwidth)
  3. Access your dashboard to get credentials
2

Get credentials

From your Cloudinary dashboard, note:
  • Cloud Name: Your unique cloud identifier
  • API Key: Public API key
  • API Secret: Private secret key
3

Configure environment

Add to your .env file:
.env
CLOUDINARY_CLOUD_NAME=your-cloud-name
CLOUDINARY_API_KEY=123456789012345
CLOUDINARY_API_SECRET=your_secret_key_here
4

Create upload presets (optional)

In Cloudinary dashboard:
  1. Go to Settings > Upload
  2. Create upload presets for different image types:
    • venue_photos - Max 2000x2000px, JPEG quality 85
    • profile_pictures - Max 500x500px, crop to square

Configuration

CLOUDINARY_CLOUD_NAME
string
required
Your Cloudinary cloud nameExample: padelhub-media, hub-prodFound in your Cloudinary dashboard header.
CLOUDINARY_API_KEY
string
required
Cloudinary API key for authenticationFormat: 15-digit numberExample: 123456789012345
CLOUDINARY_API_SECRET
string
required
Cloudinary API secret for signing requests
Keep this secret secure. Never expose in client-side code or commit to version control.

Usage in Application

The backend uses Cloudinary for:

Venue Photos

Upload venue photo
CloudinaryAdapter cloudinary;

public String uploadVenuePhoto(MultipartFile file, Long venueId) {
    return cloudinary.uploadImage(
        file,
        Map.of(
            "folder", "venues/" + venueId,
            "transformation", List.of(
                Map.of("width", 2000, "height", 2000, "crop", "limit"),
                Map.of("quality", "auto:good")
            )
        )
    );
}

User Profile Pictures

Upload profile picture
public String uploadProfilePicture(MultipartFile file, String userId) {
    return cloudinary.uploadImage(
        file,
        Map.of(
            "folder", "users/" + userId,
            "transformation", Map.of(
                "width", 500,
                "height", 500,
                "crop", "fill",
                "gravity", "face"
            )
        )
    );
}

Image Transformations

Cloudinary URLs support on-the-fly transformations:
// Original
https://res.cloudinary.com/padelhub/image/upload/v1234/venues/1/photo.jpg

// Thumbnail (300x300)
https://res.cloudinary.com/padelhub/image/upload/w_300,h_300,c_fill/v1234/venues/1/photo.jpg

// WebP format
https://res.cloudinary.com/padelhub/image/upload/f_webp/v1234/venues/1/photo.jpg

// Optimized and responsive
https://res.cloudinary.com/padelhub/image/upload/w_auto,f_auto,q_auto/v1234/venues/1/photo.jpg

Best Practices

  • Use automatic format (f_auto) and quality (q_auto) for optimal delivery
  • Implement lazy loading for images
  • Use responsive image sizes with w_auto
  • Organize images in folders by entity type
  • Set up automatic backup and moderation rules

Brevo (Email Service)

Brevo (formerly Sendinblue) handles transactional emails for bookings, match requests, and notifications.

Features

  • Transactional email API
  • Email templates
  • Delivery tracking
  • SMTP relay
  • Free tier: 300 emails/day

Setup

1

Create Brevo account

  1. Sign up at brevo.com
  2. Verify your email address
  3. Complete account setup
2

Generate API key

  1. Go to Settings > API Keys
  2. Click Generate a new API key
  3. Give it a name (e.g., “Hub Production”)
  4. Copy the generated key
3

Configure sender

  1. Go to Settings > Senders
  2. Add your sending email address (e.g., noreply@padelhub.com)
  3. Verify domain ownership (add DNS records)
4

Configure environment

Add to your .env file:
.env
BREVO_API_KEY=xkeysib-abc123...
APP_MAIL_FROM=noreply@padelhub.com

Configuration

BREVO_API_KEY
string
required
Brevo API key for sending transactional emailsFormat: xkeysib- followed by 64 charactersDevelopment: Use dummy-key-for-local to log emails without sending
Keep your API key secure. Rotate regularly and never commit to version control.
APP_MAIL_FROM
string
Sender email address for all transactional emailsDefault: noreply@padelhub.comRequirements:
  • Must be verified in Brevo
  • Domain should have SPF and DKIM records configured
  • Use a no-reply address for transactional emails

Email Types

Hub sends the following transactional emails:
Sent when a booking is confirmed:
  • Booking details (venue, court, date/time)
  • Total cost
  • Cancellation policy
  • Link to view booking
Sent when a user receives a match request:
  • Sender information
  • Match details (venue, date/time)
  • Accept/decline links
Sent when a match request is accepted:
  • Confirmation message
  • Match details
  • Player contact information
Sent 24 hours before a booking:
  • Reminder message
  • Booking details
  • Venue address and directions
Sent after successful payment:
  • Payment amount
  • Payment method
  • Receipt number
  • Booking details

Usage in Application

The BrevoEmailSender component handles email delivery:
Send Email
@Component
public class BrevoEmailSender {
    
    @Value("${brevo.api.key}")
    private String apiKey;
    
    @Value("${app.mail.from}")
    private String from;
    
    public void send(String to, String subject, String htmlContent) {
        // Sends via Brevo API v3
        // POST https://api.brevo.com/v3/smtp/email
    }
}
Example usage:
Booking Confirmation Email
public void sendBookingConfirmation(Booking booking) {
    String html = templateEngine.process("booking-confirmation", 
        Map.of(
            "userName", booking.getUser().getName(),
            "venueName", booking.getResource().getVenue().getName(),
            "dateTime", booking.getStartTime(),
            "totalCost", booking.getTotalCost()
        )
    );
    
    brevoEmailSender.send(
        booking.getUser().getEmail(),
        "Booking Confirmed - " + booking.getResource().getVenue().getName(),
        html
    );
}

Email Templates

HTML email templates use Thymeleaf and are stored in:
backend/src/main/resources/templates/emails/
├── booking-confirmation.html
├── match-request.html
├── match-accepted.html
└── booking-reminder.html
Templates use Thymeleaf syntax for dynamic content insertion.

Development Mode

For local development without sending real emails:
.env.local
BREVO_API_KEY=dummy-key-for-local
With the dummy key, emails are logged to console instead of sent:
INFO : Would send email to user@example.com
INFO : Subject: Booking Confirmed
INFO : Body: <html>...</html>

Monitoring

Brevo Dashboard:
  • View email delivery statistics
  • Check bounce and spam rates
  • Monitor API usage
  • Review email logs
Application Logs:
log.info("Email sent via Brevo API to {}", to);

Auth0 (Authentication)

Auth0 integration is covered in detail in the Authentication Configuration guide.

Quick Reference

AUTH0_ISSUER
string
required
Auth0 domain for JWT validationExample: https://padelhub.eu.auth0.com/
AUTH0_AUDIENCE
string
required
Auth0 API audience identifierExample: https://api.padelhub.com
Learn more about Auth0 configuration →

Integration Health Checks

Testing Cloudinary

curl -X POST "https://api.cloudinary.com/v1_1/${CLOUDINARY_CLOUD_NAME}/image/upload" \
  -F "file=@test-image.jpg" \
  -F "api_key=${CLOUDINARY_API_KEY}" \
  -F "timestamp=$(date +%s)" \
  -F "signature=YOUR_SIGNATURE"

Testing Brevo

curl -X POST "https://api.brevo.com/v3/smtp/email" \
  -H "api-key: ${BREVO_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "sender": {"email": "noreply@padelhub.com"},
    "to": [{"email": "test@example.com"}],
    "subject": "Test Email",
    "htmlContent": "<p>Test message</p>"
  }'

Testing Auth0

curl "${AUTH0_ISSUER}.well-known/jwks.json"

Security Considerations

1

Rotate API keys regularly

Set up a schedule to rotate all API keys every 90 days.
2

Use environment-specific keys

Never share keys between development, staging, and production.
3

Monitor usage

Set up alerts for unusual API usage patterns:
  • Sudden spike in requests
  • High error rates
  • Quota approaching limits
4

Implement rate limiting

Protect against abuse:
  • Limit image uploads per user per hour
  • Throttle email sending
  • Implement CAPTCHA for public endpoints
5

Store secrets securely

Use secrets management:
  • AWS Secrets Manager
  • HashiCorp Vault
  • Azure Key Vault
  • Google Secret Manager

Cost Management

Cloudinary

Free Tier:
  • 25 GB storage
  • 25 GB monthly bandwidth
  • 25 credits/month
Optimization Tips:
  • Use automatic format and quality (f_auto, q_auto)
  • Enable lazy loading
  • Implement image size limits
  • Delete unused images regularly

Brevo

Free Tier:
  • 300 emails/day
  • Unlimited contacts
Optimization Tips:
  • Batch notification emails
  • Implement user email preferences
  • Use email templates efficiently
  • Monitor bounce rates

Auth0

Free Tier:
  • 7,000 monthly active users
  • Unlimited logins
Optimization Tips:
  • Implement token refresh to reduce authentication calls
  • Use appropriate token expiration times
  • Cache user profile data

Troubleshooting

Error: Invalid API keySolutions:
  • Verify CLOUDINARY_API_KEY and CLOUDINARY_API_SECRET are correct
  • Check API key hasn’t been revoked
  • Ensure cloud name matches your account
Error: Unauthorized or emails not deliveredSolutions:
  • Verify BREVO_API_KEY is valid
  • Check sender email is verified in Brevo
  • Review Brevo dashboard for blocked sends
  • Check DNS records (SPF, DKIM)
Error: Invalid issuer or Invalid audienceSolutions:
  • Verify AUTH0_ISSUER includes trailing slash
  • Ensure AUTH0_AUDIENCE matches Auth0 API identifier
  • Check Auth0 API is enabled
Issue: Approaching quota limitsSolutions:
  • Review usage patterns in dashboards
  • Implement caching where appropriate
  • Optimize image sizes and formats
  • Consolidate email notifications

Next Steps

Environment Setup

Complete environment configuration

Deployment Guide

Deploy to production

API Reference

Explore API endpoints

Backend Modules

Understand backend architecture