Mengeluarkan Open Badges daripada WordPress (Tanpa Plugin Berat)

Keluarkan Open Badges daripada mana-mana plugin kursus/LMS WordPress (LearnDash, LifterLMS, Tutor) dengan memanggil API Badges Ninja apabila selesai — tanpa perlu memasang plugin lencana yang berasingan.

Nacho Coll Oleh Dikemas kini 11 minit bacaan
Keluarkan Open Badges daripada mana-mana plugin kursus/LMS WordPress (LearnDash, LifterLMS, Tutor) dengan memanggil API Badges Ninja apabila selesai — tanpa perlu memasang plugin lencana yang berasingan.

Jika anda menjalankan kursus di WordPress, anda pasti sudah biasa dengan rutin ini: seseorang menamatkan satu modul dalam LearnDash, LifterLMS, atau Tutor LMS, LMS menandakannya “selesai,” dan kemudian… tiada apa-apa yang boleh disahkan berlaku. Mungkin anda menghantar PDF melalui e-mel. Mungkin anda memasang plugin lencana WordPress khusus yang menambah jadual pangkalan data sendiri, pustaka imej sendiri, dan takrifan “lencana” sendiri — satu yang tiada sesiapa di luar laman anda boleh sahkan.

Ada jalan yang lebih mudah. Plugin kursus WordPress sudah pun mencetuskan action hook sebaik sahaja seseorang menamatkan kursus. Anda boleh menangkap hook itu dan membuat satu panggilan HTTP ke API Badges Ninja. Tiada plugin tambahan, tiada hosting tambahan, tiada format lencana proprietari — hanya kelayakan Open Badge v2.0 yang mematuhi piawaian yang boleh disahkan oleh penerima anda di mana-mana sahaja, ditambah ke LinkedIn, dan dimuat turun sebagai PDF.

Artikel ini menerangkan corak ini sekali, kemudian menunjukkan hook khusus untuk LearnDash, LifterLMS, dan Tutor LMS.

Kenapa tidak gunakan sahaja plugin lencana WordPress?

Plugin lencana WordPress khusus menyelesaikan masalah yang lebih sempit daripada yang kelihatan. Ia bagus dalam memaparkan imej pada halaman “pencapaian saya” di dalam laman anda. Ia biasanya jauh lebih lemah dalam perkara yang benar-benar penting untuk sesuatu kelayakan:

  • Kebolehalihan. Lencana yang hanya wujud sebagai shortcode di laman WordPress anda bukanlah kelayakan — ia hanya hiasan. Sebaik sahaja penerima bertukar kerja, menukar peti mel mereka, atau laman anda tidak lagi berfungsi, “bukti” itu turut hilang bersamanya.
  • Pengesahan. Sesiapa sahaja patut boleh menyemak bahawa sesuatu kelayakan itu benar tanpa perlu log masuk ke panel admin WordPress anda. Open Badge v2.0 memberi anda URL pengesahan awam dan JSON-LD yang boleh dibaca mesin, mengikut reka bentuknya.
  • Permukaan penyelenggaraan. Setiap plugin WordPress adalah satu lagi perkara yang perlu ditampal, satu lagi jadual pangkalan data yang perlu disandarkan, satu lagi titik kegagalan semasa kemas kini teras.

Memanggil API luaran apabila kursus selesai mengelakkan ketiga-tiga perkara ini. WordPress kekal bertanggungjawab untuk apa yang ia lakukan dengan baik — penyampaian kandungan dan penjejakan kemajuan — dan kelayakan itu sendiri hidup dalam sistem yang dibina khusus untuk mengeluarkan, mengesahkan, dan berkongsinya.

Corak: satu hook, satu panggilan HTTP

Setiap plugin LMS WordPress utama mencetuskan tindakan apabila pengguna menamatkan kursus. Integrasi ini sentiasa mengikut tiga langkah yang sama:

  1. Hook ke tindakan penyempurnaan untuk LMS khusus anda.
  2. Cari (atau cipta) identiti penerima — biasanya hanya e-mel akaun WordPress mereka dan nama paparan.
  3. Panggil POST /awards pada API Badges Ninja menggunakan wp_remote_post(), dengan menghantar badge ID dan butiran penerima.

Anda memerlukan API key terlebih dahulu. Janakan satu daripada dashboard anda di bawah API Keys — lihat panduan API keys untuk penerangan penuh. Kunci hanya dipaparkan sekali sahaja semasa dicipta, jadi simpan ia dalam wp-config.php sebagai pemalar dan bukannya dalam pangkalan data:

define( 'BADGES_NINJA_API_KEY', 'bws_your_32_hex_key_here' );
define( 'BADGES_NINJA_BADGE_ID', 'your-badge-id' );

Newly created key revealed once

Simpan kunci ini di sisi pelayan. Segala-galanya dalam panduan ini berjalan dalam PHP di pelayan WordPress anda — wp_remote_post() ialah panggilan sisi pelayan, dan wp-config.php tidak pernah dihantar ke pelayar. Itulah tepatnya yang anda mahu: kunci itu bergerak dari pelayan-ke-pelayan melalui HTTPS, dan tiada pelawat laman boleh membacanya. Jangan sekali-kali pindahkan panggilan ini ke JavaScript sisi klien — fetch() daripada pelayar dengan kunci disertakan terus akan mendedahkannya kepada sesiapa sahaja melalui alat pembangun pelayar mereka. Dua tabiat yang berbaloi dikekalkan: pastikan hos anda menyajikan wp-config.php sebagai PHP yang dijalankan (bukan sebagai teks biasa, dan jangan tinggalkan salinan wp-config.php.bak dalam webroot), serta cipta API key khusus untuk integrasi ini supaya anda boleh membatalkannya secara berasingan jika ia pernah terjejas — tanpa merosakkan alat lain anda.

Fungsi pembantu yang dikongsi memastikan setiap hook LMS kekal ringkas:

function badges_ninja_issue_award( $recipient_email, $recipient_name, $badge_id ) {
	$response = wp_remote_post( 'https://api.badges.ninja/awards', array(
		'headers' => array(
			'X-Api-Key'    => BADGES_NINJA_API_KEY,
			'Content-Type' => 'application/json',
		),
		'body' => wp_json_encode( array(
			'badgeId'   => $badge_id,
			'recipient' => array(
				'name'  => $recipient_name,  // must be at least 5 characters
				'email' => $recipient_email,
			),
			'issuedOn'  => round( microtime( true ) * 1000 ), // epoch milliseconds
		) ),
		'timeout' => 15,
	) );
	if ( is_wp_error( $response ) ) {
		error_log( 'Badges Ninja award failed: ' . $response->get_error_message() );
		return false;
	}
	$code = wp_remote_retrieve_response_code( $response );
	if ( $code >= 400 ) {
		error_log( 'Badges Ninja award failed with HTTP ' . $code . ': ' . wp_remote_retrieve_body( $response ) );
		return false;
	}
	return json_decode( wp_remote_retrieve_body( $response ), true );
}

E-mel penerima di-hash menggunakan SHA-256 di sisi pelayan sebaik sahaja ia sampai ke Badges Ninja, dan payload pulangan termasuk URL pengesahan anugerah — berguna jika anda mahu memaparkan pautan “lihat kelayakan anda” terus di dalam WordPress selepas panggilan berjaya.

LearnDash

LearnDash mencetuskan learndash_course_completed dengan satu argumen array yang mengandungi user dan course:

add_action( 'learndash_course_completed', function( $data ) {
	$user   = $data['user'];
	$course = $data['course'];
	// Map LearnDash course ID → your Badges Ninja badge ID.
	// A simple approach: store the badge ID in a course custom field.
	$badge_id = get_post_meta( $course->ID, 'badges_ninja_badge_id', true );
	if ( ! $badge_id ) {
		return; // no badge configured for this course
	}
	badges_ninja_issue_award( $user->user_email, $user->display_name, $badge_id );
} );

Menyimpan badge ID sebagai meta kursus (dan bukannya satu pemalar global BADGES_NINJA_BADGE_ID) adalah pilihan yang tepat sebaik sahaja anda mempunyai lebih daripada satu kursus — setiap kursus dipetakan kepada reka bentuk lencananya sendiri.

LifterLMS

LifterLMS mencetuskan lifterlms_course_completed dengan $user_id dan $course_id:

add_action( 'lifterlms_course_completed', function( $user_id, $course_id ) {
	$user     = get_userdata( $user_id );
	$badge_id = get_post_meta( $course_id, 'badges_ninja_badge_id', true );
	if ( ! $user || ! $badge_id ) {
		return;
	}
	badges_ninja_issue_award( $user->user_email, $user->display_name, $badge_id );
}, 10, 2 );

Tutor LMS

Tutor LMS mencetuskan tutor_course_complete_after dengan course ID, dan anda perlu mendapatkan pengguna semasa daripada sesi:

add_action( 'tutor_course_complete_after', function( $course_id ) {
	$user_id  = get_current_user_id();
	$user     = get_userdata( $user_id );
	$badge_id = get_post_meta( $course_id, 'badges_ninja_badge_id', true );
	if ( ! $user || ! $badge_id ) {
		return;
	}
	badges_ninja_issue_award( $user->user_email, $user->display_name, $badge_id );
} );

Jika persediaan Tutor LMS anda mencetuskan penyempurnaan daripada proses latar belakang (contohnya melalui gred automatik kuiz), tukar get_current_user_id() dengan user ID yang disediakan oleh hook khusus anda — semak payload dengan error_log( print_r( func_get_args(), true ) ) sekali semasa persediaan untuk mengesahkan argumen tersebut.

Mereka bentuk lencana sebelum menyambungkan hook

Sebelum mana-mana daripada ini dicetuskan, anda memerlukan lencana untuk dianugerahkan. Pereka bentuk visual merangkumi ini tanpa perlu ada pereka bentuk dalam kakitangan — lebih 80 templat bentuk, warna tersuai, pustaka ikon, dan muat naik logo, semuanya snap-to-grid. Jika anda baru dengan pereka bentuk ini, Mereka Bentuk Sijil Digital Boleh Disahkan Pertama Anda menerangkan cara memilih templat dan menghasilkan sesuatu yang penerima benar-benar mahu kongsikan.

Sebaik sahaja lencana wujud, ambil ID-nya daripada dashboard (atau melalui GET /badges) dan masukkan ke dalam custom field kursus anda.

Apa yang penerima sebenarnya perolehi

Inilah bahagian yang plugin lencana WordPress buatan sendiri tidak dapat tiru. Apabila POST /awards berjaya, penerima memperoleh:

  • URL pengesahan unik yang sesiapa sahaja boleh buka — tanpa perlu log masuk WordPress — menunjukkan kelayakan itu adalah benar, siapa yang mengeluarkannya, dan bila.
  • Kod QR dan sijil PDF A4, yang dijana secara automatik.
  • Butang Tambah ke Profil LinkedIn, jika pengeluar anda telah menetapkan ID organisasi LinkedIn — lihat Tambah Butang “Add to Profile” LinkedIn untuk persediaan satu kali.
  • Akses kepada portal penerima mereka sendiri di badges.ninja/me, melalui log masuk magic-link — tiada kata laluan untuk dilupakan, tiada akaun berasingan untuk diuruskan di laman WordPress anda.
  • Open Badge v2.0 JSON-LD yang mematuhi piawaian, jadi mana-mana pengesah yang mengenali OB (bukan sahaja Badges Ninja) boleh mengesahkannya.

Tiada satu pun daripada itu adalah tugas WordPress untuk dibina, dan tiada satu pun daripadanya patut hidup hanya di dalam pangkalan data WordPress anda.

Mengendalikan kegagalan dengan baik

Hook penyempurnaan kursus dicetuskan semasa permintaan halaman langsung, dan panggilan API yang perlahan atau gagal tidak sepatutnya menyekat skrin “tahniah” pelajar. Dua penyesuaian praktikal sebaik sahaja anda melangkaui bukti konsep:

Jangan biarkan anugerah yang gagal menyekat UI. Fungsi pembantu di atas sudah pun mencatat log dan memulangkan false dan bukannya membuang ralat — LearnDash, LifterLMS, dan Tutor semuanya meneruskan aliran penyempurnaan normal mereka tanpa mengira apa yang badges_ninja_issue_award() pulangkan.

Masukkan dalam baris gilir dan bukannya memanggil secara sebaris, pada skala besar. Jika anda menjalankan kohort besar melalui satu kursus serentak (tarikh mula kohort, unlock ulang tayang webinar), cetuskan acara berjadual WP-Cron daripada hook itu dan bukannya memanggil API secara segerak:

add_action( 'learndash_course_completed', function( $data ) {
	wp_schedule_single_event( time() + 30, 'badges_ninja_deferred_award', array(
		$data['user']->user_email,
		$data['user']->display_name,
		get_post_meta( $data['course']->ID, 'badges_ninja_badge_id', true ),
	) );
} );
add_action( 'badges_ninja_deferred_award', 'badges_ninja_issue_award', 10, 3 );

Ini menyebarkan beban dan mengelakkan satu permintaan yang perlahan daripada menjadi masalah pelajar. Untuk kelompok yang benar-benar besar (seluruh kohort lampau, dipindahkan sekali gus), langkau terus laluan hook WordPress dan gunakan anugerah pukal melalui CSV — muat naik sekali, dan platform akan memaparkan pengeluaran secara berhalaman di sisi pelayan dengan jeda/sambung semula terbina dalam.

Nota mengenai idempotency

Jika LMS anda pernah mencetuskan hook penyempurnaannya lebih daripada sekali untuk pengguna yang sama (kes sempadan biasa LearnDash dengan cubaan semula kuiz, atau penyegerakan semula Tutor LMS), anda tidak mahu menganugerahkan lencana yang sama dua kali. Pelindung paling mudah ialah bendera user-meta WordPress yang anda tetapkan sejurus selepas panggilan berjaya:

if ( get_user_meta( $user_id, 'badges_ninja_awarded_' . $course_id, true ) ) {
	return; // already issued
}
$result = badges_ninja_issue_award( $user->user_email, $user->display_name, $badge_id );
if ( $result ) {
	update_user_meta( $user_id, 'badges_ninja_awarded_' . $course_id, true );
}

Jika anda mengeluarkan pada volum sebenar dan mahu ini dikendalikan secara berpusat dan bukannya bagi setiap laman, lihat pengendalian acara berasaskan webhook atau panduan permulaan pantas API yang lengkap untuk bentuk permintaan/respons merentasi setiap endpoint.

Apabila corak ini melangkaui satu kursus

Contoh di atas mengandaikan satu lencana bagi setiap kursus. Sebaik sahaja anda menjalankan kelayakan bertindan — lencana laluan yang membuka kunci selepas beberapa lencana kursus, atau pencapaian puncak yang bergantung pada pelbagai prasyarat — pindahkan pemetaan “lencana mana, untuk penyempurnaan mana” keluar daripada post meta dan ke dalam jadual carian kecil, atau jalankan ia daripada automasi berasaskan hamparan (Airtable atau Google Sheets) yang mencetuskan panggilan POST /awards yang sama. Panggilan API itu sendiri tidak berubah; hanya apa yang menentukan bila hendak membuatnya yang berubah.

Menyelesaikan masalah integrasi

Beberapa isu menyumbang kepada kebanyakan geseran yang dihadapi orang ramai apabila menyambungkan ini buat kali pertama:

Hook langsung tidak tercetus. Sahkan anda menghubungkan tindakan yang betul untuk versi sebenar plugin anda — LearnDash khususnya telah menukar nama hook penyempurnaan merentasi keluaran utama (pemasangan lama kadangkala masih bergantung pada learndash_course_completed yang dicetuskan daripada laluan kod berbeza berbanding yang lebih baharu). Tambah error_log() sementara pada bahagian atas callback anda dan perhatikan wp-content/debug.log semasa anda menamatkan kursus ujian sebagai pengguna sekali guna.

wp_remote_post() tamat masa. Persekitaran hosting dikongsi kadangkala menyekat HTTPS keluar ke hos yang tidak dikenali, atau mengehadkan had masa permintaan di bawah 15 saat yang ditetapkan di atas. Jika panggilan sentiasa tamat masa, semak dengan hos anda sama ada sambungan keluar ke api.badges.ninja dibenarkan, dan sahkan sambungan PHP curl anda mempunyai sijil CA terkini — kumpulan sijil yang lapuk adalah kegagalan senyap yang biasa pada tindanan hosting dikongsi yang lebih lama.

400 Bad Request. Payload kehilangan medan yang diperlukan atau mempunyai bentuk yang salah. POST /awards menjangkakan badgeId, objek recipient bersarang dengan name dan email, serta cap masa issuedOn — fungsi pembantu di atas menghantar tepat itu. Kesilapan paling biasa ialah nama penerima: ia mesti sekurang-kurangnya 5 aksara, jadi nama paparan WordPress seperti “Jo” akan ditolak. Kembali kepada nama penuh akaun (atau bahagian sebelum @ e-mel) apabila nama paparan terlalu pendek.

401 Unauthorized. Pemalar API key tidak dimuatkan, atau ia dijana semula selepas pemalar ditetapkan. Kunci hanya dipaparkan sekali semasa dicipta dan tidak boleh diperoleh semula — jika anda telah kehilangan jejak kunci mana yang aktif, padam yang lama dan keluarkan satu yang baharu dan bukannya meneka.

Lencana dikeluarkan, tetapi kepada reka bentuk lencana yang salah. Ini hampir selalu nilai post-meta badges_ninja_badge_id yang lapuk yang tertinggal daripada ujian. Kerana pemetaan itu hidup pada post kursus, mudah untuk terlupa anda telah menukarnya selepas menduplikasi kursus untuk kohort baharu — berbaloi untuk semakan pantas setiap kali anda mengklon kursus.

Anugerah berganda bagi orang yang sama. Telah dibincangkan di atas dengan pelindung user-meta, tetapi berbaloi untuk dinyatakan semula: hook penyempurnaan LMS tidak dijamin tercetus tepat sekali. Layan “sudah dianugerahkan” sebagai kes biasa untuk disemak, bukan kes sempadan untuk diabaikan.

Soalan lazim

Adakah ini berfungsi dengan pakej kursus WooCommerce? Ya — jika pembelian pakej patut mencetuskan lencana bebas daripada penyempurnaan kursus (contohnya lencana “ahli bertauliah” bagi sesiapa yang membeli pakej tertentu), hook woocommerce_order_status_completed dan bukannya tindakan penyempurnaan LMS, dan cari badge ID daripada meta produk dan bukannya kursus.

Bolehkah penerima mendapatkan lencana tanpa akaun WordPress? Ya, dan itulah intinya. Anugerah itu dikaitkan dengan alamat e-mel mereka dalam Badges Ninja, bukan dengan rekod pengguna WordPress. Jika laman anda membenarkan pembayaran tetamu atau penyempurnaan kuiz tanpa nama, pastikan sahaja anda menangkap alamat e-mel sebenar untuk dihantar ke dalam badges_ninja_issue_award().

Bagaimana jika saya mahu menyemak anugerah sebelum ia dikeluarkan? Langkau pencetusan panggilan terus daripada hook penyempurnaan. Sebaliknya, tulis anugerah yang tertangguh (pengguna, kursus, cap masa) ke dalam jadual tersuai atau jenis pos, dan keluarkannya daripada tugas berjadual atau butang admin “Luluskan & Anugerah” yang memanggil fungsi pembantu yang sama mengikut permintaan.

Perlukah saya lencana berasingan bagi setiap kursus, atau bolehkah satu lencana merangkumi beberapa? Kedua-duanya berfungsi. Sesetengah pengeluar mencipta satu lencana bagi setiap kursus untuk kehalusan; yang lain mencipta satu lencana “penyempurnaan program” dan hanya menganugerahkannya sebaik sahaja setiap kursus yang diperlukan selesai, menyemak penyempurnaan prasyarat di dalam hook sebelum memanggil API.


Bersedia untuk mengeluarkan kelayakan boleh disahkan pertama anda? Mula percuma di badges.ninja — pereka bentuk visual, halaman pengesahan awam, sijil PDF, output Open Badge v2.0. Tiada kad kredit diperlukan.

Nacho Coll

Tentang penulis

Founder & Engineer at Badges Ninja

Nacho founded Badges Ninja to make issuing verifiable digital credentials as simple as a single API call — Open Badge v2.0 badges and certificates, minted, hosted, and verifiable without standing up your own issuer infrastructure. Writes about the Open Badges spec, credential verification, and running a credentialing platform serverless on AWS, from the operator side of the wire.

Kembali ke Blog

Artikel Berkaitan