Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/diarpicu2022-commits/backend-AgroPulse/llms.txt

Use this file to discover all available pages before exploring further.

When AgroPulse detects a sensor anomaly, it automatically notifies the people responsible for that greenhouse. Notifications travel over two channels in parallel: email via SendGrid and WhatsApp via CallMeBot. Both channels are protected by circuit breakers that prevent a failing external service from slowing down or blocking the detection loop.
Email notifications only fire if the SENDGRID_API_KEY environment variable is set and non-empty. If the variable is absent, the email step is silently skipped. WhatsApp notifications require a callmebotApikey set on each recipient record independently of SENDGRID_API_KEY.

Notification flow

When the anomaly detection sweep finishes evaluating sensors, it collects all unnotified anomalies and dispatches them in sequence:
  1. The anomaly is looked up alongside its sensor and greenhouse name.
  2. An Alert record is inserted so the anomaly appears in the dashboard feed.
  3. NotificationService.notifyAnomaly() is called with the anomaly details.
  4. For each active recipient of that greenhouse, an email and/or WhatsApp message is sent depending on which contact details are present.
  5. The anomaly’s notified flag is set to true so it is not dispatched again.

Setting up notifications

1

Configure the SendGrid API key

Set the following environment variables in your deployment. The SENDGRID_FROM_EMAIL variable controls the sender address shown in the email.
SENDGRID_API_KEY=SG.xxxxxxxxxxxxxxxxxxxx
SENDGRID_FROM_EMAIL=alerts@yourdomain.com
Without SENDGRID_API_KEY, the email step is skipped entirely. SendGrid account and a verified sender identity are required on the SendGrid side.
2

Add alert recipients

Recipients are configured per greenhouse via the /api/alert-recipients endpoint. Each recipient can have an email address, a WhatsApp phone number, or both.
# Add a recipient who receives both email and WhatsApp
curl -X POST https://your-api.example.com/api/alert-recipients \
  -H "Content-Type: application/json" \
  -d '{
    "greenhouseId": 3,
    "name": "Isabel García",
    "email": "isabel@farm.com",
    "phone": "34600000000",
    "callmebotApikey": "your-callmebot-api-key",
    "active": true
  }'
To receive WhatsApp messages, the recipient must first message the CallMeBot service to obtain their personal callmebotApikey. See the CallMeBot documentation for setup instructions.Recipients with no callmebotApikey receive only email. Recipients with no email receive only WhatsApp. A recipient with neither will not receive any notification until contact details are added.
3

Configure sensor thresholds

Notifications only fire when an anomaly is detected, and anomalies are only detected for sensors that have an active SensorThreshold record. Create thresholds via /api/sensor-thresholds with minValue, maxValue, noDataMinutes, stuckMinutes, and spikePercent values appropriate for each sensor type.See Automated sensor anomaly detection for a full explanation of how thresholds map to anomaly conditions.

Email notifications

Emails are sent via the SendGrid Java SDK. Each email includes the greenhouse name, sensor name, anomaly type, the value at detection time, and the detection timestamp. Messages are sent as HTML. The subject line follows the pattern: [AgroPulse] Anomalía: {TYPE} — Sensor "{name}"

WhatsApp notifications

WhatsApp messages are delivered via the CallMeBot free API. The message is a compact single-line text containing the anomaly type, sensor name, greenhouse name, detected value, and timestamp. Each recipient stores their own callmebotApikey in the alert_recipients table. The API key is per-phone-number and is obtained directly from CallMeBot by the recipient.

Circuit breakers

Both delivery channels are wrapped in Resilience4j circuit breakers to prevent a degraded external API from causing cascading failures in the detection loop.
ParameterSendGridCallMeBot
Sliding window size5 calls5 calls
Failure rate threshold60%60%
Pause duration when open30 seconds60 seconds
When the failure rate exceeds 60% within the last 5 calls, the circuit opens and all further calls to that channel are skipped until the pause duration elapses. A warning is logged for each skipped notification. After the pause, the circuit enters a half-open state and allows one trial call through before deciding whether to close again. A failed notification does not prevent the anomaly from being marked as notified. The delivery failure is logged but the anomaly cycle continues.

Build docs developers (and LLMs) love