-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhandler.ts
135 lines (119 loc) · 3.6 KB
/
handler.ts
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { geoSearch } from "@justfixnyc/geosearch-requester/commonjs";
import fetch from "node-fetch";
export type DialogflowWebhookRequest = {
queryResult: {
queryText: string;
parameters: {
location: {
'business-name': string,
'street-address': string,
'subadmin-area': string,
}
}
}
};
export type DialogflowWebhookResponse = {
fulfillmentMessages: {
text: {
text: string[]
}
}[]
};
function splitBBL(bbl: string) {
const bblArr = bbl.split("");
const boro = bblArr.slice(0, 1).join("");
const block = bblArr.slice(1, 6).join("");
const lot = bblArr.slice(6, 10).join("");
return { boro, block, lot };
}
async function getLandlordInfo(bbl: string): Promise<SearchResults> {
const url = new URL('https://wow-django.herokuapp.com/api/address');
const params = splitBBL(bbl);
url.searchParams.append('borough', params.boro);
url.searchParams.append('block', params.block);
url.searchParams.append('lot', params.lot);
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Got HTTP ${res.status}`);
}
return res.json();
}
type GeoSearchData = {
bbl: string;
};
type Borough = "MANHATTAN" | "BRONX" | "BROOKLYN" | "QUEENS" | "STATEN ISLAND";
type HpdOwnerContact = {
title: string;
value: string;
};
/** Date fields that come from our API Data are strings with the format YYYY-MM-DD */
type APIDate = string;
type AddressRecord = {
bbl: string;
bin: string;
boro: Borough;
businessaddrs: string[] | null;
corpnames: string[] | null;
evictions: number | null;
housenumber: string;
lastregistrationdate: APIDate;
lastsaleacrisid: string | null;
lastsaleamount: number | null;
lastsaledate: APIDate | null;
lat: number | null;
lng: number | null;
/** This property gets assigned in the PropertiesMap component, not from our API */
mapType?: "base" | "search";
openviolations: number;
ownernames: HpdOwnerContact[] | null;
registrationenddate: APIDate;
registrationid: string;
rsdiff: number | null;
rsunits2007: number | null;
rsunitslatest: number | null;
rsunitslatestyear: number;
streetname: string;
totalviolations: number;
unitsres: number | null;
yearbuilt: number | null;
zip: string | null;
};
type SearchResults = {
addrs: AddressRecord[];
geosearch?: GeoSearchData;
};
export async function handleRequest(dfReq: DialogflowWebhookRequest): Promise<DialogflowWebhookResponse> {
const loc = dfReq.queryResult.parameters.location;
let addr = loc["street-address"] || loc['business-name'];
if (loc['subadmin-area']) {
addr += ', ' + loc['subadmin-area'];
}
const geoResult = await geoSearch(addr, {
fetch: fetch as any
});
let text = "Unfortunately, I was unable to find any information about the landlord at that address.";
if (geoResult.features.length > 0) {
const feature = geoResult.features[0];
const bbl = feature.properties.pad_bbl;
const addr = `${feature.properties.name}, ${feature.properties.borough}`;
const landlord = await getLandlordInfo(bbl);
if (landlord.addrs.length === 0) {
text = `Alas, I couldn't find any information about the landlord at ${addr}.`;
} else {
if (landlord.addrs.length === 1) {
text = `The landlord at ${addr} does not own any other buildings.`;
} else {
text = `The landlord at ${addr} owns ${landlord.addrs.length} buildings.`;
}
text += ` Learn more at https://whoownswhat.justfix.nyc/bbl/${bbl}.`;
}
}
const dfRes: DialogflowWebhookResponse = {
fulfillmentMessages: [{
text: {
text: [text],
}
}]
};
return dfRes;
}