1import{c as $e,b as ze,r as Ie,j as t,L as h,H as Be}from"./app-Da8ydggO.js";import{A as De}from"./app-logo-icon-CxKMCRLi.js";import{B as Ue}from"./badge-DMIDZd3R.js";import{B as F}from"./button-BmDgkJaU.js";import{h as We,d as Pe,b as qe,r as Le}from"./index-BLAl4Rvk.js";import{Z as Me}from"./zap-rJ9yI3zJ.js";import{S as Ye}from"./shield-CPg1GzE6.js";import{c as Ge}from"./createLucideIcon-C4W1dCfJ.js";import{C as Ve}from"./check-Ci5l8BE1.js";import{C as Je}from"./copy-3r8Cbq7x.js";/* empty css *//** 2 * @license lucide-react v0.475.0 - ISC 3 * 4 * This source code is licensed under the ISC license. 5 * See the LICENSE file in the root directory of this source tree. 6 */const Xe=[["path",{d:"m18 16 4-4-4-4",key:"1inbqp"}],["path",{d:"m6 8-4 4 4 4",key:"15zrgr"}],["path",{d:"m14.5 4-5 16",key:"e7oirm"}]],Ke=Ge("CodeXml",Xe);function u(e){const s=$e.c(13),{code:a,language:x}=e,m=x===void 0?"json":x,[r,i]=Ie.useState(!1);let l;s[0]!==a?(l=()=>{navigator.clipboard.writeText(a),i(!0),setTimeout(()=>i(!1),2e3)},s[0]=a,s[1]=l):l=s[1];const o=l;let n;s[2]!==r?(n=r?t.jsx(Ve,{className:"h-4 w-4 text-green-400"}):t.jsx(Je,{className:"h-4 w-4 text-slate-300"}),s[2]=r,s[3]=n):n=s[3];let c;s[4]!==o||s[5]!==n?(c=t.jsx("button",{onClick:o,className:"absolute top-3 right-3 rounded-md bg-slate-700 p-2 opacity-0 transition-opacity group-hover:opacity-100 hover:bg-slate-600",title:"Copy to clipboard",children:n}),s[4]=o,s[5]=n,s[6]=c):c=s[6];const b=`language-${m}`;let d;s[7]!==a||s[8]!==b?(d=t.jsx("pre",{className:"overflow-x-auto rounded-lg bg-slate-900 p-4 text-sm text-slate-300",children:t.jsx("code",{className:b,children:a})}),s[7]=a,s[8]=b,s[9]=d):d=s[9];let p;return s[10]!==c||s[11]!==d?(p=t.jsxs("div",{className:"group relative",children:[c,d]}),s[10]=c,s[11]=d,s[12]=p):p=s[12],p}function He(e){const s=$e.c(10),{icon:a,title:x,description:m}=e;let r;s[0]!==a?(r=t.jsx("div",{className:"mb-4 flex h-10 w-10 items-center justify-center rounded-lg bg-[#00AAFF]/10",children:t.jsx(a,{className:"h-5 w-5 text-[#00AAFF]"})}),s[0]=a,s[1]=r):r=s[1];let i;s[2]!==x?(i=t.jsx("h3",{className:"mb-2 font-semibold text-slate-900 dark:text-white",children:x}),s[2]=x,s[3]=i):i=s[3];let l;s[4]!==m?(l=t.jsx("p",{className:"text-sm text-slate-600 dark:text-slate-400",children:m}),s[4]=m,s[5]=l):l=s[5];let o;return s[6]!==r||s[7]!==i||s[8]!==l?(o=t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-6 dark:border-slate-800 dark:bg-slate-900",children:[r,i,l]}),s[6]=r,s[7]=i,s[8]=l,s[9]=o):o=s[9],o}const Ze=`{ 7 "event_type": "publish_article", 8 "timestamp": "2025-01-15T10:30:00+00:00", 9 "data": { 10 "article": { 11 "id": 42, 12 "title": "How to Boost Your SEO Rankings in 2025", 13 "slug": "how-to-boost-seo-rankings-2025", 14 "content_html": "<h2>Introduction</h2><p>Search engine optimization...</p>", 15 "content_markdown": "## Introduction\\n\\nSearch engine optimization...", 16 "meta_description": "Learn proven SEO strategies to improve your search rankings and drive organic traffic in 2025.", 17 "excerpt": "Learn proven SEO strategies to improve your search rankings...", 18 "image_url": "https://example.com/storage/articles/featured-image.png", 19 "tags": ["SEO", "Marketing", "Digital Strategy"], 20 "created_at": "2025-01-15T10:30:00+00:00", 21 "word_count": 1847, 22 "reading_time_minutes": 8 23 } 24 } 25}`,Qe=`{ 26 "event_type": "test", 27 "timestamp": "2025-01-15T10:30:00+00:00", 28 "data": { 29 "article": { 30 "id": 0, 31 "title": "Test Connection", 32 "slug": "test-connection", 33 "content_html": "<p>This is a test payload to verify your webhook endpoint.</p>", 34 "content_markdown": "This is a test payload to verify your webhook endpoint.", 35 "meta_description": "Test payload", 36 "created_at": "2025-01-15T10:30:00+00:00" 37 } 38 } 39}`,et=`<?php 40// Laravel example webhook handler 41 42Route::post('/webhook/opencopy', function (Request $request) { 43 // Verify the Bearer token 44 $token = $request->bearerToken(); 45 if ($token !== config('services.opencopy.webhook_secret')) { 46 return response()->json(['error' => 'Unauthorized'], 401); 47 } 48 49 $payload = $request->all(); 50 $eventType = $payload['event_type']; 51 52 // Handle test events 53 if ($eventType === 'test') { 54 return response()->json([ 55 'success' => true, 56 'message' => 'Webhook configured successfully' 57 ]); 58 } 59 60 // Handle article publish events 61 if ($eventType === 'publish_article') { 62 $article = $payload['data']['article']; 63 64 // Create your blog post 65 $post = Post::create([ 66 'title' => $article['title'], 67 'slug' => $article['slug'], 68 'content' => $article['content_html'], 69 'excerpt' => $article['excerpt'], 70 'meta_description' => $article['meta_description'], 71 'featured_image' => $article['image_url'], 72 ]); 73 74 return response()->json([ 75 'id' => $post->id, 76 'url' => url("/blog/{$post->slug}"), 77 ]); 78 } 79 80 return response()->json(['success' => true]); 81});`,tt=`// Express.js example webhook handler 82 83const express = require('express'); 84const app = express(); 85 86app.use(express.json()); 87 88app.post('/webhook/opencopy', (req, res) => { 89 // Verify the Bearer token 90 const authHeader = req.headers.authorization; 91 const token = authHeader?.replace('Bearer ', ''); 92 93 if (token !== process.env.OPENCOPY_WEBHOOK_SECRET) { 94 return res.status(401).json({ error: 'Unauthorized' }); 95 } 96 97 const { event_type, data } = req.body; 98 99 // Handle test events 100 if (event_type === 'test') { 101 return res.json({ 102 success: true, 103 message: 'Webhook configured successfully' 104 }); 105 } 106 107 // Handle article publish events 108 if (event_type === 'publish_article') { 109 const article = data.article; 110 111 // Create your blog post (example using a database) 112 const post = await createBlogPost({ 113 title: article.title, 114 slug: article.slug, 115 content: article.content_html, 116 excerpt: article.excerpt, 117 metaDescription: article.meta_description, 118 featuredImage: article.image_url, 119 }); 120 121 return res.json({ 122 id: post.id, 123 url: \`https://yourdomain.com/blog/\${post.slug}\`, 124 }); 125 } 126 127 res.json({ success: true }); 128});`,st=`// Next.js API Route (app/api/webhook/opencopy/route.ts) 129 130import { NextRequest, NextResponse } from 'next/server'; 131 132export async function POST(request: NextRequest) { 133 // Verify the Bearer token 134 const authHeader = request.headers.get('authorization'); 135 const token = authHeader?.replace('Bearer ', ''); 136 137 if (token !== process.env.OPENCOPY_WEBHOOK_SECRET) { 138 return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); 139 } 140 141 const payload = await request.json(); 142 const { event_type, data } = payload; 143 144 // Handle test events 145 if (event_type === 'test') { 146 return NextResponse.json({ 147 success: true, 148 message: 'Webhook configured successfully' 149 }); 150 } 151 152 // Handle article publish events 153 if (event_type === 'publish_article') { 154 const article = data.article; 155 156 // Create your blog post 157 const post = await prisma.post.create({ 158 data: { 159 title: article.title, 160 slug: article.slug, 161 content: article.content_html, 162 excerpt: article.excerpt, 163 metaDescription: article.meta_description, 164 featuredImage: article.image_url, 165 }, 166 }); 167 168 return NextResponse.json({ 169 id: post.id, 170 url: \`https://yourdomain.com/blog/\${post.slug}\`, 171 }); 172 } 173 174 return NextResponse.json({ success: true }); 175}`;function pt(){const e=$e.c(97),{auth:s}=ze().props,[a,x]=Ie.useState("php");let m;e[0]===Symbol.for("react.memo_cache_sentinel")?(m=t.jsx(Be,{title:"Webhook Integration Guide | OpenCopy.ai"}),e[0]=m):m=e[0];let r;e[1]===Symbol.for("react.memo_cache_sentinel")?(r=We(),e[1]=r):r=e[1];let i;e[2]===Symbol.for("react.memo_cache_sentinel")?(i=t.jsx(De,{className:"size-8"}),e[2]=i):i=e[2];let l;e[3]===Symbol.for("react.memo_cache_sentinel")?(l=t.jsxs(h,{href:r,className:"flex items-center gap-2",children:[i,t.jsxs("span",{className:"text-lg font-semibold text-slate-900 dark:text-white",children:["OpenCopy",t.jsx("span",{className:"text-[#00AAFF]",children:".ai"})]})]}),e[3]=l):l=e[3];let o;e[4]!==s.user?(o=t.jsx("header",{className:"border-b border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-950",children:t.jsxs("div",{className:"mx-auto flex h-16 max-w-5xl items-center justify-between px-6",children:[l,t.jsx("div",{className:"flex items-center gap-3",children:s.user?t.jsx(F,{asChild:!0,size:"sm",children:t.jsx(h,{href:Pe(),children:"Dashboard"})}):t.jsxs(t.Fragment,{children:[t.jsx(F,{variant:"ghost",asChild:!0,size:"sm",children:t.jsx(h,{href:qe(),children:"Log in"})}),t.jsx(F,{asChild:!0,size:"sm",className:"bg-[#00AAFF] hover:bg-[#0095e0]",children:t.jsx(h,{href:Le(),children:"Get Started"})})]})})]})}),e[4]=s.user,e[5]=o):o=e[5];let n;e[6]===Symbol.for("react.memo_cache_sentinel")?(n=t.jsx("div",{className:"border-b border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-950",children:t.jsxs("div",{className:"mx-auto max-w-5xl px-6 py-16",children:[t.jsx(Ue,{className:"mb-4 bg-[#00AAFF]/10 text-[#00AAFF] hover:bg-[#00AAFF]/20",children:"Developer Documentation"}),t.jsx("h1",{className:"mb-4 text-4xl font-bold tracking-tight text-slate-900 dark:text-white",children:"Webhook Integration Guide"}
175),t.jsx("p",{className:"max-w-2xl text-lg text-slate-600 dark:text-slate-400",children:"Automatically publish AI-generated articles to your website or CMS. OpenCopy sends structured JSON payloads to your endpoint whenever content is ready."})]})}),e[6]=n):n=e[6];let c;e[7]===Symbol.for("react.memo_cache_sentinel")?(c=t.jsxs("div",{className:"mb-16 grid gap-6 md:grid-cols-3",children:[t.jsx(He,{icon:Me,title:"Real-time Delivery",description:"Articles are sent to your endpoint immediately when published, with automatic retry on failures."}),t.jsx(He,{icon:Ye,title:"Secure by Default",description:"All webhooks require HTTPS and Bearer token authentication to protect your endpoint."}),t.jsx(He,{icon:Ke,title:"Flexible Format",description:"Receive content in both HTML and Markdown, plus SEO metadata, tags, and featured images."})]}),e[7]=c):c=e[7];let b;e[8]===Symbol.for("react.memo_cache_sentinel")?(b=t.jsx("h2",{className:"mb-6 text-2xl font-bold text-slate-900 dark:text-white",children:"Setting Up Your Webhook"}),e[8]=b):b=e[8];let d;e[9]===Symbol.for("react.memo_cache_sentinel")?(d=t.jsx("h3",{className:"mb-4 text-lg font-semibold text-slate-900 dark:text-white",children:"What You'll Need"}),e[9]=d):d=e[9];let p,C;e[10]===Symbol.for("react.memo_cache_sentinel")?(C=t.jsx("div",{className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[#00AAFF] text-sm font-bold text-white",children:"1"}),p=t.jsx("h4",{className:"font-medium text-slate-900 dark:text-white",children:"Webhook URL"}),e[10]=p,e[11]=C):(p=e[10],C=e[11]);let T;e[12]===Symbol.for("react.memo_cache_sentinel")?(T=t.jsxs("div",{className:"flex gap-4",children:[C,t.jsxs("div",{children:[p,t.jsxs("p",{className:"mt-1 text-sm text-slate-600 dark:text-slate-400",children:["A publicly accessible HTTPS endpoint that can receive POST requests. Example:"," ",t.jsx("code",{className:"rounded bg-slate-100 px-1.5 py-0.5 text-sm dark:bg-slate-800",children:"https://yoursite.com/api/webhook/opencopy"})]})]})]}),e[12]=T):T=e[12];let O,E;e[13]===Symbol.for("react.memo_cache_sentinel")?(O=t.jsx("div",{className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[#00AAFF] text-sm font-bold text-white",children:"2"}),E=t.jsx("h4",{className:"font-medium text-slate-900 dark:text-white",children:"Access Token"}),e[13]=O,e[14]=E):(O=e[13],E=e[14]);let R;e[15]===Symbol.for("react.memo_cache_sentinel")?(R=t.jsxs("section",{className:"mb-16",children:[b,t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-8 dark:border-slate-800 dark:bg-slate-900",children:[d,t.jsxs("div",{className:"space-y-6",children:[T,t.jsxs("div",{className:"flex gap-4",children:[O,t.jsxs("div",{children:[E,t.jsxs("p",{className:"mt-1 text-sm text-slate-600 dark:text-slate-400",children:["A secret token you generate to authenticate webhook requests. OpenCopy sends this as a Bearer token in the"," ",t.jsx("code",{className:"rounded bg-slate-100 px-1.5 py-0.5 text-sm dark:bg-slate-800",children:"Authorization"})," ","header. Generate a secure random string (32+ characters recommended)."]})]})]})]})]})]}),e[15]=R):R=e[15];let H,$;e[16]===Symbol.for("react.memo_cache_sentinel")?(H=t.jsx("h2",{className:"mb-6 text-2xl font-bold text-slate-900 dark:text-white",children:"Webhook Payload Structure"}),$=t.jsx("p",{className:"mb-6 text-slate-600 dark:text-slate-400",children:"When you publish an article from OpenCopy, we send a POST request to your webhook URL with the following JSON structure:"}),e[16]=H,e[17]=$):(H=e[16],$=e[17]);let P;e[18]===Symbol.for("react.memo_cache_sentinel")?(P=t.jsxs("div",{className:"mb-8",children:[t.jsx("h3",{className:"mb-3 text-sm font-semibold tracking-wide text-slate-500 uppercase dark:text-slate-400",children:"Publish Article Event"}),t.jsx(u,{code:Ze})]}),e[18]=P):P=e[18];let q;e[19]===Symbol.for("react.memo_cache_sentinel")?(q=t.jsx("h3",{className:"mb-4 text-lg font-semibold text-slate-900 dark:text-white",children:"Field Reference"}),e[19]=q):q=e[19];let L;e[20]===Symbol.for("react.memo_cache_sentinel")?(L=t.jsx("thead",{children:t.jsxs("tr",{className:"border-b border-slate-200 dark:border-slate-700",children:[t.jsx("th",{className:"pr-4 pb-3 text-left font-semibold text-slate-900 dark:text-white",children:"Field"}),t.jsx("th",{className:"pr-4 pb-3 text-left font-semibold text-slate-900 dark:text-white",children:"Type"}),t.jsx("th",{className:"pb-3 text-left font-semibold text-slate-900 dark:text-white",children:"Description"})]})}),e[20]=L):L=e[20];let I,z;e[21]===Symbol.for("react.memo_cache_sentinel")?(I=t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"event_type"}
175),z=t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"string"}),e[21]=I,e[22]=z):(I=e[21],z=e[22]);let B;e[23]===Symbol.for("react.memo_cache_sentinel")?(B=t.jsx("code",{className:"rounded bg-slate-100 px-1 dark:bg-slate-800",children:'"publish_article"'}),e[23]=B):B=e[23];let D;e[24]===Symbol.for("react.memo_cache_sentinel")?(D=t.jsxs("section",{className:"mb-16",children:[H,$,P,t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-6 dark:border-slate-800 dark:bg-slate-900",children:[q,t.jsx("div",{className:"overflow-x-auto",children:t.jsxs("table",{className:"w-full text-sm",children:[L,t.jsxs("tbody",{className:"divide-y divide-slate-100 dark:divide-slate-800",children:[t.jsxs("tr",{children:[I,z,t.jsxs("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:[B," ","or"," ",t.jsx("code",{className:"rounded bg-slate-100 px-1 dark:bg-slate-800",children:'"test"'})]})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"timestamp"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"string"}),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"ISO 8601 formatted timestamp"})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"data.article.id"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"integer"}),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"Unique article ID in OpenCopy"})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"data.article.title"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"string"}),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"Article headline/title"})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"data.article.slug"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"string"}),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"URL-friendly slug for routing"})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"data.article.content_html"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"string"}),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"Full article content as HTML"})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"data.article.content_markdown"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"string"}),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"Full article content as Markdown"})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"data.article.meta_description"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"string | null"}),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"SEO meta description (150-160 chars)"})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"data.article.excerpt"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"string | null"}),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"Short summary for previews"})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"data.article.image_url"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"string | null"}),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"Featured image URL (absolute)"})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"data.article.tags"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"string[]"}
175),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"Array of tag/category names"})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"data.article.word_count"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"integer"}),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"Total word count"})]}),t.jsxs("tr",{children:[t.jsx("td",{className:"py-3 pr-4 font-mono text-xs text-[#00AAFF]",children:"data.article.reading_time_minutes"}),t.jsx("td",{className:"py-3 pr-4 text-slate-600 dark:text-slate-400",children:"integer"}),t.jsx("td",{className:"py-3 text-slate-600 dark:text-slate-400",children:"Estimated reading time"})]})]})]})})]})]}),e[24]=D):D=e[24];let U,W,M;e[25]===Symbol.for("react.memo_cache_sentinel")?(U=t.jsx("h2",{className:"mb-6 text-2xl font-bold text-slate-900 dark:text-white",children:"Test Connection Event"}),W=t.jsx("p",{className:"mb-6 text-slate-600 dark:text-slate-400",children:'When you click "Test Connection" in OpenCopy, we send a test payload to verify your endpoint is working correctly:'}),M=t.jsx(u,{code:Qe}),e[25]=U,e[26]=W,e[27]=M):(U=e[25],W=e[26],M=e[27]);let Y;e[28]===Symbol.for("react.memo_cache_sentinel")?(Y=t.jsx("strong",{children:"Note:"}),e[28]=Y):Y=e[28];let G;e[29]===Symbol.for("react.memo_cache_sentinel")?(G=t.jsx("code",{className:"rounded bg-amber-100 px-1 dark:bg-amber-900",children:'event_type: "test"'}),e[29]=G):G=e[29];let V;e[30]===Symbol.for("react.memo_cache_sentinel")?(V=t.jsxs("section",{className:"mb-16",children:[U,W,M,t.jsx("div",{className:"mt-4 rounded-lg border border-amber-200 bg-amber-50 p-4 dark:border-amber-900 dark:bg-amber-950/50",children:t.jsxs("p",{className:"text-sm text-amber-800 dark:text-amber-200",children:[Y," Test events have"," ",G," ","and"," ",t.jsx("code",{className:"rounded bg-amber-100 px-1 dark:bg-amber-900",children:"id: 0"}),". Your endpoint should handle these gracefully without creating actual content."]})})]}),e[30]=V):V=e[30];let J,X;e[31]===Symbol.for("react.memo_cache_sentinel")?(J=t.jsx("h2",{className:"mb-6 text-2xl font-bold text-slate-900 dark:text-white",children:"Expected Response"}),X=t.jsx("p",{className:"mb-6 text-slate-600 dark:text-slate-400",children:"Your endpoint should return a JSON response. OpenCopy looks for specific fields to track the publication:"}),e[31]=J,e[32]=X):(J=e[31],X=e[32]);let K;e[33]===Symbol.for("react.memo_cache_sentinel")?(K=t.jsxs("section",{className:"mb-16",children:[J,X,t.jsxs("div",{className:"grid gap-6 md:grid-cols-2",children:[t.jsxs("div",{children:[t.jsx("h3",{className:"mb-3 text-sm font-semibold tracking-wide text-green-600 uppercase dark:text-green-400",children:"Success Response (2xx)"}),t.jsx(u,{code:`{ 176 "id": "123", 177 "url": "https://yoursite.com/blog/article-slug" 178}`}),t.jsx("p",{className:"mt-3 text-sm text-slate-600 dark:text-slate-400",children:"Return the created post's ID and public URL. These are stored in OpenCopy for your reference."})]}),t.jsxs("div",{children:[t.jsx("h3",{className:"mb-3 text-sm font-semibold tracking-wide text-red-600 uppercase dark:text-red-400",children:"Error Response (4xx/5xx)"}),t.jsx(u,{code:`{ 179 "error": "Invalid article data", 180 "message": "Title is required" 181}`}),t.jsx("p",{className:"mt-3 text-sm text-slate-600 dark:text-slate-400",children:"Return an error message. OpenCopy will retry on 5xx errors up to 3 times."})]})]})]}),e[33]=K):K=e[33];let Z,Q;e[34]===Symbol.for("react.memo_cache_sentinel")?(Z=t.jsx("h2",{className:"mb-6 text-2xl font-bold text-slate-900 dark:text-white",children:"Request Headers"}),Q=t.jsx("p",{className:"mb-6 text-slate-600 dark:text-slate-400",children:"OpenCopy sends the following headers with every webhook request:"}),e[34]=Z,e[35]=Q):(Z=e[34],Q=e[35]);let ee;e[36]===Symbol.for("react.memo_cache_sentinel")?(ee=t.jsx("thead",{className:"bg-slate-50 dark:bg-slate-900",children:t.jsxs("tr",{children:[t.jsx("th",{className:"px-4 py-3 text-left font-semibold text-slate-900 dark:text-white",children:"Header"}),t.jsx("th",{className:"px-4 py-3 text-left font-semibold text-slate-900 dark:text-white",children:"Value"})]})}),e[36]=ee):ee=e[36];let te;
181e[37]===Symbol.for("react.memo_cache_sentinel")?(te=t.jsx("td",{className:"px-4 py-3 font-mono text-xs text-[#00AAFF]",children:"Authorization"}),e[37]=te):te=e[37];let se,ae;e[38]===Symbol.for("react.memo_cache_sentinel")?(se=t.jsxs("tr",{children:[te,t.jsx("td",{className:"px-4 py-3 text-slate-600 dark:text-slate-400",children:t.jsx("code",{className:"rounded bg-slate-100 px-1.5 py-0.5 dark:bg-slate-800",children:"Bearer your-access-token"})})]}),ae=t.jsx("td",{className:"px-4 py-3 font-mono text-xs text-[#00AAFF]",children:"Content-Type"}),e[38]=se,e[39]=ae):(se=e[38],ae=e[39]);let le,re;e[40]===Symbol.for("react.memo_cache_sentinel")?(le=t.jsxs("tr",{children:[ae,t.jsx("td",{className:"px-4 py-3 text-slate-600 dark:text-slate-400",children:t.jsx("code",{className:"rounded bg-slate-100 px-1.5 py-0.5 dark:bg-slate-800",children:"application/json"})})]}),re=t.jsx("td",{className:"px-4 py-3 font-mono text-xs text-[#00AAFF]",children:"Accept"}),e[40]=le,e[41]=re):(le=e[40],re=e[41]);let oe,ie;e[42]===Symbol.for("react.memo_cache_sentinel")?(oe=t.jsxs("tr",{children:[re,t.jsx("td",{className:"px-4 py-3 text-slate-600 dark:text-slate-400",children:t.jsx("code",{className:"rounded bg-slate-100 px-1.5 py-0.5 dark:bg-slate-800",children:"application/json"})})]}),ie=t.jsx("td",{className:"px-4 py-3 font-mono text-xs text-[#00AAFF]",children:"User-Agent"}),e[42]=oe,e[43]=ie):(oe=e[42],ie=e[43]);let ne;e[44]===Symbol.for("react.memo_cache_sentinel")?(ne=t.jsxs("section",{className:"mb-16",children:[Z,Q,t.jsx("div",{className:"overflow-hidden rounded-lg border border-slate-200 dark:border-slate-800",children:t.jsxs("table",{className:"w-full text-sm",children:[ee,t.jsxs("tbody",{className:"divide-y divide-slate-200 bg-white dark:divide-slate-800 dark:bg-slate-950",children:[se,le,oe,t.jsxs("tr",{children:[ie,t.jsx("td",{className:"px-4 py-3 text-slate-600 dark:text-slate-400",children:t.jsx("code",{className:"rounded bg-slate-100 px-1.5 py-0.5 dark:bg-slate-800",children:"OpenCopy/1.0"})})]})]})]})})]}),e[44]=ne):ne=e[44];let ce,de;e[45]===Symbol.for("react.memo_cache_sentinel")?(ce=t.jsx("h2",{className:"mb-6 text-2xl font-bold text-slate-900 dark:text-white",children:"Implementation Examples"}),de=t.jsx("p",{className:"mb-6 text-slate-600 dark:text-slate-400",children:"Here are example webhook handlers for popular frameworks:"}),e[45]=ce,e[46]=de):(ce=e[45],de=e[46]);let xe;e[47]===Symbol.for("react.memo_cache_sentinel")?(xe=()=>x("php"),e[47]=xe):xe=e[47];const Oe=`rounded-lg px-4 py-2 text-sm font-medium transition-colors ${a==="php"?"bg-[#00AAFF] text-white":"bg-slate-100 text-slate-700 hover:bg-slate-200 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700"}`;let f;e[48]!==Oe?(f=t.jsx("button",{onClick:xe,className:Oe,children:"PHP / Laravel"}),e[48]=Oe,e[49]=f):f=e[49];let me;e[50]===Symbol.for("react.memo_cache_sentinel")?(me=()=>x("node"),e[50]=me):me=e[50];const Ee=`rounded-lg px-4 py-2 text-sm font-medium transition-colors ${a==="node"?"bg-[#00AAFF] text-white":"bg-slate-100 text-slate-700 hover:bg-slate-200 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700"}`;let g;e[51]!==Ee?(g=t.jsx("button",{onClick:me,className:Ee,children:"Node.js / Express"}),e[51]=Ee,e[52]=g):g=e[52];let he;e[53]===Symbol.for("react.memo_cache_sentinel")?(he=()=>x("nextjs"),e[53]=he):he=e[53];const Re=`rounded-lg px-4 py-2 text-sm font-medium transition-colors ${a==="nextjs"?"bg-[#00AAFF] text-white":"bg-slate-100 text-slate-700 hover:bg-slate-200 dark:bg-slate-800 dark:text-slate-300 dark:hover:bg-slate-700"}`;let j;e[54]!==Re?(j=t.jsx("button",{onClick:he,className:Re,children:"Next.js"}),e[54]=Re,e[55]=j):j=e[55];let y;e[56]!==f||e[57]!==g||e[58]!==j?(y=t.jsxs("div",{className:"mb-4 flex gap-2",children:[f,g,j]}),e[56]=f,e[57]=g,e[58]=j,e[59]=y):y=e[59];let k;e[60]!==a?(k=a==="php"&&t.jsx(u,{code:et,language:"php"}),e[60]=a,e[61]=k):k=e[61];let N;e[62]!==a?(N=a==="node"&&t.jsx(u,{code:tt,language:"javascript"}),e[62]=a,e[63]=N):N=e[63];let _;e[64]!==a?(_=a==="nextjs"&&t.jsx(u,{code:st,language:"typescript"}),e[64]=a,e[65]=_):_=e[65];let v;e[66]!==k||e[67]!==N||e[68]!==_?(v=t.jsxs("div",{children:[k,N,_]}),e[66]=k,e[67]=N,e[68]=_,e[69]=v):v=e[69];let w;e[70]!==y||e[71]!==v?(w=t.jsxs("section",{className:"mb-16",children:[ce,de,y,v]}),e[70]=y,e[71]=v,e[72]=w):w=e[72];let pe;e[73]===Symbol.for("react.memo_cache_sentinel")?(pe=t.jsx("h2",{className:"mb-6 text-2xl font-bold text-slate-900 dark:text-white",children:"Security Best Practices"}),e[73]=pe):pe=e[73];let be;e[74]===Symbol.for("react.memo_cache_sentinel")?(be=t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-6 dark:border-slate-800 dark:bg-slate-900",children:[t.jsx("h3",{className:"mb-2 font-semibold text-slate-900 dark:text-white",children:"Always Verify the Access Token"}
181),t.jsx("p",{className:"text-sm text-slate-600 dark:text-slate-400",children:"Check that the Bearer token in the Authorization header matches your configured secret. Reject requests with invalid or missing tokens with a 401 response."})]}),e[74]=be):be=e[74];let ue;e[75]===Symbol.for("react.memo_cache_sentinel")?(ue=t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-6 dark:border-slate-800 dark:bg-slate-900",children:[t.jsx("h3",{className:"mb-2 font-semibold text-slate-900 dark:text-white",children:"Use HTTPS Only"}),t.jsx("p",{className:"text-sm text-slate-600 dark:text-slate-400",children:"OpenCopy requires HTTPS endpoints. Never use HTTP as it exposes your access token and content in transit."})]}),e[75]=ue):ue=e[75];let fe;e[76]===Symbol.for("react.memo_cache_sentinel")?(fe=t.jsx("h3",{className:"mb-2 font-semibold text-slate-900 dark:text-white",children:"Generate Strong Access Tokens"}),e[76]=fe):fe=e[76];let ge;e[77]===Symbol.for("react.memo_cache_sentinel")?(ge=t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-6 dark:border-slate-800 dark:bg-slate-900",children:[fe,t.jsxs("p",{className:"text-sm text-slate-600 dark:text-slate-400",children:["Use cryptographically secure random strings of at least 32 characters. Tools like"," ",t.jsx("code",{className:"rounded bg-slate-100 px-1 dark:bg-slate-800",children:"openssl rand -hex 32"})," ","work great."]})]}),e[77]=ge):ge=e[77];let je;e[78]===Symbol.for("react.memo_cache_sentinel")?(je=t.jsxs("section",{className:"mb-16",children:[pe,t.jsxs("div",{className:"space-y-4",children:[be,ue,ge,t.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-6 dark:border-slate-800 dark:bg-slate-900",children:[t.jsx("h3",{className:"mb-2 font-semibold text-slate-900 dark:text-white",children:"Sanitize HTML Content"}),t.jsx("p",{className:"text-sm text-slate-600 dark:text-slate-400",children:"If you render the HTML content directly, ensure you sanitize it to prevent XSS attacks. Use libraries like DOMPurify (JavaScript) or HTMLPurifier (PHP)."})]})]})]}),e[78]=je):je=e[78];let ye;e[79]===Symbol.for("react.memo_cache_sentinel")?(ye=t.jsx("h2",{className:"mb-6 text-2xl font-bold text-slate-900 dark:text-white",children:"Troubleshooting"}),e[79]=ye):ye=e[79];let ke,Ne,_e,ve;e[80]===Symbol.for("react.memo_cache_sentinel")?(ke=t.jsxs("div",{children:[t.jsx("h3",{className:"mb-2 font-semibold text-slate-900 dark:text-white",children:"Connection Timeout"}),t.jsx("p",{className:"text-sm text-slate-600 dark:text-slate-400",children:"By default, OpenCopy waits 30 seconds for a response. If your processing takes longer, consider accepting the webhook quickly and processing asynchronously (e.g., using a job queue)."})]}),Ne=t.jsxs("div",{children:[t.jsx("h3",{className:"mb-2 font-semibold text-slate-900 dark:text-white",children:"401 Unauthorized Errors"}),t.jsx("p",{className:"text-sm text-slate-600 dark:text-slate-400",children:"Ensure the access token configured in OpenCopy matches exactly what your endpoint expects. Check for trailing spaces or newlines."})]}),_e=t.jsxs("div",{children:[t.jsx("h3",{className:"mb-2 font-semibold text-slate-900 dark:text-white",children:"SSL Certificate Errors"}),t.jsx("p",{className:"text-sm text-slate-600 dark:text-slate-400",children:"Make sure your SSL certificate is valid and not self-signed. Free certificates from Let's Encrypt work perfectly."})]}),ve=t.jsx("h3",{className:"mb-2 font-semibold text-slate-900 dark:text-white",children:"Retries and Duplicate Content"}),e[80]=ke,e[81]=Ne,e[82]=_e,e[83]=ve):(ke=e[80],Ne=e[81],_e=e[82],ve=e[83]);let we;e[84]===Symbol.for("react.memo_cache_sentinel")?(we=t.jsxs("section",{className:"mb-16",children:[ye,t.jsxs("div",{className:"space-y-6",children:[ke,Ne,_e,t.jsxs("div",{children:[ve,t.jsxs("p",{className:"text-sm text-slate-600 dark:text-slate-400",children:["OpenCopy retries failed requests (5xx errors) up to 3 times. Implement idempotency using the",t.jsx("code",{className:"mx-1 rounded bg-slate-100 px-1 dark:bg-slate-800",children:"data.article.id"}),"field to prevent duplicate posts."]})]})]})]}),e[84]=we):we=e[84];let Se,Ae;e[85]===Symbol.for("react.memo_cache_sentinel")?(Se=t.jsx("h2",{className:"mb-4 text-2xl font-bold",children:"Ready to Get Started?"}),Ae=t.jsx("p",{className:"mb-6 text-blue-100",children:"Set up your webhook integration in minutes and start publishing AI-generated content automatically."}),e[85]=Se,e[86]=Ae):(Se=e[85],Ae=e[86]);let S;e[87]!==s.user?(S=t.jsxs("section",{className:"rounded-2xl bg-gradient-to-br from-[#00AAFF] to-[#394f87] p-8 text-center text-white",children:[Se,Ae,t.jsx("div",{className:"flex justify-center gap-4",children:s.user?t.jsx(F,{asChild:!0,size:"lg",className:"bg-white text-[#00AAFF] hover:bg-slate-100",children:t.jsx(h,{href:Pe(),children:"Go to Dashboard"})}):t.jsxs(t.Fragment,{children:[t.jsx(F,{asChild:!0,size:"lg",className:"bg-white text-[#00AAFF] hover:bg-slate-100",children:t.jsx(h,{href:Le(),children:"Start Free Trial"})}),t.jsx(F,{asChild:!0,size:"lg",className:"border-2 border-white bg-transparent text-white hover:bg-white/10",children:t.jsx(h,{href:qe(),children:"Log In"})})]})})]}),e[87]=s.user,e[88]=S):S=e[88];let A;e[89]!==w||e[90]!==S?(A=t.jsxs("main",{className:"mx-auto max-w-5xl px-6 py-12",children:[c,R,D,V,K,ne,w,je,we,S]}),e[89]=w,e[90]=S,e[91]=A):A=e[91];let Fe;e[92]===Symbol.for("react.memo_cache_sentinel")?(Fe=t.jsxs("p",{children:["© ",new Date().getFullYear()," OpenCopy.ai. All rights reserved."]}),e[92]=Fe):Fe=e[92];let Ce;e[93]===Symbol.for("react.memo_cache_sentinel")?(Ce=t.jsx("footer",{className:"border-t border-slate-200 py-8 dark:border-slate-800",children:t.jsxs("div",{className:"mx-auto max-w-5xl px-6 text-center text-sm text-slate-500 dark:text-slate-400",children:[Fe,t.jsxs("div",{className:"mt-2 flex justify-center gap-4",children:[t.jsx(h,{href:"/terms",className:"hover:text-slate-900 dark:hover:text-white",children:"Terms of Service"}),t.jsx(h,{href:"/privacy",className:"hover:text-slate-900 dark:hover:text-white",children:"Privacy Policy"}),t.jsx(h,{href:"/docs/webhook-integration",className:"text-[#00AAFF]",children:"Webhook Docs"})]})]})}),e[93]=Ce):Ce=e[93];let Te;return e[94]!==o||e[95]!==A?(Te=t.jsxs(t.Fragment,{children:[m,t.jsxs("div",{className:"min-h-screen bg-slate-50 dark:bg-slate-950",children:[o,n,A,Ce]})]}),e[94]=o,e[95]=A,e[96]=Te):Te=e[96],Te}export{pt as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.