Kembali ke katalog plugin
group
afk
Tandai sedang AFK dengan alasan
Mark yourself AFK with a reason
plugins/group/afk.js
Lokasi file di repo kana-md
1
Perintah termasuk alias
3.5 KB
Ukuran file sumber
4/11/2026
Update terakhir, commit ab47575
Daftar perintah
Ketuk tombol salin untuk menyalin perintah, lalu tempel di chat WhatsApp bot KANA.
.afkCara pakai
.afk [alasan]
Contoh
.afk lagi makan
Kode sumber plugin
Cara pasang: simpan file ini ke folder plugins/group/ di bot KANA kamu, lalu restart bot. Pemilik source code lain bisa mengambil update plugin terbaru dari halaman ini kapan saja.
import { getGroupSettings, updateGroupSettings } from '../../src/services/group-service.js'
import { getProfile, updateProfile } from '../../src/services/user-service.js'
import { digitsOf } from '../../src/services/guard-rules.js'
export const config = {
name: 'afk',
alias: [],
category: 'group',
description: { id: 'Tandai sedang AFK dengan alasan', en: 'Mark yourself AFK with a reason' },
usage: '.afk [alasan]',
example: '.afk lagi makan',
cooldown: 3,
priority: 30,
}
export const i18n = {
id: {
afk: {
set: 'Siap~ kamu AFK sekarang: {reason}. KANA catat yaa, istirahat yang cukup~',
setNoReason: 'Siap~ kamu AFK sekarang. KANA catat yaa, istirahat yang cukup~',
back: 'Selamat datang kembali, @{digits}~ Kamu AFK selama {duration}. Udah nggak AFK lagi yaa~',
info: '@{digits} lagi AFK sejak {duration} yang lalu. Alasan: {reason}',
infoNoReason: '@{digits} lagi AFK sejak {duration} yang lalu.',
minutes: '{count} menit', hours: '{count} jam', justNow: 'baru aja',
defaultReason: 'lagi sibuk',
},
},
en: {
afk: {
set: 'Got it~ you are AFK now: {reason}. I noted it, please rest well~',
setNoReason: 'Got it~ you are AFK now. I noted it, please rest well~',
back: 'Welcome back, @{digits}~ You were AFK for {duration}. You are no longer AFK~',
info: '@{digits} is AFK since {duration} ago. Reason: {reason}',
infoNoReason: '@{digits} is AFK since {duration} ago.',
minutes: '{count} minutes', hours: '{count} hours', justNow: 'just now',
defaultReason: 'busy',
},
},
}
function formatDuration(ctx, since) {
const ms = Date.now() - Number(since || Date.now())
const minutes = Math.floor(ms / 60000)
if (minutes < 1) return ctx.t('afk.justNow')
if (minutes < 60) return ctx.t('afk.minutes', { count: minutes })
return ctx.t('afk.hours', { count: Math.floor(minutes / 60) })
}
export const test = { input: '.afk', expect: /AFK/i }
export async function handler(ctx) {
const reason = ctx.text.trim()
const entry = { reason, since: Date.now() }
if (ctx.isGroup) {
const settings = await getGroupSettings(ctx.storage, ctx.chat)
await updateGroupSettings(ctx.storage, ctx.chat, { afk: { ...(settings.afk ?? {}), [ctx.senderDigits]: entry } })
} else {
await updateProfile(ctx.storage, ctx.senderDigits, { afk: entry })
}
await ctx.reply(ctx.t(reason ? 'afk.set' : 'afk.setNoReason', { reason }))
}
export async function before(ctx) {
if (!ctx.isGroup) return
// Perintah .afk sendiri jangan memicu pesan kembali.
if (/^[.!/#]afk\b/i.test(ctx.text || '')) return
const settings = await getGroupSettings(ctx.storage, ctx.chat)
const afkMap = settings.afk ?? {}
const myDigits = digitsOf(ctx.sender)
if (afkMap[myDigits]) {
const entry = afkMap[myDigits]
const next = { ...afkMap }
delete next[myDigits]
await updateGroupSettings(ctx.storage, ctx.chat, { afk: next })
await ctx.sock.sendMessage(ctx.chat, {
text: ctx.t('afk.back', { digits: myDigits, duration: formatDuration(ctx, entry.since) }),
mentions: [ctx.sender],
})
}
// Info untuk member AFK yang di-mention, maks 1 balasan per pesan.
for (const jid of ctx.mentionedJids ?? []) {
const d = digitsOf(jid)
if (d === myDigits) continue
const entry = afkMap[d]
if (!entry) continue
const duration = formatDuration(ctx, entry.since)
await ctx.sock.sendMessage(ctx.chat, {
text: ctx.t(entry.reason ? 'afk.info' : 'afk.infoNoReason', { digits: d, duration, reason: entry.reason || '' }),
mentions: [jid],
})
break
}
}
