Public
HTTP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { bearerAuth } from "npm:hono/bearer-auth";
import { cors } from "npm:hono/cors";
import { Hono } from "npm:hono@3";
import Typesense from "npm:typesense";
import type { SearchParams, SearchParamsWithPreset, SearchResponseHit } from "npm:typesense/lib/Typesense/Documents";
const MAX_SEARCH_RADIUS_IN_MILES = 10;
const COLLECTIONS = {
"resources": "resources",
};
const typesenseClient = new Typesense.Client({
"nodes": [{
"host": Deno.env.get("TYPESENSE_HOST") || "", // For Typesense Cloud use xxx.a1.typesense.net
"port": 443, // For Typesense Cloud use 443
"protocol": "https", // For Typesense Cloud use https
}],
"apiKey": Deno.env.get("TYPESENSE_API_KEY") || "",
"connectionTimeoutSeconds": 10,
"retryIntervalSeconds": 0.1,
"healthcheckIntervalSeconds": 2,
"logLevel": "debug",
});
interface Resource {
id: string;
name: string;
address: {
full_address: string;
latitude: number;
longitude: number;
};
website: string;
phone: string;
user_email: string;
description: string;
utc_offset: number;
featured_image_url: string;
hours_text: string | null;
hours: {
day: string;
day_int: number;
open_time: string | null;
close_time: string | null;
}[];
services: {
id: string | number;
name: string;
description: string;
category: {
icon: string;
name: ResourceTypes;
};
}[];
qualifications: {
id: string | number;
name: string;
}[];
// Custom field added by Cameron Pak to calculate on the fly.
distance_between: number;
}
const CATEGORY_IDS_FROM_TYPESENSE = {
// Favorites does not exist in Typesense but is a ResourceTypes type.
"Favorites": -1,
"Food": 53,
"Shelter": 52,
"Churches": 56,
"Resources": 57,
"Medical": 54,
"Addiction Recovery": 58,
"Domestic Violence": 51,
"Housing": 69,
};
type ResourceTypes = keyof typeof CATEGORY_IDS_FROM_TYPESENSE;
/**
* Converts meters to miles.
*
* @param {number} meters - the distance in meters to convert
* @return {number} the distance in miles
*/
function convertMetersToMiles(meters: number): number {
return 0.000621371 * meters;
}
// Round a number to the nearest quarter.
function roundToQuarter(number: number) {
let remainder = number % 1;
// I only want 1/8th of a mile to appear when when that's the only remainder.
if (number < 1 && remainder <= 0.125) {
return Math.floor(number) + 0.125;
} else if (remainder <= 0.375) {
return Math.floor(number) + 0.25;
} else if (remainder <= 0.625) {
return Math.floor(number) + 0.50;
} else if (remainder <= 0.875) {
return Math.floor(number) + 0.75;
} else {
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
May 24, 2024
This is cool! What is this val for?
Dude, you're THE STEVE, @stevekrouse!
This is an API endpoint I built for a ChatGPT Assistant to fetch homeless resources nearby given I pass in a geolocation coordinates. It gets our data that we house in Typesense to make it super fast. Imagine Google Maps for homeless resources, that's what we've built
https://app.homeless.resources
oof, I meant https://app.homeless.services
So cool!!! :)
Is there a way for me to demo the chatgpt assistant?
(I'd love to feature this in our next newsletter!)
I'm interested! but... our API isn't public for anyone to use. However, the ChatGPT Assistant would be available to anyone! I couldn't however get ChatGPT Assistant to properly call the endpoint from ValTown, oddly enough
Here's the ChatGPT Assistant
Here's the endpoint it should be hitting:![](https://drive.google.com/uc?export=download&id=1ikXeOEoiDTUoDb8iQ2sjWr5ZpM3lmPuQ)
I'd love our tech to be part of the newsletter :) This is from https://OurTechnology.co
So, it's like 90% complete. When the I can figure out why the GPT action isn't working properly, then it's good to go!
Also, @stevekrouse, do I need to tag you or since you've commented you'll get notifications anyways?
Great question - I get notifications because I commented :)
Let me see if I can help you fix the GPT action...
Probably easiest on a call - have time today? Shoot me a note - steve@val.town :)
I'm down! Email sent :)
Ping me (or comment here) when you add a readme - then i'll tweet about it :)
@stevekrouse, it's ready :)