[{"data":1,"prerenderedAt":149},["ShallowReactive",2],{"pseo:tutorials:follow-channels:php":3,"highlight:tutorial:follow-channels:php":138},{"ban_risk":4,"ban_risk_note":5,"deploy_targets":6,"errors":11,"faqs":12,"feature":23,"full_script":27,"gotchas":31,"intro_note":37,"language":38,"pitfalls":42,"prerequisites":46,"related":49,"seo":76,"siblings":95,"step_summary":102,"steps":103,"tier":131,"url":89,"webhook_receiver":132},"low","Following a handful of channels is what a normal account does. Following hundreds in a short period, or scraping a channel's entire history in a tight loop, is not, and both are easy for an abuse system to spot. Follow deliberately, page history at a human pace, and respect the publisher's terms about reusing their content.",[7,8,9,10],"Shared hosting or cPanel with a single public webhook.php endpoint","A VPS managed by Laravel Forge or Ploi, with the sender on a supervisor-managed queue worker","Google Cloud Run using the official php:8.3-cli image","Any Heroku-style buildpack platform for the Slim receiver",[],[13,17,20],{"a":14,"q":15,"source":16},"Only if you have its invite link, which is how private channels are shared in the first place. There is no way to discover a private channel through search, and resolving a code you were not given will simply fail. Treat a channel link like any other credential.","Can I follow a private channel?","features.json",{"a":18,"q":19,"source":16},"New posts from channels the linked number follows arrive as message events keyed to the channel id, so yes for anything published after you follow. History is a separate problem: page back through the messages endpoint once, then rely on the webhook for everything after that.","Do I get every post as a webhook?",{"a":21,"q":22,"source":16},"That is a copyright and terms question rather than an API one, and the answer depends on the publisher and your jurisdiction. Reading a public channel to trigger your own workflow is uncontroversial; republishing someone else's posts wholesale is a decision to take with your own legal advice.","Is it legal to republish what I read?",{"name":24,"slug":25,"url":26},"Follow Channels","follow-channels","\u002Fwhatsapp-api\u002Ffollow-channels\u002F",{"code":28,"filename":29,"lang":30},"\u003C?php\n\u002F\u002F Follow Channels with the Wapito WhatsApp API.\n\u002F\u002F\n\u002F\u002F Search or resolve a link, verify it is the right channel, page back through the history, then handle new posts from the webhook.\n\u002F\u002F\n\u002F\u002F Run it with:\n\u002F\u002F   export WAPITO_TOKEN=\"wpt_...\"\n\u002F\u002F   php follow-channels.php\nrequire __DIR__ . '\u002Fvendor\u002Fautoload.php';\n\n$baseUrl = 'https:\u002F\u002Fapi.wapito.com\u002Fv1';\n$token = getenv('WAPITO_TOKEN');\n\n\u002F\u002F --- Search the directory ---\n$client = new \\GuzzleHttp\\Client();\n\n$response = $client->request('GET', $baseUrl . '\u002Fnewsletters\u002Ffind?q=release%20notes&country=GB&count=50', [\n  'headers' => [\n    'Authorization' => 'Bearer ' . $token,\n  ],\n]);\n\necho $response->getBody();\n\n\u002F\u002F --- Resolve an invite link ---\n$client = new \\GuzzleHttp\\Client();\n\n$response = $client->request('GET', $baseUrl . '\u002Fnewsletters\u002Finvite\u002F0029VaAbCdEfGhIjKlMnOp', [\n  'headers' => [\n    'Authorization' => 'Bearer ' . $token,\n  ],\n]);\n\necho $response->getBody();\n\n\u002F\u002F --- Read what has been published ---\n$client = new \\GuzzleHttp\\Client();\n\n$response = $client->request('GET', $baseUrl . '\u002Fnewsletters\u002F120363099887766554@newsletter\u002Fmessages?count=50&offset=0', [\n  'headers' => [\n    'Authorization' => 'Bearer ' . $token,\n  ],\n]);\n\necho $response->getBody();\n\n","follow-channels.php","php",[32,33,34,35,36],"Guzzle throws a ClientException on a 4xx by default, and the useful part - the API error code - is inside $e->getResponse()->getBody(). Either catch it and decode the body, or pass http_errors => false and branch on the status yourself.","json_decode($raw, true) turns an empty JSON object into an empty PHP array, so is_array() tells you nothing about whether a field arrived. Check array_key_exists() before you read a webhook field.","PHP running behind Apache or shared hosting often gets a request body that has already been consumed. Read the raw webhook body with file_get_contents(\"php:\u002F\u002Finput\") exactly once and pass it around; a second read returns an empty string and signature checks fail.","Integer ids overflow on 32-bit builds. WhatsApp group ids and timestamps are strings in Wapito responses - keep them as strings and never cast with (int).","The default max_execution_time of 30 seconds will kill a bulk loop halfway. Run bulk sends from the CLI SAPI (php send.php), not from a web request.","With PHP the follow-and-bridge job is a set of Guzzle GETs from a CLI script plus a Slim route for new posts. The paged history read is a do-while over offsets, the processed ids live in a table rather than in a PHP array that dies with the process, and the resolution of an invite code is the step that keeps a customer from following a lookalike.",{"family":39,"name":40,"slug":30,"url":41},"scripting","PHP","\u002Fwhatsapp-bot\u002Fphp\u002F",[43,44,45],"Building the search URL with string concatenation and no rawurlencode sends a term with spaces that the API rejects; pass the query option to Guzzle instead, which also encodes the ampersand a channel name may contain.","A processed-ids array kept in a PHP session or a static variable is gone at the end of the request, and the bridge reposts the archive; use a table with a unique index on the message id and let the database refuse the duplicate.","A do-while that reads $data['count'] as the page size and stops when it is smaller than the request's count ends one page early when the API caps the page below what you asked for; loop on the offset against total instead, and treat a missing total as one more page to fetch.",[47,48],"composer require guzzlehttp\u002Fguzzle","getenv('WAPITO_TOKEN')",{"language_hub":41,"operations":50,"pillar":26,"same_language_features":60},[51,54,57],{"title":52,"url":53},"GET \u002Fnewsletters\u002Ffind","\u002Fdocs\u002Fapi\u002Fnewsletters\u002Ffind-newsletters\u002F",{"title":55,"url":56},"GET \u002Fnewsletters\u002Finvite\u002F{code}","\u002Fdocs\u002Fapi\u002Fnewsletters\u002Fget-newsletter-by-invite\u002F",{"title":58,"url":59},"GET \u002Fnewsletters\u002F{id}\u002Fmessages","\u002Fdocs\u002Fapi\u002Fnewsletters\u002Flist-newsletter-messages\u002F",[61,64,67,70,73],{"title":62,"url":63},"Create Group","\u002Fwhatsapp-api\u002Fcreate-group\u002Fphp\u002F",{"title":65,"url":66},"Group Participants","\u002Fwhatsapp-api\u002Fgroup-participants\u002Fphp\u002F",{"title":68,"url":69},"Group Admins","\u002Fwhatsapp-api\u002Fgroup-admins\u002Fphp\u002F",{"title":71,"url":72},"Group Invite Link","\u002Fwhatsapp-api\u002Fgroup-invite-link\u002Fphp\u002F",{"title":74,"url":75},"Group Settings","\u002Fwhatsapp-api\u002Fgroup-settings\u002Fphp\u002F",{"breadcrumb":77,"canonical":90,"description":91,"h1":92,"lastmod":93,"title":94},[78,81,84,87,88],{"name":79,"url":80},"Home","\u002F",{"name":82,"url":83},"WhatsApp API","\u002Fwhatsapp-api\u002F",{"name":85,"url":86},"Channels","\u002Fwhatsapp-api\u002Fchannels\u002F",{"name":24,"url":26},{"name":40,"url":89},"\u002Fwhatsapp-api\u002Ffollow-channels\u002Fphp\u002F","https:\u002F\u002Fwapito.com\u002Fwhatsapp-api\u002Ffollow-channels\u002Fphp\u002F","How to follow a channel in PHP with the Wapito WhatsApp API. 4 steps with runnable code, a Slim 4 webhook receiver and the errors to expect.","How to follow a channel in PHP with the Wapito WhatsApp API","2026-09-17","Follow Channels in PHP (WhatsApp API Tutorial) | Wapito",[96,99],{"title":97,"url":98},"Python","\u002Fwhatsapp-api\u002Ffollow-channels\u002Fpython\u002F",{"title":100,"url":101},"Node.js","\u002Fwhatsapp-api\u002Ffollow-channels\u002Fnodejs\u002F","Search or resolve a link, verify it is the right channel, page back through the history, then handle new posts from the webhook.",[104,112,119,126],{"body":105,"note":106,"operationId":107,"operation_url":53,"snippet":108,"title":110,"webhook":111},"Search returns public channels matching a term. Treat the results as candidates rather than as matches: names are not unique and a lookalike channel is a real risk when you are following on a customer's behalf.","In PHP search with $client->request('GET', $url, ['query' => ['q' => $term]]) so Guzzle encodes the term, and treat the decoded list under 'newsletters' as candidates; names repeat, so pick by an explicit rule on subscribers_count, the verified flag or a known id. Log every candidate you rejected and why, because the rule will need tuning.","findNewsletters",{"code":109,"lang":30},"\u003C?php\n\n$client = new \\GuzzleHttp\\Client();\n\n$response = $client->request('GET', 'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fnewsletters\u002Ffind?q=release%20notes&country=GB&count=50', [\n  'headers' => [\n    'Authorization' => 'Bearer wpt_YOUR_TOKEN',\n  ],\n]);\n\necho $response->getBody();","Search the directory",null,{"body":113,"note":114,"operationId":115,"operation_url":56,"snippet":116,"title":118,"webhook":111},"If you already have a channel link, resolve its code to get the name, description and follower count before doing anything else. This is how you confirm you have the official channel and not an imitation.","In PHP resolve a link with a GET on \u002Fnewsletters\u002Finvite\u002F . rawurlencode($code) and compare $data['name'] and $data['subscribers_count'] with the values you expect before following. Catch GuzzleHttp\\Exception\\ClientException for a 404: an expired link is an ordinary answer, and the invite code is the part after the last slash of the public link.","getNewsletterByInvite",{"code":117,"lang":30},"\u003C?php\n\n$client = new \\GuzzleHttp\\Client();\n\n$response = $client->request('GET', 'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fnewsletters\u002Finvite\u002F0029VaAbCdEfGhIjKlMnOp', [\n  'headers' => [\n    'Authorization' => 'Bearer wpt_YOUR_TOKEN',\n  ],\n]);\n\necho $response->getBody();","Resolve an invite link",{"body":120,"note":121,"operationId":122,"operation_url":59,"snippet":123,"title":125,"webhook":111},"Page back through the channel's posts to seed your own archive or to catch up after an outage. Store the message ids so a re-run does not process the same post twice.","In PHP page the history with a do-while that adds count to the offset until it reaches $data['total'], inserting each message id into a table with INSERT IGNORE or an ON CONFLICT clause so a re-run skips what it already stored. Keep the newest id in a settings row and page forward from it next time rather than from zero.","listNewsletterMessages",{"code":124,"lang":30},"\u003C?php\n\n$client = new \\GuzzleHttp\\Client();\n\n$response = $client->request('GET', 'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fnewsletters\u002F120363099887766554@newsletter\u002Fmessages?count=50&offset=0', [\n  'headers' => [\n    'Authorization' => 'Bearer wpt_YOUR_TOKEN',\n  ],\n]);\n\necho $response->getBody();","Read what has been published",{"body":127,"note":128,"operationId":111,"operation_url":111,"snippet":111,"title":129,"webhook":130},"New posts arrive as message events from the channel id. Route them by that id so a bridge to another system knows which feed a post belongs to.","In PHP the Slim handler decodes the messages event and reads the sender id from $payload['data']; look it up in an array from id to destination and forward from a queued job after returning the 200. The handler itself must not call the destination system, and the job checks the ids table before posting so a redelivery is a no-op.","React to new posts","messages","t2",{"code":133,"events":134,"filename":135,"framework":136,"install":137,"lang":30},"\u003C?php\n\u002F\u002F public\u002Fwebhook.php - run with: php -S 0.0.0.0:8000 -t public\nrequire __DIR__ . '\u002F..\u002Fvendor\u002Fautoload.php';\n\nuse Psr\\Http\\Message\\ResponseInterface as Response;\nuse Psr\\Http\\Message\\ServerRequestInterface as Request;\nuse Slim\\Factory\\AppFactory;\n\n$secret = getenv('WAPITO_WEBHOOK_SECRET');\n$events = ['messages'];\n\n\u002F** Checks the X-Wapito-Signature header: t=\u003Cms>,v1=\u003Chex hmac-sha256>. *\u002F\nfunction wapito_verify(string $raw, ?string $header, string $secret): bool\n{\n    if (!$header) {\n        return false;\n    }\n    $parts = [];\n    foreach (explode(',', $header) as $pair) {\n        [$k, $v] = array_pad(explode('=', $pair, 2), 2, null);\n        $parts[$k] = $v;\n    }\n    if (empty($parts['t']) || empty($parts['v1'])) {\n        return false;\n    }\n    if (abs((int) (microtime(true) * 1000) - (int) $parts['t']) > 300000) {\n        return false; \u002F\u002F 5 minute clock skew\n    }\n    $expected = hash_hmac('sha256', $parts['t'] . '.' . $raw, $secret);\n    return hash_equals($expected, $parts['v1']);\n}\n\n$app = AppFactory::create();\n$app->post('\u002Fwapito', function (Request $request, Response $response) use ($secret, $events) {\n    $raw = (string) $request->getBody();\n    if (!wapito_verify($raw, $request->getHeaderLine('X-Wapito-Signature'), $secret)) {\n        return $response->withStatus(401);\n    }\n    $payload = json_decode($raw, true);\n    if (in_array($payload['event'], $events, true)) {\n        error_log($payload['event'] . ' ' . json_encode($payload['data']));\n    }\n    return $response->withStatus(200); \u002F\u002F answer 2xx fast; do the real work in a queue\n});\n$app->run();\n",[130],"webhook.php","Slim 4","composer require slim\u002Fslim:^4 slim\u002Fpsr7",[139,141,143,145,147],{"label":40,"id":30,"lang":30,"code":109,"html":140},"\u003Cpre class=\"shiki shiki-themes github-light-default github-dark-default\" style=\"background-color:#ffffff;--shiki-dark-bg:#0d1117;color:#1f2328;--shiki-dark:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">&#x3C;?\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">php\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$client \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> \\GuzzleHttp\\Client\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $client\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">request\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'GET'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fnewsletters\u002Ffind?q=release%20notes&#x26;country=GB&#x26;count=50'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">  'headers'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    'Authorization'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Bearer wpt_YOUR_TOKEN'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  ],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">echo\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">getBody\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":40,"id":30,"lang":30,"code":117,"html":142},"\u003Cpre class=\"shiki shiki-themes github-light-default github-dark-default\" style=\"background-color:#ffffff;--shiki-dark-bg:#0d1117;color:#1f2328;--shiki-dark:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">&#x3C;?\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">php\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$client \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> \\GuzzleHttp\\Client\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $client\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">request\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'GET'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fnewsletters\u002Finvite\u002F0029VaAbCdEfGhIjKlMnOp'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">  'headers'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    'Authorization'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Bearer wpt_YOUR_TOKEN'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  ],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">echo\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">getBody\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":40,"id":30,"lang":30,"code":124,"html":144},"\u003Cpre class=\"shiki shiki-themes github-light-default github-dark-default\" style=\"background-color:#ffffff;--shiki-dark-bg:#0d1117;color:#1f2328;--shiki-dark:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">&#x3C;?\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">php\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$client \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> \\GuzzleHttp\\Client\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $client\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">request\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'GET'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fnewsletters\u002F120363099887766554@newsletter\u002Fmessages?count=50&#x26;offset=0'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">  'headers'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    'Authorization'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Bearer wpt_YOUR_TOKEN'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  ],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">echo\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">getBody\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":40,"id":30,"lang":30,"code":28,"html":146},"\u003Cpre class=\"shiki shiki-themes github-light-default github-dark-default\" style=\"background-color:#ffffff;--shiki-dark-bg:#0d1117;color:#1f2328;--shiki-dark:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">&#x3C;?\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">php\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F Follow Channels with the Wapito WhatsApp API.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F Search or resolve a link, verify it is the right channel, page back through the history, then handle new posts from the webhook.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F Run it with:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F   export WAPITO_TOKEN=\"wpt_...\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F   php follow-channels.php\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">require\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> __DIR__\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> .\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> '\u002Fvendor\u002Fautoload.php'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$baseUrl \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'https:\u002F\u002Fapi.wapito.com\u002Fv1'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$token \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> getenv\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'WAPITO_TOKEN'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F --- Search the directory ---\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$client \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> \\GuzzleHttp\\Client\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $client\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">request\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'GET'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, $baseUrl \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">.\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> '\u002Fnewsletters\u002Ffind?q=release%20notes&#x26;country=GB&#x26;count=50'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">  'headers'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    'Authorization'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Bearer '\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> .\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $token,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  ],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">echo\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">getBody\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F --- Resolve an invite link ---\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$client \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> \\GuzzleHttp\\Client\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $client\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">request\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'GET'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, $baseUrl \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">.\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> '\u002Fnewsletters\u002Finvite\u002F0029VaAbCdEfGhIjKlMnOp'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">  'headers'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    'Authorization'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Bearer '\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> .\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $token,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  ],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">echo\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">getBody\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F --- Read what has been published ---\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$client \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> \\GuzzleHttp\\Client\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $client\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">request\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'GET'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, $baseUrl \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">.\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> '\u002Fnewsletters\u002F120363099887766554@newsletter\u002Fmessages?count=50&#x26;offset=0'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">  'headers'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    'Authorization'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'Bearer '\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> .\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $token,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  ],\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">echo\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">getBody\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":136,"id":30,"lang":30,"code":133,"html":148},"\u003Cpre class=\"shiki shiki-themes github-light-default github-dark-default\" style=\"background-color:#ffffff;--shiki-dark-bg:#0d1117;color:#1f2328;--shiki-dark:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">&#x3C;?\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">php\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F public\u002Fwebhook.php - run with: php -S 0.0.0.0:8000 -t public\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">require\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> __DIR__\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> .\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> '\u002F..\u002Fvendor\u002Fautoload.php'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> Psr\\Http\\Message\\ResponseInterface\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> as\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> Response\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> Psr\\Http\\Message\\ServerRequestInterface\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> as\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> Request\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> Slim\\Factory\\AppFactory\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$secret \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> getenv\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'WAPITO_WEBHOOK_SECRET'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$events \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'messages'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F** Checks the X-Wapito-Signature header: t=&#x3C;ms>,v1=&#x3C;hex hmac-sha256>. *\u002F\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">function\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> wapito_verify\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">string\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $raw, \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">?string\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $header, \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">string\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $secret)\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">:\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> bool\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">!\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$header) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> false\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    $parts \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [];\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    foreach\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">explode\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">','\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, $header) \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">as\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $pair) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">        [$k, $v] \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> array_pad\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">explode\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'='\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, $pair, \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">2\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">), \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">2\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">null\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">        $parts[$k] \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $v;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">empty\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">($parts[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'t'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]) \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">||\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> empty\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">($parts[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'v1'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> false\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">abs\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">int\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) (\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">microtime\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">true\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">*\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 1000\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">-\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">int\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) $parts[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'t'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]) \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">>\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 300000\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> false\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">; \u003C\u002Fspan>\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F 5 minute clock skew\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    $expected \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> hash_hmac\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'sha256'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, $parts[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'t'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">] \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">.\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> '.'\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> .\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $raw, $secret);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    return\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> hash_equals\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">($expected, $parts[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'v1'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$app \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> AppFactory\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">create\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$app\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">post\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'\u002Fwapito'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">function\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">Request\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $request, \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">Response\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $response) \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> ($secret, $events) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    $raw \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">string\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) $request\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">getBody\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">!\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">wapito_verify\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">($raw, $request\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">getHeaderLine\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'X-Wapito-Signature'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">), $secret)) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">withStatus\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">401\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    $payload \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> json_decode\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">($raw, \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">true\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">in_array\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">($payload[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'event'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], $events, \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">true\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">        error_log\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">($payload[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'event'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">] \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">.\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> ' '\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> .\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> json_encode\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">($payload[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'data'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    }\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    return\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">withStatus\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">200\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">); \u003C\u002Fspan>\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F answer 2xx fast; do the real work in a queue\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">});\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">$app\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">->\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">run\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",1790464902671]