Custom CMS — Laravel¶
Contoh receiver webhook + upsert artikel.
Route¶
// routes/api.php
Route::post('/hooks/nulis', [NulisWebhookController::class, 'handle']);
Controller¶
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Http\Request;
class NulisWebhookController extends Controller
{
public function handle(Request $request)
{
$secret = config('services.nulis.webhook_secret');
$sig = $request->header('X-Nulis-Signature', '');
$body = $request->getContent();
$expected = 'sha256=' . hash_hmac('sha256', $body, $secret);
if (!hash_equals($expected, $sig)) {
abort(401);
}
$payload = $request->json()->all();
$data = $payload['data'] ?? [];
$uuid = $data['article_uuid'] ?? null;
if (!$uuid) {
return response()->json(['error' => 'missing uuid'], 422);
}
$seo = $data['seo_package']['seo'] ?? [];
Article::updateOrCreate(
['external_uuid' => $uuid],
[
'title' => $data['title']['h1'] ?? $data['topic'],
'slug' => $data['title']['slug'] ?? null,
'body_html' => $data['content']['body_html'] ?? '',
'meta_title' => $seo['meta_title'] ?? null,
'meta_description' => $seo['meta_description'] ?? null,
'focus_keyword' => $seo['focus_keyword'] ?? null,
]
);
return response()->json(['ok' => true]);
}
}
Pull alternatif¶
$response = Http::withToken($apiKey)
->get("https://studio.nulis.top/api/v1/articles/{$uuid}");
$article = $response->json();
Gunakan article_uuid sebagai kunci idempotency.