Logo OmniDevvKANA Web
Kembali ke katalog plugin

fun

zodiak

Cek zodiak dari tanggal lahir plus sifat umumnya, untuk hiburan

Check your zodiac sign from your birth date plus general traits, for fun

plugins/fun/zodiak.js

Lokasi file di repo kana-md

2

Perintah termasuk alias

5.8 KB

Ukuran file sumber

4/11/2026

Update terakhir, commit 5d6f23b

Daftar perintah

Ketuk tombol salin untuk menyalin perintah, lalu tempel di chat WhatsApp bot KANA.

.zodiak.zodiac

Cara pakai

.zodiak <DD-MM atau DD-MM-YYYY>

Contoh

.zodiak 17-08

Kode sumber plugin

Unduh .js

Cara pasang: simpan file ini ke folder plugins/fun/ di bot KANA kamu, lalu restart bot. Pemilik source code lain bisa mengambil update plugin terbaru dari halaman ini kapan saja.

import { sendButtons } from '../../src/ui/buttons.js'

export const config = {
  name: 'zodiak',
  alias: ['zodiac'],
  category: 'fun',
  description: { id: 'Cek zodiak dari tanggal lahir plus sifat umumnya, untuk hiburan', en: 'Check your zodiac sign from your birth date plus general traits, for fun' },
  usage: '.zodiak <DD-MM atau DD-MM-YYYY>',
  example: '.zodiak 17-08',
  cooldown: 3,
}

// Tabel murni: [bulan mulai, hari mulai, kunci zodiak]. Urutan dari Capricorn
// (yang membungkus pergantian tahun) memakai batas awal tiap tanda.
export const ZODIAC_SIGNS = [
  { key: 'capricorn', name: 'Capricorn', start: [12, 22], trait: { id: 'Rajin, sabar, dan kalau sudah punya target susah digoyahkan.', en: 'Hardworking, patient, and hard to sway once a goal is set.' } },
  { key: 'aquarius', name: 'Aquarius', start: [1, 20], trait: { id: 'Pikirannya unik, suka ide baru, dan senang membantu banyak orang.', en: 'Unique thinker, loves new ideas, and enjoys helping many people.' } },
  { key: 'pisces', name: 'Pisces', start: [2, 19], trait: { id: 'Perasa, imajinatif, dan gampang iba melihat orang kesusahan.', en: 'Sensitive, imaginative, and quick to empathize with others.' } },
  { key: 'aries', name: 'Aries', start: [3, 21], trait: { id: 'Berani, enerjik, dan selalu ingin jadi yang pertama mencoba.', en: 'Brave, energetic, and always eager to try things first.' } },
  { key: 'taurus', name: 'Taurus', start: [4, 20], trait: { id: 'Tenang, setia, dan pencinta kenyamanan serta makanan enak.', en: 'Calm, loyal, and a lover of comfort and good food.' } },
  { key: 'gemini', name: 'Gemini', start: [5, 21], trait: { id: 'Ceria, cepat bosan, dan jago bikin obrolan jadi hidup.', en: 'Cheerful, easily bored, and great at livening up conversations.' } },
  { key: 'cancer', name: 'Cancer', start: [6, 21], trait: { id: 'Penyayang, peka, dan keluarga selalu jadi prioritas utama.', en: 'Caring, sensitive, and family always comes first.' } },
  { key: 'leo', name: 'Leo', start: [7, 23], trait: { id: 'Percaya diri, hangat, dan diam-diam suka jadi pusat perhatian.', en: 'Confident, warm, and secretly loves being the center of attention.' } },
  { key: 'virgo', name: 'Virgo', start: [8, 23], trait: { id: 'Teliti, rapi, dan puas kalau semua hal berjalan sesuai rencana.', en: 'Detail oriented, tidy, and satisfied when everything goes to plan.' } },
  { key: 'libra', name: 'Libra', start: [9, 23], trait: { id: 'Suka damai, adil, dan paling susah memilih di antara dua pilihan bagus.', en: 'Peace loving, fair, and struggles to pick between two good options.' } },
  { key: 'scorpio', name: 'Scorpio', start: [10, 23], trait: { id: 'Serius, penuh tekad, dan kalau sudah sayang, sayangnya total.', en: 'Serious, determined, and loves wholeheartedly once attached.' } },
  { key: 'sagittarius', name: 'Sagittarius', start: [11, 22], trait: { id: 'Petualang, jujur, dan selalu punya rencana jalan-jalan berikutnya.', en: 'Adventurous, honest, and always planning the next trip.' } },
]

const DAYS_IN_MONTH = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

// Fungsi murni untuk tes: dari (hari, bulan) kembalikan tanda zodiak.
export function zodiacFor(day, month) {
  const d = Number(day)
  const m = Number(month)
  if (!Number.isInteger(d) || !Number.isInteger(m) || m < 1 || m > 12 || d < 1 || d > DAYS_IN_MONTH[m - 1]) {
    return null
  }
  // Tanda dengan tanggal mulai terbesar yang sudah dilewati menang;
  // sebelum 20 Januari tidak ada yang cocok, jatuh ke Capricorn (pembungkus tahun).
  const value = m * 100 + d
  let result = ZODIAC_SIGNS[0]
  let best = -1
  for (const sign of ZODIAC_SIGNS) {
    const sv = sign.start[0] * 100 + sign.start[1]
    if (sv <= value && sv > best) {
      best = sv
      result = sign
    }
  }
  return result
}

export function parseBirthDate(text) {
  const m = String(text ?? '').trim().match(/^(\d{1,2})[-/](\d{1,2})(?:[-/](\d{2,4}))?$/)
  if (!m) return null
  const day = Number(m[1])
  const month = Number(m[2])
  if (!zodiacFor(day, month)) return null
  return { day, month, year: m[3] ? Number(m[3]) : null }
}

export const i18n = {
  id: {
    zodiak: {
      usage: 'Pakai: .zodiak <tanggal lahir>, contoh .zodiak 17-08 atau .zodiak 17-08-2008 yaa~',
      result: '✨ ZODIAK KAMU ✨\n\nTanggal: {date}\nZodiak: {sign}\nSifat umumnya: {trait}\n\nKira-kira cocok tidak sama kamu? Ehehe~ {mood}\n\n{disclaimer}',
      disclaimer: 'Catatan: ini cuma hiburan ringan dari KANA yaa, sifat orang tidak ditentukan tanggal lahir kok~',
      againBtn: '✨ Cek Zodiak Lagi',
      menuBtn: '🎲 Menu Fun',
      footer: 'Cek-cek hiburan KANA',
    },
  },
  en: {
    zodiak: {
      usage: 'Use: .zodiak <birth date>, for example .zodiak 17-08 or .zodiak 17-08-2008~',
      result: '✨ YOUR ZODIAC ✨\n\nDate: {date}\nSign: {sign}\nGeneral traits: {trait}\n\nDoes it sound like you? Ehehe~ {mood}\n\n{disclaimer}',
      disclaimer: 'Note: this is just light fun from KANA, a birth date does not define a person~',
      againBtn: '✨ Check Zodiac Again',
      menuBtn: '🎲 Fun Menu',
      footer: 'KANA fun checks',
    },
  },
}

export const test = { input: '.zodiak 17-08', expect: /zodiak/i }

export async function handler(ctx) {
  const parsed = parseBirthDate(ctx.text || ctx.args?.[0] || '')
  if (!parsed) return ctx.reply(ctx.t('zodiak.usage'))
  const sign = zodiacFor(parsed.day, parsed.month)
  const date = `${String(parsed.day).padStart(2, '0')}-${String(parsed.month).padStart(2, '0')}${parsed.year ? `-${parsed.year}` : ''}`
  const body = ctx.t('zodiak.result', {
    date,
    sign: sign.name,
    trait: sign.trait[ctx.lang] ?? sign.trait.id,
    mood: ctx.say('senang'),
    disclaimer: ctx.t('zodiak.disclaimer'),
  })
  return sendButtons(ctx.sock, ctx.chat, {
    title: 'KANA',
    body,
    footer: ctx.t('zodiak.footer'),
    replies: [
      { text: ctx.t('zodiak.againBtn'), id: '.zodiak' },
    ],
    textFallback: body,
  })
}