backend/src/api/trip-alert/services/trip-alert.ts (view raw)
1import { factories } from "@strapi/strapi";
2import pMap from "p-map";
3import {
4 Coordinates,
5 calculateHaversineDistance,
6} from "../../../utils/geography";
7
8export default factories.createCoreService(
9 "api::trip-alert.trip-alert",
10 ({ strapi }) => ({
11 async sendTripAlerts(eventId: string, travel) {
12 if (!travel.meeting_latitude || !travel.meeting_longitude) {
13 strapi.log.warn(
14 `Can't send trip alert for travel ${travel.id}. No coordinates found.`
15 );
16 return;
17 }
18
19 const travelCoordinates: Coordinates = [
20 travel.meeting_latitude,
21 travel.meeting_longitude,
22 ];
23 const eventTripAlerts = await strapi.entityService.findMany(
24 "api::trip-alert.trip-alert",
25 {
26 filters: {
27 enabled: true,
28 event: { id: eventId },
29 },
30 populate: ["user"],
31 }
32 );
33 const filteredTripAlerts = eventTripAlerts.filter((tripAlert) => {
34 // If alert has no geographical info, send alert on each new trip
35 if (!tripAlert.latitude || !tripAlert.longitude || !tripAlert.radius)
36 return true;
37
38 // Else, check if new travel is in alert area
39 const alertCoordinates: Coordinates = [
40 tripAlert.latitude,
41 tripAlert.longitude,
42 ];
43 const distance = calculateHaversineDistance(
44 travelCoordinates,
45 alertCoordinates
46 );
47 return distance <= tripAlert.radius;
48 });
49
50 await pMap(filteredTripAlerts, async (tripAlert) => {
51 strapi.log.debug(
52 `Create trip alert notification for user ${tripAlert.user.id}`
53 );
54 strapi.entityService.create("api::notification.notification", {
55 data: {
56 type: "NewTrip",
57 event: eventId,
58 user: tripAlert.user.id,
59 },
60 });
61 });
62 },
63 })
64);