Back to Home
Gistify Snippet
kyiov
Sep 20·1 file(s)
Public

wilayah.js

Imported from GitHub Gist: wilayah.js

#github-gist#javascript#gist:b7b12ab50f5b2b7489c46d03459c4e1f
1
Raw
wilayah.jsjavascript
172 lines
1/**
2 * Wilayah Indonesia + Jadwal Sholat + Cuaca Scraper & API Client
3 * Author / Base: Nimzz
4 * Sources:
5 * - Wilayah : https://wilayah.cahyadsn.com
6 * - Sholat : https://api.aladhan.com
7 * - Cuaca : https://api.open-meteo.com
8 */
9
10import fetch from 'node-fetch'
11
12const BASE_WILAYAH = 'https://wilayah.cahyadsn.com/api/'
13const BASE_SHOLAT = 'https://api.aladhan.com/v1/timings'
14const BASE_CUACA = 'https://api.open-meteo.com/v1/forecast'
15
16const USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36'
17
18async function fetchJson(url) {
19 const res = await fetch(url, {
20 headers: {
21 'User-Agent': USER_AGENT,
22 'Accept': 'application/json'
23 }
24 })
25 if (!res.ok) throw new Error(`HTTP ${res.status} untuk ${url}`)
26 return res.json()
27}
28
29const WEATHER_CODES = {
30 0: 'Cerah (Clear sky)',
31 1: 'Utamanya Cerah (Mainly clear)',
32 2: 'Sebagian Berawan (Partly cloudy)',
33 3: 'Mendung (Overcast)',
34 45: 'Berkabut (Fog)',
35 48: 'Kabut Tebal (Depositing rime fog)',
36 51: 'Gerimis Ringan (Light drizzle)',
37 53: 'Gerimis Sedang (Moderate drizzle)',
38 55: 'Gerimis Lebat (Dense drizzle)',
39 61: 'Hujan Ringan (Slight rain)',
40 63: 'Hujan Sedang (Moderate rain)',
41 65: 'Hujan Deras (Heavy rain)',
42 71: 'Salju Ringan',
43 73: 'Salju Sedang',
44 75: 'Salju Lebat',
45 80: 'Hujan Singkat Ringan',
46 81: 'Hujan Singkat Sedang',
47 82: 'Hujan Badai Lokal',
48 95: 'Badai Petir (Thunderstorm)',
49 96: 'Badai Petir Berbutir Es Ringan',
50 99: 'Badai Petir Berbutir Es Lebat'
51}
52
53/**
54 * Mengambil daftar Provinsi di Indonesia
55 */
56export async function getProvinsi() {
57 const data = await fetchJson(`${BASE_WILAYAH}?kode=`)
58 return data.data || []
59}
60
61/**
62 * Mengambil daftar Kabupaten/Kota berdasarkan kode provinsi
63 * @param {string} kodeProvinsi Kode provinsi (contoh: '31', '32', '33')
64 */
65export async function getKabupaten(kodeProvinsi) {
66 if (!kodeProvinsi) throw new Error('Kode provinsi harus diisi.')
67 const data = await fetchJson(`${BASE_WILAYAH}?kode=${kodeProvinsi}&level=2`)
68 return data.data || []
69}
70
71/**
72 * Mengambil daftar Kecamatan berdasarkan kode kabupaten
73 * @param {string} kodeKabupaten Kode kabupaten (contoh: '33.72')
74 */
75export async function getKecamatan(kodeKabupaten) {
76 if (!kodeKabupaten) throw new Error('Kode kabupaten harus diisi.')
77 const data = await fetchJson(`${BASE_WILAYAH}?kode=${kodeKabupaten}&level=3`)
78 return data.data || []
79}
80
81/**
82 * Mengambil daftar Kelurahan/Desa berdasarkan kode kecamatan
83 * @param {string} kodeKecamatan Kode kecamatan (contoh: '33.72.03')
84 */
85export async function getKelurahan(kodeKecamatan) {
86 if (!kodeKecamatan) throw new Error('Kode kecamatan harus diisi.')
87 const data = await fetchJson(`${BASE_WILAYAH}?kode=${kodeKecamatan}&level=4`)
88 return data.data || []
89}
90
91/**
92 * Mengambil detail lengkap koordinat lat, lng, kodepos, dan polygon suatu wilayah
93 * @param {string} kodeWilayah Kode wilayah lengkap (contoh: '33.72.03.1009' atau '31')
94 */
95export async function getDetailWilayah(kodeWilayah) {
96 if (!kodeWilayah) throw new Error('Kode wilayah harus diisi.')
97 const data = await fetchJson(`${BASE_WILAYAH}?kode=${kodeWilayah}&detail=1`)
98 return data.data || data
99}
100
101/**
102 * Mengambil jadwal sholat realtime berdasarkan koordinat Latitude & Longitude
103 * @param {number|string} lat Latitude
104 * @param {number|string} lon Longitude
105 */
106export async function getJadwalSholat(lat, lon) {
107 if (!lat || !lon) throw new Error('Latitude dan Longitude harus diisi.')
108 const date = new Date()
109 const dd = String(date.getDate()).padStart(2, '0')
110 const mm = String(date.getMonth() + 1).padStart(2, '0')
111 const yyyy = date.getFullYear()
112 const data = await fetchJson(`${BASE_SHOLAT}/${dd}-${mm}-${yyyy}?latitude=${lat}&longitude=${lon}&method=20`)
113 return data.data || data
114}
115
116/**
117 * Mengambil cuaca realtime (suhu, kelembaban, angin, deskripsi cuaca) dari koordinat
118 * @param {number|string} lat Latitude
119 * @param {number|string} lon Longitude
120 */
121export async function getCuacaRealtime(lat, lon) {
122 if (!lat || !lon) throw new Error('Latitude dan Longitude harus diisi.')
123 const data = await fetchJson(`${BASE_CUACA}?latitude=${lat}&longitude=${lon}&current=temperature_2m,relative_humidity_2m,wind_speed_10m,weather_code`)
124 const current = data.current || {}
125 const weatherDesc = WEATHER_CODES[current.weather_code] || 'Tidak diketahui'
126 return {
127 ...current,
128 weather_desc: weatherDesc
129 }
130}
131
132/**
133 * Mengambil informasi lengkap (Wilayah + Jadwal Sholat + Cuaca) sekaligus dari kode wilayah
134 * @param {string} kodeWilayah Kode wilayah (contoh: '31.71', '33.72.03.1009')
135 */
136export async function getWilayahFullInfo(kodeWilayah) {
137 const detail = await getDetailWilayah(kodeWilayah)
138 const item = Array.isArray(detail) ? detail[0] : detail
139 if (!item) throw new Error(`Wilayah dengan kode ${kodeWilayah} tidak ditemukan.`)
140
141 let sholat = null
142 let cuaca = null
143
144 if (item.lat && item.lng) {
145 try {
146 [sholat, cuaca] = await Promise.all([
147 getJadwalSholat(item.lat, item.lng),
148 getCuacaRealtime(item.lat, item.lng)
149 ])
150 } catch (err) {
151 console.warn('[WilayahFullInfo Warning]:', err.message)
152 }
153 }
154
155 return {
156 wilayah: item,
157 sholat,
158 cuaca
159 }
160}
161
162export default {
163 getProvinsi,
164 getKabupaten,
165 getKecamatan,
166 getKelurahan,
167 getDetailWilayah,
168 getJadwalSholat,
169 getCuacaRealtime,
170 getWilayahFullInfo
171}
172
Discussion & Comments0

No comments yet — be the first to leave feedback or start a code discussion.

Sign in with your GitHub account to write comments and join the discussion.