Kembali ke katalog plugin
download
ig
Unduh foto atau video Instagram dari link
Download an Instagram photo or video from a link
plugins/download/ig.js
Lokasi file di repo kana-md
3
Perintah termasuk alias
3.7 KB
Ukuran file sumber
4/11/2026
Update terakhir, commit 095e221
Daftar perintah
Ketuk tombol salin untuk menyalin perintah, lalu tempel di chat WhatsApp bot KANA.
.ig.igdl.instagramCara pakai
.ig <link instagram>
Contoh
.ig https://www.instagram.com/reel/xxxx/
Kode sumber plugin
Cara pasang: simpan file ini ke folder plugins/download/ di bot KANA kamu, lalu restart bot. Pemilik source code lain bisa mengambil update plugin terbaru dari halaman ini kapan saja.
import { instagramDownload } from '../../src/scrapers/instagram/instagram.js'
import { downloadBuffer } from '../../src/scrapers/runner.js'
import { sendVideo, sendImage, MAX_VIDEO_BYTES, MAX_IMAGE_BYTES } from '../../src/ui/media.js'
import { sendButtons } from '../../src/ui/buttons.js'
export const config = {
name: 'ig',
alias: ['igdl', 'instagram'],
category: 'download',
description: { id: 'Unduh foto atau video Instagram dari link', en: 'Download an Instagram photo or video from a link' },
usage: '.ig <link instagram>',
example: '.ig https://www.instagram.com/reel/xxxx/',
cooldown: 10,
limit: 5,
}
export const i18n = {
id: {
ig: {
needUrl: 'Kirim link Instagram-nya dulu yaa, contoh: .ig https://www.instagram.com/reel/...~',
working: 'Sebentar, KANA ambilin medianya dulu... {mood}',
failed: 'Mouu, gagal ambil medianya: {message}. Pastikan linknya dari akun publik ya~',
tooBig: 'Aduh, ada media yang kegedean buat dikirim lewat WhatsApp, jadi KANA lewati ya~',
caption: '{title}',
btnRetry: 'Unduh ulang',
btnMenu: 'Menu unduhan',
btnAio: 'Coba .aio',
followUp: 'Lanjutan: .ig {url} • .menu download',
},
},
en: {
ig: {
needUrl: 'Send the Instagram link first, example: .ig https://www.instagram.com/reel/...~',
working: 'One sec, KANA is fetching the media... {mood}',
failed: 'Mouu, failed to fetch the media: {message}. Make sure the link is from a public account~',
tooBig: 'Oops, some media was too big to send over WhatsApp, so KANA skipped it~',
caption: '{title}',
btnRetry: 'Download again',
btnMenu: 'Download menu',
btnAio: 'Try .aio',
followUp: 'Next: .ig {url} • .menu download',
},
},
}
// Tombol susulan sesudah media terkirim: unduh ulang URL yang sama + menu
// unduhan. URL tidak tersedia: menu unduhan + .aio saja.
export function buildIgButtons(url, t) {
return url
? [
{ text: t('ig.btnRetry'), id: `.ig ${url}` },
{ text: t('ig.btnMenu'), id: '.menu download' },
]
: [
{ text: t('ig.btnMenu'), id: '.menu download' },
{ text: t('ig.btnAio'), id: '.aio' },
]
}
export const test = { input: '.ig https://www.instagram.com/reel/DMXCETGSC5i/', expect: /Instagram|reel/i }
export async function handler(ctx) {
const url = ctx.args[0]
if (!url) return ctx.reply(ctx.t('ig.needUrl'))
await ctx.reply(ctx.t('ig.working', { mood: ctx.say('mikir') }))
const result = await instagramDownload(url)
if (!result.status) return ctx.reply(ctx.t('ig.failed', { message: result.message }))
const items = result.result.downloads.slice(0, 3)
let skipped = false
for (const [index, item] of items.entries()) {
try {
if (item.type === 'photo') {
const media = await downloadBuffer(item.url, { maxBytes: MAX_IMAGE_BYTES })
await sendImage(ctx, media.buffer, { caption: index === 0 ? ctx.t('ig.caption', { title: result.result.title }) : undefined })
} else {
const media = await downloadBuffer(item.url, { maxBytes: MAX_VIDEO_BYTES })
await sendVideo(ctx, media.buffer, { caption: index === 0 ? ctx.t('ig.caption', { title: result.result.title }) : undefined })
}
} catch (err) {
if (err.code === 'TOO_BIG') skipped = true
else return ctx.reply(ctx.t('ig.failed', { message: err.message }))
}
}
if (skipped) await ctx.reply(ctx.t('ig.tooBig'))
const body = [ctx.t('ig.caption', { title: result.result.title }), ctx.t('ig.followUp', { url })].join('\n')
return sendButtons(ctx.sock, ctx.chat, {
title: 'KANA',
body,
footer: ctx.t('menu.footer'),
replies: buildIgButtons(url, ctx.t),
textFallback: body,
})
}
