# Webhooks

Webhooks merupakan fondasi untuk fitur-fitur yang berkaitan dengan MLOps. Webhooks memungkinkan Anda untuk mendengarkan perubahan baru pada repositori tertentu atau pada semua repositori yang dimiliki oleh kumpulan pengguna/organisasi tertentu (bukan hanya repositori Anda, tetapi repositori apa pun).

Anda dapat menggunakannya untuk mengonversi model secara otomatis, membangun bot komunitas, atau membangun CI/CD untuk model, dataset, Spaces, dan bucket Anda (dan banyak lagi!). Webhooks juga dapat [memicu Jobs](./jobs-webhooks) untuk mengotomatiskan tugas komputasi sebagai respons terhadap event repo.

Dokumentasi untuk Webhooks ada di bawah – atau Anda juga dapat menelusuri **panduan** kami yang menampilkan beberapa kasus penggunaan Webhooks yang mungkin:
- [Latih ulang model baru setiap kali dataset diperbarui (Python)](./webhooks-guide-auto-retrain)
- [Buat bot diskusi di Hub, menggunakan API LLM (NodeJS)](./webhooks-guide-discussion-bot)
- [Buat laporan kualitas metadata (Python)](./webhooks-guide-metadata-review)
- [Memproses file baru di bucket dengan Jobs (CLI)](./webhooks-guide-bucket-jobs)
- dan masih banyak lagi…

## Buat Webhook Anda

Anda dapat membuat Webhook baru dan mengedit yang sudah ada di [pengaturan](https://huggingface.co/settings/webhooks) Webhook Anda:

![Settings of an individual webhook](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/webhook-settings.png)

Webhooks dapat memantau pembaruan repositori, Pull Requests, diskusi, dan komentar baru. Bahkan, Anda dapat membuat Space untuk bereaksi terhadap Webhooks Anda!

## Payload Webhook

Setelah mendaftarkan Webhook, Anda akan diberi tahu tentang event baru melalui panggilan `HTTP POST` pada URL target yang ditentukan. Payload dikodekan dalam JSON.

Anda dapat melihat riwayat payload yang dikirim di tab aktivitas pada halaman pengaturan webhook, dan juga memungkinkan untuk memutar ulang webhook sebelumnya untuk memudahkan debugging:

![image.png](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/webhook-activity.png)

Sebagai contoh, berikut adalah payload lengkap saat Pull Request dibuka:

```json
{
  "event": {
    "action": "create",
    "scope": "discussion"
  },
  "repo": {
    "type": "model",
    "name": "openai-community/gpt2",
    "id": "621ffdc036468d709f17434d",
    "private": false,
    "url": {
      "web": "https://huggingface.co/openai-community/gpt2",
      "api": "https://huggingface.co/api/models/openai-community/gpt2"
    },
    "owner": {
      "id": "628b753283ef59b5be89e937"
    }
  },
  "discussion": {
    "id": "6399f58518721fdd27fc9ca9",
    "title": "Update co2 emissions",
    "url": {
      "web": "https://huggingface.co/openai-community/gpt2/discussions/19",
      "api": "https://huggingface.co/api/models/openai-community/gpt2/discussions/19"
    },
    "status": "open",
    "author": {
      "id": "61d2f90c3c2083e1c08af22d"
    },
    "num": 19,
    "isPullRequest": true,
    "changes": {
      "base": "refs/heads/main"
    }
  },
  "comment": {
    "id": "6399f58518721fdd27fc9caa",
    "author": {
      "id": "61d2f90c3c2083e1c08af22d"
    },
    "content": "Add co2 emissions information to the model card",
    "hidden": false,
    // Note: when `hidden` is `true`, `content` will be undefined
    "url": {
      "web": "https://huggingface.co/openai-community/gpt2/discussions/19#6399f58518721fdd27fc9caa"
    }
  },
  "webhook": {
    "id": "6390e855e30d9209411de93b",
    "version": 3
  }
}
```

### Peristiwa

Properti tingkat atas `event` selalu ditentukan dan digunakan untuk menentukan sifat dari peristiwa tersebut.

Ia memiliki dua sub-properti: `event.action` dan `event.scope`.

`event.scope` akan menjadi salah satu dari nilai berikut:

- `"repo"` - Peristiwa global pada repositori. Nilai yang mungkin untuk `action` terkait: `"create"`, `"delete"`, `"update"`, `"move"`.
- `"repo.content"` - Peristiwa pada konten repo, seperti commit atau tag baru. Ini juga dipicu oleh Pull Request baru karena referensi/commit yang baru dibuat. Untuk Buckets, ini dipicu oleh file yang ditambahkan atau dihapus, bukan oleh referensi Git. `action` yang terkait selalu `"update"`.
- `"repo.config"` - Peristiwa pada config: memperbarui rahasia Space, memperbarui pengaturan, memperbarui DOI, dinonaktifkan atau tidak, dan sebagainya. `action` yang terkait selalu `"update"`.
- `"discussion"` - Membuat diskusi atau Pull Request, memperbarui judul atau status, dan menggabungkan. Nilai yang mungkin untuk `action` terkait: `"create"`, `"delete"`, `"update"`.
- `"discussion.comment"` - Membuat, memperbarui, dan menyembunyikan komentar. Nilai yang mungkin untuk `action` terkait: `"create"`, `"update"`.

Cakupan lain dapat ditambahkan di masa depan. Untuk menangani peristiwa yang tidak dikenal, handler webhook Anda dapat menganggap setiap tindakan pada cakupan yang lebih sempit sebagai tindakan `"update"` pada cakupan yang lebih luas.

Sebagai contoh, jika scope `"repo.config.dois"` ditambahkan di masa depan, setiap event dengan scope tersebut dapat dipertimbangkan oleh webhook handler Anda sebagai aksi `"update"` pada scope `"repo.config"`.

### Repo

Pada versi webhooks saat ini, properti tingkat atas `repo` selalu ditentukan, karena event selalu dapat dikaitkan dengan sebuah repo. Sebagai contoh, pertimbangkan nilai berikut:

```json
"repo": {
	"type": "model",
	"name": "some-user/some-repo",
	"id": "6366c000a2abcdf2fd69a080",
	"private": false,
	"url": {
		"web": "https://huggingface.co/some-user/some-repo",
		"api": "https://huggingface.co/api/models/some-user/some-repo"
	},
	"headSha": "c379e821c9c95d613899e8c4343e4bfee2b0c600",
	"owner": {
		"id": "61d2000c3c2083e1c08af22d"
	}
}
```

`repo.headSha` adalah sha dari commit terbaru pada cabang `main` repo. Nilai ini hanya dikirim ketika `event.scope` diawali dengan `"repo"`, bukan pada event komunitas seperti diskusi dan komentar, dan juga tidak untuk bucket, yang tidak memiliki riwayat Git.

### Perubahan kode

Pada perubahan kode, properti tingkat atas `updatedRefs` ditentukan pada event repo. Ini adalah array dari referensi yang telah diperbarui. Berikut adalah contoh nilainya:

```json
"updatedRefs": [
  {
    "ref": "refs/heads/main",
    "oldSha": "ce9a4674fa833a68d5a73ec355f0ea95eedd60b7",
    "newSha": "575db8b7a51b6f85eb06eee540738584589f131c"
  },
  {
    "ref": "refs/tags/test",
    "oldSha": null,
    "newSha": "575db8b7a51b6f85eb06eee540738584589f131c"
  }
]
```

Referensi yang baru dibuat akan memiliki `oldSha` yang diatur ke `null`. Referensi yang dihapus akan memiliki `newSha` yang diatur ke `null`.

Anda dapat merespons commit baru pada pull request tertentu, tag baru, atau branch baru.

### Buckets

[Buckets](./storage-buckets) bukan repositori Git: tidak memiliki commit, branch, atau tag. Peristiwa siklus hidup (`create`, `delete`, `move`, dan pembaruan konfigurasi seperti visibilitas) menggunakan cakupan `"repo"` / `"repo.config"` yang sama seperti tipe repositori lainnya.

Perubahan file menggunakan `"repo.content"`, tetapi payload memiliki properti `updatedFiles` alih-alih `updatedRefs`. Menimpa file yang sudah ada dilaporkan sebagai `"add"`. Berikut adalah contoh payload setelah satu file ditambahkan dan satu lagi dihapus:

```json
{
  "event": {
    "action": "update",
    "scope": "repo.content"
  },
  "repo": {
    "type": "bucket",
    "name": "some-user/some-bucket",
    "id": "6366c000a2abcdf2fd69a080",
    "private": false,
    "url": {
      "web": "https://huggingface.co/buckets/some-user/some-bucket",
      "api": "https://huggingface.co/api/buckets/some-user/some-bucket"
    },
    "owner": {
      "id": "61d2000c3c2083e1c08af22d"
    }
  },
  "updatedFiles": [
    {
      "path": "data/train.txt",
      "action": "add",
      "xetHash": "55faef2f2f80cd1a087c35b729f228960739441d38073cd5aa4320751e137166",
      "size": 20
    },
    {
      "path": "data/old.txt",
      "action": "delete"
    },
    ...
  ],
  "updatedFilesTruncated": true,
  "webhook": {
    "id": "6390e855e30d9209411de93b",
    "version": 3
  }
}
```

Di atas 10.000 entri, daftar dipangkas dan `updatedFilesTruncated` diatur ke `true`. Dalam kasus tersebut, daftarkan bucket untuk mendapatkan gambaran lengkap.

Buckets tidak memiliki diskusi atau Pull Request, sehingga Anda tidak akan pernah menerima event `"discussion"` dan `"discussion.comment"` untuknya.

Jika Anda ingin klien melacak perubahan file pada bucket secara langsung, bukan melalui callback ke server Anda sendiri, bucket juga menyediakan [live follow stream](./storage-buckets#live-follow).

### Perubahan konfigurasi

Ketika properti tingkat atas `event.scope` adalah `"repo.config"`, properti `updatedConfig` ditentukan. Properti ini adalah objek yang berisi konfigurasi yang diperbarui. Berikut adalah contoh nilainya:

```json
"updatedConfig": {
  "private": false
}
```

Ketika kunci konfigurasi yang diperbarui tidak didukung oleh webhook, objeknya akan kosong:

```json
"updatedConfig": {}
```

Saat ini hanya `private` yang didukung. Jika Anda merasa akan diuntungkan dengan hadirnya lebih banyak kunci konfigurasi di sini, silakan beri tahu kami di website@huggingface.co.

### Diskusi dan Pull Request

Properti tingkat atas `discussion` ditentukan pada peristiwa komunitas (diskusi dan Pull Request). Properti `discussion.isPullRequest` adalah boolean yang menunjukkan apakah diskusi tersebut juga merupakan Pull Request (di Hub, PR adalah jenis diskusi khusus). Berikut adalah contoh nilainya:

```json
"discussion": {
	"id": "639885d811ae2bad2b7ba461",
	"title": "Hello!",
	"url": {
		"web": "https://huggingface.co/some-user/some-repo/discussions/3",
		"api": "https://huggingface.co/api/models/some-user/some-repo/discussions/3"
	},
	"status": "open",
	"author": {
		"id": "61d2000c3c2083e1c08af22d"
	},
	"isPullRequest": true,
	"changes": {
		"base": "refs/heads/main"
	}
	"num": 3
}
```

### Komentar

Properti tingkat atas `comment` ditentukan saat komentar dibuat (termasuk saat pembuatan diskusi) atau diperbarui. Berikut adalah contoh nilainya:

```json
"comment": {
	"id": "6398872887bfcfb93a306f18",
	"author": {
		"id": "61d2000c3c2083e1c08af22d"
	},
	"content": "This adds an env key",
	"hidden": false,
	"url": {
		"web": "https://huggingface.co/some-user/some-repo/discussions/4#6398872887bfcfb93a306f18"
	}
}
```

## Rahasia Webhook

Mengatur rahasia Webhook berguna untuk memastikan bahwa payload yang dikirim ke URL handler Webhook Anda benar-benar berasal dari Hugging Face.

Jika Anda mengatur secret untuk Webhook Anda, secret tersebut akan dikirim bersama sebagai header HTTP `X-Webhook-Secret` pada setiap permintaan. Hanya karakter ASCII yang didukung.

> [!TIP]
> Anda juga dapat menambahkan secret secara langsung di URL handler. Misalnya, dengan menyetelnya sebagai parameter query: https://example.com/webhook?secret=XXX.
>
> Hal ini dapat membantu jika mengakses header HTTP dari permintaan tersebut rumit untuk handler Webhook Anda.

## Pengiriman dan pengulangan

Payload webhook dikirim secara asinkron, segera setelah peristiwa terjadi di Hub. Urutan tidak dijamin: jika beberapa peristiwa terjadi berdekatan, mereka mungkin tiba di luar urutan.

Handler Anda harus mengakui pengiriman dengan kode status `2xx`. Kode status lainnya dianggap sebagai pengiriman yang gagal, sama seperti error koneksi: pengiriman akan diulang dengan backoff. Jika pemrosesan Anda lambat, balas dengan `2xx` segera dan lakukan pekerjaannya secara asinkron, agar pengiriman tidak dianggap gagal.

Setiap pengiriman memiliki header HTTP `Webhook-Id` yang unik. Percobaan ulang dari pengiriman yang gagal menggunakan ID yang sama, sehingga Anda dapat memperlakukannya sebagai kunci idempotensi dan memproses setiap event hanya sekali.

Ketika pengiriman ke Webhook terus gagal, Webhook tersebut akan ditangguhkan secara otomatis dan pemiliknya akan diberi tahu melalui email. Anda dapat melakukan pemecahan masalah dan mengaktifkannya kembali dari [pengaturan](https://huggingface.co/settings/webhooks) Webhooks Anda.

## Batas laju

Setiap Webhook dibatasi hingga 1.000 pemicuan per 24 jam. Anda dapat melihat penggunaan Anda di halaman pengaturan Webhook pada tab "Activity".

Jika Anda perlu meningkatkan jumlah pemicu untuk Webhook Anda, tingkatkan ke PRO, Team, atau Enterprise dan hubungi kami di website@huggingface.co.

## Mengembangkan Webhooks Anda

Jika Anda tidak memiliki endpoint/URL HTTPS, Anda dapat mencoba alat publik untuk pengujian webhook. Alat-alat ini berfungsi sebagai penangkap semua (menerima semua permintaan) yang dikirim ke mereka dan memberikan kode status 200 OK. [Beeceptor](https://beeceptor.com/) adalah salah satu alat yang dapat Anda gunakan untuk membuat endpoint HTTP sementara dan meninjau payload yang masuk. Alat lain semacam itu adalah [Webhook.site](https://webhook.site/).

Selain itu, Anda dapat merutekan payload Webhook asli ke kode yang berjalan secara lokal di mesin Anda selama pengembangan. Ini adalah cara yang sangat baik untuk menguji dan men-debug guna integrasi yang lebih cepat. Anda dapat melakukan ini dengan mengekspos port localhost Anda ke Internet. Agar dapat menempuh jalur ini, Anda dapat menggunakan [ngrok](https://ngrok.com/) atau [localtunnel](https://theboroer.github.io/localtunnel-www/).

## Debugging Webhook

Anda dapat dengan mudah menemukan event yang baru saja dibuat untuk webhook Anda. Buka tab aktivitas untuk webhook Anda. Di sana Anda akan melihat daftar event terbaru.

![image.png](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/webhook-payload.png)
 
Di sini Anda dapat meninjau kode status HTTP dan payload dari event yang dihasilkan. Selain itu, Anda dapat memutar ulang event ini dengan mengklik tombol `Replay`!

Catatan: Saat mengubah URL target atau secret dari Webhook, pemutaran ulang (replay) sebuah event akan mengirim payload ke URL yang telah diperbarui.

Catatan: Event yang diputar ulang dikirim dengan `Webhook-Id` yang sama dengan pengiriman aslinya.

## FAQ

##### Bisakah saya mendefinisikan webhook pada organisasi saya, bukan pada akun pengguna saya?

Tidak, ini belum didukung saat ini.

##### Bagaimana cara berlangganan semua event di HF (atau di seluruh tipe repo, seperti di semua model)?

Saat ini, fitur ini belum tersedia untuk pengguna akhir, tetapi kami dapat mengaktifkannya untuk Anda jika Anda mengirim email ke website@huggingface.co.

