[{"data":1,"prerenderedAt":1604},["ShallowReactive",2],{"page-\u002Fwebhook\u002Fsetup":3},{"id":4,"title":5,"body":6,"description":1596,"endpoint":1597,"extension":1598,"icon":1597,"meta":1599,"method":1597,"nav":1597,"navigation":220,"path":1600,"seo":1601,"stem":1602,"__hash__":1603},"docs\u002Fwebhook\u002Fsetup.md","Setup webhook",{"type":7,"value":8,"toc":1583},"minimark",[9,24,29,85,89,120,123,135,139,142,157,168,173,591,595,788,809,813,1042,1046,1478,1482,1485,1539,1546,1550,1559,1563,1579],[10,11,12,13,17,18,23],"p",{},"Webhook membuat CSKU mengirim ",[14,15,16],"code",{},"POST"," ke server Anda setiap kali ada pesan masuk dari pelanggan, balasan AI, atau balasan agen. Anda tidak perlu polling ke ",[19,20,22],"a",{"href":21},"\u002Fapi\u002Fambil-pesan","Ambil pesan",".",[25,26,28],"h2",{"id":27},"prasyarat","Prasyarat",[30,31,32,45,52,70],"ul",{},[33,34,35,36,40,41,23],"li",{},"Paket Anda punya fitur ",[37,38,39],"strong",{},"Webhook",". Jika tidak, menu Webhook menampilkan ajakan upgrade. Lihat ",[19,42,44],{"href":43},"\u002Fpanduan\u002Fberlangganan","Berlangganan & kredit",[33,46,47,48,51],{},"Anda login sebagai ",[37,49,50],{},"owner"," bisnis. OTP hanya dikirim ke email owner.",[33,53,54,57,58,61,62,65,66,23],{},[37,55,56],{},"Secret Key"," sudah dibuat di ",[37,59,60],{},"Pengaturan → Secret Key",". Nilai ini dikirim di header ",[14,63,64],{},"Authorization"," setiap request webhook. Lihat ",[19,67,69],{"href":68},"\u002Fapi\u002Fautentikasi","Autentikasi",[33,71,72,73,76,77,80,81,84],{},"Server Anda bisa diakses publik lewat ",[14,74,75],{},"https",". Dashboard menolak URL ",[14,78,79],{},"http",", ",[14,82,83],{},"localhost",", dan alamat IP privat.",[25,86,88],{"id":87},"daftarkan-url","Daftarkan URL",[90,91,92,98,108,115],"ol",{},[33,93,94,95,23],{},"Buka ",[37,96,97],{},"Pengaturan → Webhook",[33,99,100,101,104,105,23],{},"Isi ",[37,102,103],{},"Webhook URL",", misalnya ",[14,106,107],{},"https:\u002F\u002Fapi.toko-anda.com\u002Fcsku\u002Fwebhook",[33,109,110,111,114],{},"Klik ",[37,112,113],{},"Perbarui Webhook",", lalu konfirmasi. CSKU mengirim kode OTP 6 digit ke email owner. Kode berlaku 5 menit.",[33,116,117,118,23],{},"Masukkan kode OTP, lalu klik ",[37,119,113],{},[10,121,122],{},"Setelah tersimpan, semua event langsung dikirim ke URL tersebut.",[124,125,128],"callout",{"title":126,"type":127},"Satu URL, semua event","info",[10,129,130,131,23],{},"Setiap bisnis punya satu URL webhook. Semua event dikirim ke URL itu dan tidak bisa difilter dari dashboard. Abaikan event yang tidak Anda perlukan di server Anda. Daftar event ada di ",[19,132,134],{"href":133},"\u002Fwebhook\u002Fevent","Event & payload",[25,136,138],{"id":137},"contoh-penerima","Contoh penerima",[10,140,141],{},"Server Anda wajib:",[90,143,144,150],{},[33,145,146,147,149],{},"Mencocokkan header ",[14,148,64],{}," dengan Secret Key Anda.",[33,151,152,153,156],{},"Membalas body JSON ",[14,154,155],{},"{\"success\": true}"," secepatnya (di bawah 30 detik).",[10,158,159,160,163,164,23],{},"Status HTTP tidak dibaca. Yang menentukan sukses hanya field ",[14,161,162],{},"success"," di body. Detail ada di ",[19,165,167],{"href":166},"\u002Fwebhook\u002Fkeamanan-retry","Keamanan & retry",[169,170,172],"h3",{"id":171},"nodejs-express","Node.js (Express)",[174,175,180],"pre",{"className":176,"code":177,"language":178,"meta":179,"style":179},"language-js shiki shiki-themes github-light github-dark","import express from 'express'\nimport crypto from 'node:crypto'\n\nconst app = express()\napp.use(express.json())\n\nconst SECRET = process.env.CSKU_SECRET\n\nfunction isValid(header) {\n  const a = Buffer.from(header || '')\n  const b = Buffer.from(SECRET)\n  return a.length === b.length && crypto.timingSafeEqual(a, b)\n}\n\napp.post('\u002Fcsku\u002Fwebhook', (req, res) => {\n  if (!isValid(req.get('Authorization'))) {\n    return res.status(401).json({ success: false })\n  }\n\n  res.json({ success: true })\n\n  \u002F\u002F Proses setelah membalas\n  const { event, message } = req.body\n  console.log(event, message.id)\n})\n\napp.listen(3000)\n","js","",[14,181,182,202,215,222,242,260,265,281,286,305,333,354,386,392,397,430,459,490,496,501,516,521,528,553,565,571,576],{"__ignoreMap":179},[183,184,187,191,195,198],"span",{"class":185,"line":186},"line",1,[183,188,190],{"class":189},"szBVR","import",[183,192,194],{"class":193},"sVt8B"," express ",[183,196,197],{"class":189},"from",[183,199,201],{"class":200},"sZZnC"," 'express'\n",[183,203,205,207,210,212],{"class":185,"line":204},2,[183,206,190],{"class":189},[183,208,209],{"class":193}," crypto ",[183,211,197],{"class":189},[183,213,214],{"class":200}," 'node:crypto'\n",[183,216,218],{"class":185,"line":217},3,[183,219,221],{"emptyLinePlaceholder":220},true,"\n",[183,223,225,228,232,235,239],{"class":185,"line":224},4,[183,226,227],{"class":189},"const",[183,229,231],{"class":230},"sj4cs"," app",[183,233,234],{"class":189}," =",[183,236,238],{"class":237},"sScJk"," express",[183,240,241],{"class":193},"()\n",[183,243,245,248,251,254,257],{"class":185,"line":244},5,[183,246,247],{"class":193},"app.",[183,249,250],{"class":237},"use",[183,252,253],{"class":193},"(express.",[183,255,256],{"class":237},"json",[183,258,259],{"class":193},"())\n",[183,261,263],{"class":185,"line":262},6,[183,264,221],{"emptyLinePlaceholder":220},[183,266,268,270,273,275,278],{"class":185,"line":267},7,[183,269,227],{"class":189},[183,271,272],{"class":230}," SECRET",[183,274,234],{"class":189},[183,276,277],{"class":193}," process.env.",[183,279,280],{"class":230},"CSKU_SECRET\n",[183,282,284],{"class":185,"line":283},8,[183,285,221],{"emptyLinePlaceholder":220},[183,287,289,292,295,298,302],{"class":185,"line":288},9,[183,290,291],{"class":189},"function",[183,293,294],{"class":237}," isValid",[183,296,297],{"class":193},"(",[183,299,301],{"class":300},"s4XuR","header",[183,303,304],{"class":193},") {\n",[183,306,308,311,314,316,319,321,324,327,330],{"class":185,"line":307},10,[183,309,310],{"class":189},"  const",[183,312,313],{"class":230}," a",[183,315,234],{"class":189},[183,317,318],{"class":193}," Buffer.",[183,320,197],{"class":237},[183,322,323],{"class":193},"(header ",[183,325,326],{"class":189},"||",[183,328,329],{"class":200}," ''",[183,331,332],{"class":193},")\n",[183,334,336,338,341,343,345,347,349,352],{"class":185,"line":335},11,[183,337,310],{"class":189},[183,339,340],{"class":230}," b",[183,342,234],{"class":189},[183,344,318],{"class":193},[183,346,197],{"class":237},[183,348,297],{"class":193},[183,350,351],{"class":230},"SECRET",[183,353,332],{"class":193},[183,355,357,360,363,366,369,372,374,377,380,383],{"class":185,"line":356},12,[183,358,359],{"class":189},"  return",[183,361,362],{"class":193}," a.",[183,364,365],{"class":230},"length",[183,367,368],{"class":189}," ===",[183,370,371],{"class":193}," b.",[183,373,365],{"class":230},[183,375,376],{"class":189}," &&",[183,378,379],{"class":193}," crypto.",[183,381,382],{"class":237},"timingSafeEqual",[183,384,385],{"class":193},"(a, b)\n",[183,387,389],{"class":185,"line":388},13,[183,390,391],{"class":193},"}\n",[183,393,395],{"class":185,"line":394},14,[183,396,221],{"emptyLinePlaceholder":220},[183,398,400,402,405,407,410,413,416,418,421,424,427],{"class":185,"line":399},15,[183,401,247],{"class":193},[183,403,404],{"class":237},"post",[183,406,297],{"class":193},[183,408,409],{"class":200},"'\u002Fcsku\u002Fwebhook'",[183,411,412],{"class":193},", (",[183,414,415],{"class":300},"req",[183,417,80],{"class":193},[183,419,420],{"class":300},"res",[183,422,423],{"class":193},") ",[183,425,426],{"class":189},"=>",[183,428,429],{"class":193}," {\n",[183,431,433,436,439,442,445,448,451,453,456],{"class":185,"line":432},16,[183,434,435],{"class":189},"  if",[183,437,438],{"class":193}," (",[183,440,441],{"class":189},"!",[183,443,444],{"class":237},"isValid",[183,446,447],{"class":193},"(req.",[183,449,450],{"class":237},"get",[183,452,297],{"class":193},[183,454,455],{"class":200},"'Authorization'",[183,457,458],{"class":193},"))) {\n",[183,460,462,465,468,471,473,476,479,481,484,487],{"class":185,"line":461},17,[183,463,464],{"class":189},"    return",[183,466,467],{"class":193}," res.",[183,469,470],{"class":237},"status",[183,472,297],{"class":193},[183,474,475],{"class":230},"401",[183,477,478],{"class":193},").",[183,480,256],{"class":237},[183,482,483],{"class":193},"({ success: ",[183,485,486],{"class":230},"false",[183,488,489],{"class":193}," })\n",[183,491,493],{"class":185,"line":492},18,[183,494,495],{"class":193},"  }\n",[183,497,499],{"class":185,"line":498},19,[183,500,221],{"emptyLinePlaceholder":220},[183,502,504,507,509,511,514],{"class":185,"line":503},20,[183,505,506],{"class":193},"  res.",[183,508,256],{"class":237},[183,510,483],{"class":193},[183,512,513],{"class":230},"true",[183,515,489],{"class":193},[183,517,519],{"class":185,"line":518},21,[183,520,221],{"emptyLinePlaceholder":220},[183,522,524],{"class":185,"line":523},22,[183,525,527],{"class":526},"sJ8bj","  \u002F\u002F Proses setelah membalas\n",[183,529,531,533,536,539,541,544,547,550],{"class":185,"line":530},23,[183,532,310],{"class":189},[183,534,535],{"class":193}," { ",[183,537,538],{"class":230},"event",[183,540,80],{"class":193},[183,542,543],{"class":230},"message",[183,545,546],{"class":193}," } ",[183,548,549],{"class":189},"=",[183,551,552],{"class":193}," req.body\n",[183,554,556,559,562],{"class":185,"line":555},24,[183,557,558],{"class":193},"  console.",[183,560,561],{"class":237},"log",[183,563,564],{"class":193},"(event, message.id)\n",[183,566,568],{"class":185,"line":567},25,[183,569,570],{"class":193},"})\n",[183,572,574],{"class":185,"line":573},26,[183,575,221],{"emptyLinePlaceholder":220},[183,577,579,581,584,586,589],{"class":185,"line":578},27,[183,580,247],{"class":193},[183,582,583],{"class":237},"listen",[183,585,297],{"class":193},[183,587,588],{"class":230},"3000",[183,590,332],{"class":193},[169,592,594],{"id":593},"php","PHP",[174,596,599],{"className":597,"code":598,"language":593,"meta":179,"style":179},"language-php shiki shiki-themes github-light github-dark","\u003C?php\n$secret = getenv('CSKU_SECRET');\n$auth = $_SERVER['HTTP_AUTHORIZATION'] ?? '';\n\nheader('Content-Type: application\u002Fjson');\n\nif (!hash_equals($secret, $auth)) {\n    http_response_code(401);\n    echo json_encode(['success' => false]);\n    exit;\n}\n\n$payload = json_decode(file_get_contents('php:\u002F\u002Finput'), true);\n\n\u002F\u002F Simpan ke antrean, lalu balas\necho json_encode(['success' => true]);\n",[14,600,601,609,627,651,655,666,670,685,696,719,726,730,734,761,765,770],{"__ignoreMap":179},[183,602,603,606],{"class":185,"line":186},[183,604,605],{"class":189},"\u003C?",[183,607,608],{"class":230},"php\n",[183,610,611,614,616,619,621,624],{"class":185,"line":204},[183,612,613],{"class":193},"$secret ",[183,615,549],{"class":189},[183,617,618],{"class":230}," getenv",[183,620,297],{"class":193},[183,622,623],{"class":200},"'CSKU_SECRET'",[183,625,626],{"class":193},");\n",[183,628,629,632,634,637,640,643,646,648],{"class":185,"line":217},[183,630,631],{"class":193},"$auth ",[183,633,549],{"class":189},[183,635,636],{"class":193}," $_SERVER[",[183,638,639],{"class":200},"'HTTP_AUTHORIZATION'",[183,641,642],{"class":193},"] ",[183,644,645],{"class":189},"??",[183,647,329],{"class":200},[183,649,650],{"class":193},";\n",[183,652,653],{"class":185,"line":224},[183,654,221],{"emptyLinePlaceholder":220},[183,656,657,659,661,664],{"class":185,"line":244},[183,658,301],{"class":230},[183,660,297],{"class":193},[183,662,663],{"class":200},"'Content-Type: application\u002Fjson'",[183,665,626],{"class":193},[183,667,668],{"class":185,"line":262},[183,669,221],{"emptyLinePlaceholder":220},[183,671,672,675,677,679,682],{"class":185,"line":267},[183,673,674],{"class":189},"if",[183,676,438],{"class":193},[183,678,441],{"class":189},[183,680,681],{"class":230},"hash_equals",[183,683,684],{"class":193},"($secret, $auth)) {\n",[183,686,687,690,692,694],{"class":185,"line":283},[183,688,689],{"class":230},"    http_response_code",[183,691,297],{"class":193},[183,693,475],{"class":230},[183,695,626],{"class":193},[183,697,698,701,704,707,710,713,716],{"class":185,"line":288},[183,699,700],{"class":230},"    echo",[183,702,703],{"class":230}," json_encode",[183,705,706],{"class":193},"([",[183,708,709],{"class":200},"'success'",[183,711,712],{"class":189}," =>",[183,714,715],{"class":230}," false",[183,717,718],{"class":193},"]);\n",[183,720,721,724],{"class":185,"line":307},[183,722,723],{"class":189},"    exit",[183,725,650],{"class":193},[183,727,728],{"class":185,"line":335},[183,729,391],{"class":193},[183,731,732],{"class":185,"line":356},[183,733,221],{"emptyLinePlaceholder":220},[183,735,736,739,741,744,746,749,751,754,757,759],{"class":185,"line":388},[183,737,738],{"class":193},"$payload ",[183,740,549],{"class":189},[183,742,743],{"class":230}," json_decode",[183,745,297],{"class":193},[183,747,748],{"class":230},"file_get_contents",[183,750,297],{"class":193},[183,752,753],{"class":200},"'php:\u002F\u002Finput'",[183,755,756],{"class":193},"), ",[183,758,513],{"class":230},[183,760,626],{"class":193},[183,762,763],{"class":185,"line":394},[183,764,221],{"emptyLinePlaceholder":220},[183,766,767],{"class":185,"line":399},[183,768,769],{"class":526},"\u002F\u002F Simpan ke antrean, lalu balas\n",[183,771,772,775,777,779,781,783,786],{"class":185,"line":432},[183,773,774],{"class":230},"echo",[183,776,703],{"class":230},[183,778,706],{"class":193},[183,780,709],{"class":200},[183,782,712],{"class":189},[183,784,785],{"class":230}," true",[183,787,718],{"class":193},[124,789,792],{"title":790,"type":791},"Header Authorization di Apache","tip",[10,793,794,795,797,798,801,802,805,806,23],{},"Beberapa konfigurasi Apache + PHP-FPM tidak meneruskan header ",[14,796,64],{},". Jika ",[14,799,800],{},"$_SERVER['HTTP_AUTHORIZATION']"," kosong, tambahkan ",[14,803,804],{},"SetEnvIf Authorization \"(.*)\" HTTP_AUTHORIZATION=$1"," di ",[14,807,808],{},".htaccess",[169,810,812],{"id":811},"python-flask","Python (Flask)",[174,814,818],{"className":815,"code":816,"language":817,"meta":179,"style":179},"language-python shiki shiki-themes github-light github-dark","import hmac\nimport os\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\nSECRET = os.environ[\"CSKU_SECRET\"]\n\n@app.post(\"\u002Fcsku\u002Fwebhook\")\ndef csku_webhook():\n    auth = request.headers.get(\"Authorization\", \"\")\n    if not hmac.compare_digest(auth, SECRET):\n        return jsonify(success=False), 401\n\n    payload = request.get_json(silent=True) or {}\n    # Kirim ke antrean \u002F background job\n    print(payload.get(\"event\"), payload.get(\"message\", {}).get(\"id\"))\n\n    return jsonify(success=True)\n","python",[14,819,820,827,834,846,850,865,880,884,896,907,927,943,963,967,993,998,1024,1028],{"__ignoreMap":179},[183,821,822,824],{"class":185,"line":186},[183,823,190],{"class":189},[183,825,826],{"class":193}," hmac\n",[183,828,829,831],{"class":185,"line":204},[183,830,190],{"class":189},[183,832,833],{"class":193}," os\n",[183,835,836,838,841,843],{"class":185,"line":217},[183,837,197],{"class":189},[183,839,840],{"class":193}," flask ",[183,842,190],{"class":189},[183,844,845],{"class":193}," Flask, request, jsonify\n",[183,847,848],{"class":185,"line":224},[183,849,221],{"emptyLinePlaceholder":220},[183,851,852,855,857,860,863],{"class":185,"line":244},[183,853,854],{"class":193},"app ",[183,856,549],{"class":189},[183,858,859],{"class":193}," Flask(",[183,861,862],{"class":230},"__name__",[183,864,332],{"class":193},[183,866,867,869,871,874,877],{"class":185,"line":262},[183,868,351],{"class":230},[183,870,234],{"class":189},[183,872,873],{"class":193}," os.environ[",[183,875,876],{"class":200},"\"CSKU_SECRET\"",[183,878,879],{"class":193},"]\n",[183,881,882],{"class":185,"line":267},[183,883,221],{"emptyLinePlaceholder":220},[183,885,886,889,891,894],{"class":185,"line":283},[183,887,888],{"class":237},"@app.post",[183,890,297],{"class":193},[183,892,893],{"class":200},"\"\u002Fcsku\u002Fwebhook\"",[183,895,332],{"class":193},[183,897,898,901,904],{"class":185,"line":288},[183,899,900],{"class":189},"def",[183,902,903],{"class":237}," csku_webhook",[183,905,906],{"class":193},"():\n",[183,908,909,912,914,917,920,922,925],{"class":185,"line":307},[183,910,911],{"class":193},"    auth ",[183,913,549],{"class":189},[183,915,916],{"class":193}," request.headers.get(",[183,918,919],{"class":200},"\"Authorization\"",[183,921,80],{"class":193},[183,923,924],{"class":200},"\"\"",[183,926,332],{"class":193},[183,928,929,932,935,938,940],{"class":185,"line":335},[183,930,931],{"class":189},"    if",[183,933,934],{"class":189}," not",[183,936,937],{"class":193}," hmac.compare_digest(auth, ",[183,939,351],{"class":230},[183,941,942],{"class":193},"):\n",[183,944,945,948,951,953,955,958,960],{"class":185,"line":356},[183,946,947],{"class":189},"        return",[183,949,950],{"class":193}," jsonify(",[183,952,162],{"class":300},[183,954,549],{"class":189},[183,956,957],{"class":230},"False",[183,959,756],{"class":193},[183,961,962],{"class":230},"401\n",[183,964,965],{"class":185,"line":388},[183,966,221],{"emptyLinePlaceholder":220},[183,968,969,972,974,977,980,982,985,987,990],{"class":185,"line":394},[183,970,971],{"class":193},"    payload ",[183,973,549],{"class":189},[183,975,976],{"class":193}," request.get_json(",[183,978,979],{"class":300},"silent",[183,981,549],{"class":189},[183,983,984],{"class":230},"True",[183,986,423],{"class":193},[183,988,989],{"class":189},"or",[183,991,992],{"class":193}," {}\n",[183,994,995],{"class":185,"line":399},[183,996,997],{"class":526},"    # Kirim ke antrean \u002F background job\n",[183,999,1000,1003,1006,1009,1012,1015,1018,1021],{"class":185,"line":432},[183,1001,1002],{"class":230},"    print",[183,1004,1005],{"class":193},"(payload.get(",[183,1007,1008],{"class":200},"\"event\"",[183,1010,1011],{"class":193},"), payload.get(",[183,1013,1014],{"class":200},"\"message\"",[183,1016,1017],{"class":193},", {}).get(",[183,1019,1020],{"class":200},"\"id\"",[183,1022,1023],{"class":193},"))\n",[183,1025,1026],{"class":185,"line":461},[183,1027,221],{"emptyLinePlaceholder":220},[183,1029,1030,1032,1034,1036,1038,1040],{"class":185,"line":492},[183,1031,464],{"class":189},[183,1033,950],{"class":193},[183,1035,162],{"class":300},[183,1037,549],{"class":189},[183,1039,984],{"class":230},[183,1041,332],{"class":193},[169,1043,1045],{"id":1044},"go","Go",[174,1047,1050],{"className":1048,"code":1049,"language":1044,"meta":179,"style":179},"language-go shiki shiki-themes github-light github-dark","package main\n\nimport (\n    \"crypto\u002Fsubtle\"\n    \"encoding\u002Fjson\"\n    \"net\u002Fhttp\"\n    \"os\"\n)\n\nvar secret = []byte(os.Getenv(\"CSKU_SECRET\"))\n\nfunc webhook(w http.ResponseWriter, r *http.Request) {\n    w.Header().Set(\"Content-Type\", \"application\u002Fjson\")\n\n    auth := []byte(r.Header.Get(\"Authorization\"))\n    if subtle.ConstantTimeCompare(auth, secret) != 1 {\n        w.WriteHeader(http.StatusUnauthorized)\n        w.Write([]byte(`{\"success\":false}`))\n        return\n    }\n\n    var payload map[string]any\n    if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {\n        w.Write([]byte(`{\"success\":false}`))\n        return\n    }\n\n    \u002F\u002F Proses di goroutine \u002F antrean\n    w.Write([]byte(`{\"success\":true}`))\n}\n\nfunc main() {\n    http.HandleFunc(\"\u002Fcsku\u002Fwebhook\", webhook)\n    http.ListenAndServe(\":3000\", nil)\n}\n",[14,1051,1052,1060,1064,1071,1082,1091,1100,1109,1113,1117,1145,1149,1187,1213,1217,1240,1261,1272,1291,1296,1301,1305,1328,1364,1380,1384,1388,1392,1398,1416,1421,1426,1437,1453,1473],{"__ignoreMap":179},[183,1053,1054,1057],{"class":185,"line":186},[183,1055,1056],{"class":189},"package",[183,1058,1059],{"class":237}," main\n",[183,1061,1062],{"class":185,"line":204},[183,1063,221],{"emptyLinePlaceholder":220},[183,1065,1066,1068],{"class":185,"line":217},[183,1067,190],{"class":189},[183,1069,1070],{"class":193}," (\n",[183,1072,1073,1076,1079],{"class":185,"line":224},[183,1074,1075],{"class":200},"    \"",[183,1077,1078],{"class":237},"crypto\u002Fsubtle",[183,1080,1081],{"class":200},"\"\n",[183,1083,1084,1086,1089],{"class":185,"line":244},[183,1085,1075],{"class":200},[183,1087,1088],{"class":237},"encoding\u002Fjson",[183,1090,1081],{"class":200},[183,1092,1093,1095,1098],{"class":185,"line":262},[183,1094,1075],{"class":200},[183,1096,1097],{"class":237},"net\u002Fhttp",[183,1099,1081],{"class":200},[183,1101,1102,1104,1107],{"class":185,"line":267},[183,1103,1075],{"class":200},[183,1105,1106],{"class":237},"os",[183,1108,1081],{"class":200},[183,1110,1111],{"class":185,"line":283},[183,1112,332],{"class":193},[183,1114,1115],{"class":185,"line":288},[183,1116,221],{"emptyLinePlaceholder":220},[183,1118,1119,1122,1125,1127,1130,1133,1136,1139,1141,1143],{"class":185,"line":307},[183,1120,1121],{"class":189},"var",[183,1123,1124],{"class":193}," secret ",[183,1126,549],{"class":189},[183,1128,1129],{"class":193}," []",[183,1131,1132],{"class":189},"byte",[183,1134,1135],{"class":193},"(os.",[183,1137,1138],{"class":237},"Getenv",[183,1140,297],{"class":193},[183,1142,876],{"class":200},[183,1144,1023],{"class":193},[183,1146,1147],{"class":185,"line":335},[183,1148,221],{"emptyLinePlaceholder":220},[183,1150,1151,1154,1157,1159,1162,1165,1167,1170,1172,1175,1178,1180,1182,1185],{"class":185,"line":356},[183,1152,1153],{"class":189},"func",[183,1155,1156],{"class":237}," webhook",[183,1158,297],{"class":193},[183,1160,1161],{"class":300},"w",[183,1163,1164],{"class":237}," http",[183,1166,23],{"class":193},[183,1168,1169],{"class":237},"ResponseWriter",[183,1171,80],{"class":193},[183,1173,1174],{"class":300},"r",[183,1176,1177],{"class":189}," *",[183,1179,79],{"class":237},[183,1181,23],{"class":193},[183,1183,1184],{"class":237},"Request",[183,1186,304],{"class":193},[183,1188,1189,1192,1195,1198,1201,1203,1206,1208,1211],{"class":185,"line":388},[183,1190,1191],{"class":193},"    w.",[183,1193,1194],{"class":237},"Header",[183,1196,1197],{"class":193},"().",[183,1199,1200],{"class":237},"Set",[183,1202,297],{"class":193},[183,1204,1205],{"class":200},"\"Content-Type\"",[183,1207,80],{"class":193},[183,1209,1210],{"class":200},"\"application\u002Fjson\"",[183,1212,332],{"class":193},[183,1214,1215],{"class":185,"line":394},[183,1216,221],{"emptyLinePlaceholder":220},[183,1218,1219,1221,1224,1226,1228,1231,1234,1236,1238],{"class":185,"line":399},[183,1220,911],{"class":193},[183,1222,1223],{"class":189},":=",[183,1225,1129],{"class":193},[183,1227,1132],{"class":189},[183,1229,1230],{"class":193},"(r.Header.",[183,1232,1233],{"class":237},"Get",[183,1235,297],{"class":193},[183,1237,919],{"class":200},[183,1239,1023],{"class":193},[183,1241,1242,1244,1247,1250,1253,1256,1259],{"class":185,"line":432},[183,1243,931],{"class":189},[183,1245,1246],{"class":193}," subtle.",[183,1248,1249],{"class":237},"ConstantTimeCompare",[183,1251,1252],{"class":193},"(auth, secret) ",[183,1254,1255],{"class":189},"!=",[183,1257,1258],{"class":230}," 1",[183,1260,429],{"class":193},[183,1262,1263,1266,1269],{"class":185,"line":461},[183,1264,1265],{"class":193},"        w.",[183,1267,1268],{"class":237},"WriteHeader",[183,1270,1271],{"class":193},"(http.StatusUnauthorized)\n",[183,1273,1274,1276,1279,1282,1284,1286,1289],{"class":185,"line":492},[183,1275,1265],{"class":193},[183,1277,1278],{"class":237},"Write",[183,1280,1281],{"class":193},"([]",[183,1283,1132],{"class":189},[183,1285,297],{"class":193},[183,1287,1288],{"class":200},"`{\"success\":false}`",[183,1290,1023],{"class":193},[183,1292,1293],{"class":185,"line":498},[183,1294,1295],{"class":189},"        return\n",[183,1297,1298],{"class":185,"line":503},[183,1299,1300],{"class":193},"    }\n",[183,1302,1303],{"class":185,"line":518},[183,1304,221],{"emptyLinePlaceholder":220},[183,1306,1307,1310,1313,1316,1319,1322,1325],{"class":185,"line":523},[183,1308,1309],{"class":189},"    var",[183,1311,1312],{"class":193}," payload ",[183,1314,1315],{"class":189},"map",[183,1317,1318],{"class":193},"[",[183,1320,1321],{"class":189},"string",[183,1323,1324],{"class":193},"]",[183,1326,1327],{"class":237},"any\n",[183,1329,1330,1332,1335,1337,1340,1343,1346,1349,1351,1354,1357,1359,1362],{"class":185,"line":530},[183,1331,931],{"class":189},[183,1333,1334],{"class":193}," err ",[183,1336,1223],{"class":189},[183,1338,1339],{"class":193}," json.",[183,1341,1342],{"class":237},"NewDecoder",[183,1344,1345],{"class":193},"(r.Body).",[183,1347,1348],{"class":237},"Decode",[183,1350,297],{"class":193},[183,1352,1353],{"class":189},"&",[183,1355,1356],{"class":193},"payload); err ",[183,1358,1255],{"class":189},[183,1360,1361],{"class":230}," nil",[183,1363,429],{"class":193},[183,1365,1366,1368,1370,1372,1374,1376,1378],{"class":185,"line":555},[183,1367,1265],{"class":193},[183,1369,1278],{"class":237},[183,1371,1281],{"class":193},[183,1373,1132],{"class":189},[183,1375,297],{"class":193},[183,1377,1288],{"class":200},[183,1379,1023],{"class":193},[183,1381,1382],{"class":185,"line":567},[183,1383,1295],{"class":189},[183,1385,1386],{"class":185,"line":573},[183,1387,1300],{"class":193},[183,1389,1390],{"class":185,"line":578},[183,1391,221],{"emptyLinePlaceholder":220},[183,1393,1395],{"class":185,"line":1394},28,[183,1396,1397],{"class":526},"    \u002F\u002F Proses di goroutine \u002F antrean\n",[183,1399,1401,1403,1405,1407,1409,1411,1414],{"class":185,"line":1400},29,[183,1402,1191],{"class":193},[183,1404,1278],{"class":237},[183,1406,1281],{"class":193},[183,1408,1132],{"class":189},[183,1410,297],{"class":193},[183,1412,1413],{"class":200},"`{\"success\":true}`",[183,1415,1023],{"class":193},[183,1417,1419],{"class":185,"line":1418},30,[183,1420,391],{"class":193},[183,1422,1424],{"class":185,"line":1423},31,[183,1425,221],{"emptyLinePlaceholder":220},[183,1427,1429,1431,1434],{"class":185,"line":1428},32,[183,1430,1153],{"class":189},[183,1432,1433],{"class":237}," main",[183,1435,1436],{"class":193},"() {\n",[183,1438,1440,1443,1446,1448,1450],{"class":185,"line":1439},33,[183,1441,1442],{"class":193},"    http.",[183,1444,1445],{"class":237},"HandleFunc",[183,1447,297],{"class":193},[183,1449,893],{"class":200},[183,1451,1452],{"class":193},", webhook)\n",[183,1454,1456,1458,1461,1463,1466,1468,1471],{"class":185,"line":1455},34,[183,1457,1442],{"class":193},[183,1459,1460],{"class":237},"ListenAndServe",[183,1462,297],{"class":193},[183,1464,1465],{"class":200},"\":3000\"",[183,1467,80],{"class":193},[183,1469,1470],{"class":230},"nil",[183,1472,332],{"class":193},[183,1474,1476],{"class":185,"line":1475},35,[183,1477,391],{"class":193},[25,1479,1481],{"id":1480},"uji-saat-development","Uji saat development",[10,1483,1484],{},"Belum ada tombol \"kirim webhook uji\". Untuk mencoba:",[90,1486,1487,1518,1529],{},[33,1488,1489,1490],{},"Pakai URL publik sementara:\n",[30,1491,1492,1504],{},[33,1493,1494,1500,1501,1503],{},[19,1495,1499],{"href":1496,"rel":1497},"https:\u002F\u002Fwebhook.site",[1498],"nofollow","webhook.site"," untuk melihat isi request tanpa menulis kode. Ingat: webhook.site tidak membalas ",[14,1502,155],{}," secara default, jadi CSKU akan mencoba ulang.",[33,1505,1506,1507,1510,1511,1514,1515,1517],{},"Tunnel ke server lokal, misalnya ",[14,1508,1509],{},"ngrok http 3000"," atau ",[14,1512,1513],{},"cloudflared tunnel --url http:\u002F\u002Flocalhost:3000",". Daftarkan URL ",[14,1516,75],{}," yang diberikan tunnel.",[33,1519,1520,1521,1524,1525,1528],{},"Picu event sungguhan: kirim pesan ke salah satu channel Anda (misalnya lewat Webchat atau WhatsApp). Anda akan menerima ",[14,1522,1523],{},"channel.message_in",", lalu ",[14,1526,1527],{},"ai.message_generated"," jika AI agent aktif.",[33,1530,1531,1532,1535,1536,23],{},"Balas dari menu ",[37,1533,1534],{},"Chat"," di dashboard untuk menerima ",[14,1537,1538],{},"agent.message_out",[124,1540,1543],{"title":1541,"type":1542},"Ganti URL setelah selesai","warning",[10,1544,1545],{},"URL tunnel biasanya berubah setiap kali dijalankan ulang. Daftarkan URL produksi sebelum go-live, agar event tidak terkirim ke alamat yang sudah mati.",[25,1547,1549],{"id":1548},"reset-webhook","Reset webhook",[10,1551,94,1552,1554,1555,1558],{},[37,1553,97],{},", klik ",[37,1556,1557],{},"Reset",", lalu konfirmasi. URL dihapus dan CSKU berhenti mengirim event. Untuk mengaktifkan lagi, daftarkan URL baru dengan OTP.",[25,1560,1562],{"id":1561},"selanjutnya","Selanjutnya",[1564,1565,1566,1573],"cards",{},[1567,1568,1570],"card",{"icon":1569,"title":134,"to":133},"tabler:list-details",[10,1571,1572],{},"Daftar event dan isi lengkap payload.",[1567,1574,1576],{"icon":1575,"title":167,"to":166},"tabler:shield-check",[10,1577,1578],{},"Verifikasi request, aturan sukses, dan jadwal retry.",[1580,1581,1582],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":179,"searchDepth":217,"depth":217,"links":1584},[1585,1586,1587,1593,1594,1595],{"id":27,"depth":204,"text":28},{"id":87,"depth":204,"text":88},{"id":137,"depth":204,"text":138,"children":1588},[1589,1590,1591,1592],{"id":171,"depth":217,"text":172},{"id":593,"depth":217,"text":594},{"id":811,"depth":217,"text":812},{"id":1044,"depth":217,"text":1045},{"id":1480,"depth":204,"text":1481},{"id":1548,"depth":204,"text":1549},{"id":1561,"depth":204,"text":1562},"Daftarkan URL webhook di dashboard dan siapkan server yang menerima event dari CSKU.",null,"md",{},"\u002Fwebhook\u002Fsetup",{"title":5,"description":1596},"webhook\u002Fsetup","zvD6UrT0Gp62hXRjQFC1Bhj2cXT1qmiogtY_IgAS0sY",1791957694417]