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., [email protected])
  3. Verify domain ownership (add DNS records)
4

Configure environment

Add to your .env file:
.env
BREVO_API_KEY=xkeysib-abc123...
APP_MAIL_FROM=[email protected]

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: [email protected]Requirements:
  • 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 [email protected]
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 "[email protected]" \
  -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": "[email protected]"},
    "to": [{"email": "[email protected]"}],
    "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

Build docs developers (and LLMs) love