enh
This commit is contained in:
parent
ba14653721
commit
64d4d26909
8 changed files with 426 additions and 597 deletions
|
|
@ -23,15 +23,13 @@
|
|||
"license": "ISC",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.888.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.888.0",
|
||||
"@hono/node-server": "^1.19.11",
|
||||
"@hono/trpc-server": "^0.4.2",
|
||||
"@trpc/server": "^11.6.0",
|
||||
"@turf/turf": "^7.2.0",
|
||||
"@turf/boolean-point-in-polygon": "^7.2.0",
|
||||
"@turf/helpers": "^7.2.0",
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"aws4fetch": "^1.0.20",
|
||||
"axios": "^1.11.0",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"dayjs": "^1.11.18",
|
||||
"dotenv": "^17.2.1",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { Buffer } from 'buffer'
|
||||
import axios from 'axios'
|
||||
import { scaffoldProducts } from '@/src/trpc/apis/common-apis/common'
|
||||
import { scaffoldEssentialConsts } from '@/src/trpc/apis/common-apis/common-trpc-index'
|
||||
import { scaffoldStores } from '@/src/trpc/apis/user-apis/apis/stores'
|
||||
|
|
@ -180,18 +179,19 @@ export async function clearUrlCache(urls: string[]): Promise<{ success: boolean;
|
|||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
const resp = await fetch(
|
||||
`https://api.cloudflare.com/client/v4/zones/${cloudflareZoneId}/purge_cache`,
|
||||
{ files: urls },
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${cloudflareApiToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ files: urls }),
|
||||
}
|
||||
)
|
||||
|
||||
const result = response.data as { success: boolean; errors?: { message: string }[] }
|
||||
const result = await resp.json() as { success: boolean; errors?: { message: string }[] }
|
||||
|
||||
if (!result.success) {
|
||||
const errorMessages = result.errors?.map(e => e.message) || ['Unknown error']
|
||||
|
|
@ -218,18 +218,19 @@ export async function clearAllCache(): Promise<{ success: boolean; errors?: stri
|
|||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
const resp = await fetch(
|
||||
`https://api.cloudflare.com/client/v4/zones/${cloudflareZoneId}/purge_cache`,
|
||||
{ purge_everything: true },
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${cloudflareApiToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ purge_everything: true }),
|
||||
}
|
||||
)
|
||||
|
||||
const result = response.data as { success: boolean; errors?: { message: string }[] }
|
||||
const result = await resp.json() as { success: boolean; errors?: { message: string }[] }
|
||||
|
||||
if (!result.success) {
|
||||
const errorMessages = result.errors?.map(e => e.message) || ['Unknown error']
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
import axios from 'axios';
|
||||
|
||||
export async function extractCoordsFromRedirectUrl(url: string): Promise<{ latitude: string; longitude: string } | null> {
|
||||
try {
|
||||
await axios.get(url, { maxRedirects: 0 });
|
||||
return null;
|
||||
} catch (error: any) {
|
||||
if (error.response?.status === 302 || error.response?.status === 301) {
|
||||
const redirectUrl = error.response.headers.location;
|
||||
const coordsMatch = redirectUrl.match(/!3d([-\d.]+)!4d([-\d.]+)/);
|
||||
const response = await fetch(url, { redirect: 'manual' })
|
||||
if (response.status === 301 || response.status === 302) {
|
||||
const redirectUrl = response.headers.get('location')
|
||||
if (redirectUrl) {
|
||||
const coordsMatch = redirectUrl.match(/!3d([-\d.]+)!4d([-\d.]+)/)
|
||||
if (coordsMatch) {
|
||||
return {
|
||||
latitude: coordsMatch[1],
|
||||
longitude: coordsMatch[2],
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
// import { Queue, Worker } from 'bullmq';
|
||||
import { Expo } from 'expo-server-sdk';
|
||||
// import { db } from '@/src/db/db_index'
|
||||
import { scaffoldAssetUrl } from '@/src/lib/s3-client'
|
||||
import { queueDataPusher } from '@/src/lib/queue-data-pusher'
|
||||
|
|
@ -51,6 +50,7 @@ export async function sendAdminNotification(data: {
|
|||
imageUrl: string | null;
|
||||
}) {
|
||||
const { token, title, body, imageUrl } = data;
|
||||
const { Expo } = await import('expo-server-sdk')
|
||||
|
||||
// Validate Expo push token
|
||||
if (!Expo.isExpoPushToken(token)) {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
import axios from 'axios';
|
||||
import { getIsDevMode, getTelegramBotToken, getTelegramChatIds } from '@/src/lib/env-exporter'
|
||||
|
||||
/**
|
||||
* Send a message to Telegram bot
|
||||
* @param message The message text to send
|
||||
* @returns Promise<boolean | null> indicating success, failure, or null if dev mode
|
||||
*/
|
||||
export const sendTelegramMessage = async (message: string): Promise<boolean | null> => {
|
||||
if (getIsDevMode()) {
|
||||
return null;
|
||||
|
|
@ -21,33 +15,32 @@ export const sendTelegramMessage = async (message: string): Promise<boolean | nu
|
|||
const results = await Promise.all(
|
||||
chatIds.map(async (chatId) => {
|
||||
try {
|
||||
const response = await axios.post(`${telegramApiUrl}/sendMessage`, {
|
||||
chat_id: chatId,
|
||||
text: message,
|
||||
parse_mode: 'HTML',
|
||||
});
|
||||
const response = await fetch(`${telegramApiUrl}/sendMessage`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ chat_id: chatId, text: message, parse_mode: 'HTML' }),
|
||||
})
|
||||
const data = await response.json() as { ok: boolean }
|
||||
|
||||
if (response.data && response.data.ok) {
|
||||
console.log(`Telegram message sent successfully to ${chatId}`);
|
||||
return true;
|
||||
if (data.ok) {
|
||||
console.log(`Telegram message sent successfully to ${chatId}`)
|
||||
return true
|
||||
} else {
|
||||
console.error(`Telegram API error for ${chatId}:`, response.data);
|
||||
return false;
|
||||
console.error(`Telegram API error for ${chatId}:`, data)
|
||||
return false
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to send Telegram message to ${chatId}:`, error);
|
||||
return false;
|
||||
console.error(`Failed to send Telegram message to ${chatId}:`, error)
|
||||
return false
|
||||
}
|
||||
})
|
||||
);
|
||||
)
|
||||
|
||||
console.log('sent telegram message successfully')
|
||||
|
||||
|
||||
// Return true if at least one message was sent successfully
|
||||
return results.some((result) => result);
|
||||
return results.some((result) => result)
|
||||
} catch (error) {
|
||||
console.error('Failed to send Telegram message:', error);
|
||||
return false;
|
||||
console.error('Failed to send Telegram message:', error)
|
||||
return false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ import {
|
|||
getCacheVersion,
|
||||
} from '@/src/dbService'
|
||||
import type { StoresSummaryResponse } from '@packages/shared'
|
||||
import * as turf from '@turf/turf';
|
||||
import { polygon as turfPolygon, point as turfPoint } from '@turf/helpers';
|
||||
import { booleanPointInPolygon } from '@turf/boolean-point-in-polygon';
|
||||
import { z } from 'zod';
|
||||
import { mbnrGeoJson } from '@/src/lib/mbnr-geojson'
|
||||
import { generateUploadUrl } from '@/src/lib/s3-client'
|
||||
|
|
@ -15,7 +16,7 @@ import { getAllConstValues } from '@/src/lib/const-store'
|
|||
import { CONST_KEYS } from '@/src/lib/const-keys'
|
||||
import { getAssetsDomain, getApiCacheKey } from '@/src/lib/env-exporter'
|
||||
|
||||
const polygon = turf.polygon(mbnrGeoJson.features[0].geometry.coordinates);
|
||||
const polygon = turfPolygon(mbnrGeoJson.features[0].geometry.coordinates);
|
||||
|
||||
export async function scaffoldEssentialConsts() {
|
||||
const consts = await getAllConstValues();
|
||||
|
|
@ -76,8 +77,8 @@ export const commonApiRouter = router({
|
|||
.query(({ input }) => {
|
||||
try {
|
||||
const { lat, lng } = input;
|
||||
const point = turf.point([lng, lat]); // GeoJSON: [longitude, latitude]
|
||||
const isInside = turf.booleanPointInPolygon(point, polygon);
|
||||
const point = turfPoint([lng, lat]); // GeoJSON: [longitude, latitude]
|
||||
const isInside = booleanPointInPolygon(point, polygon);
|
||||
return { isInside };
|
||||
} catch (error) {
|
||||
throw new Error('Invalid coordinates or polygon data');
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ import {
|
|||
|
||||
export { CacheCreator }
|
||||
|
||||
let app: ReturnType<typeof createApp> | null = null
|
||||
|
||||
export default {
|
||||
async fetch(
|
||||
request: Request,
|
||||
|
|
@ -33,9 +35,10 @@ export default {
|
|||
},
|
||||
ctx: ExecutionContext
|
||||
) {
|
||||
console.log(env)
|
||||
ensureWorkerInit(env)
|
||||
const app = createApp()
|
||||
if (!app) {
|
||||
app = createApp()
|
||||
}
|
||||
return app.fetch(request, env, ctx)
|
||||
},
|
||||
async queue(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue