[{"data":1,"prerenderedAt":155},["ShallowReactive",2],{"pseo:tutorials:group-participants:nodejs":3,"highlight:tutorial:group-participants:nodejs":144},{"ban_risk":4,"ban_risk_note":5,"deploy_targets":6,"errors":11,"faqs":18,"feature":29,"full_script":33,"gotchas":37,"intro_note":43,"language":44,"pitfalls":49,"prerequisites":52,"related":55,"seo":82,"siblings":101,"step_summary":108,"steps":109,"tier":137,"url":95,"webhook_receiver":138},"high","Adding people who never asked to be in a group is the behaviour WhatsApp punishes hardest, because it is what bulk marketing looks like from the inside. Prefer invite links; when you must add directly, add small batches of people who expect it, spread over time, and stop immediately if the API starts reporting that participants are being invited rather than added.",[7,8,9,10],"Google Cloud Run (container, min instances 0, one process per channel worker)","Railway or Render web service for the Express receiver","Vercel or Netlify Functions for the webhook receiver only - they cannot hold the sender queue open","Fly.io machine with a persistent volume if you queue sends locally",[12,15],{"title":13,"url":14},"invalid_request (400)","\u002Fdocs\u002Ferrors\u002Finvalid-request\u002F",{"title":16,"url":17},"forbidden (403)","\u002Fdocs\u002Ferrors\u002Fforbidden\u002F",[19,23,26],{"a":20,"q":21,"source":22},"WhatsApp lets everyone choose who may add them to groups. If a person has restricted that to their contacts, an add from an unknown number becomes an invitation they have to accept. The API reports this per participant, so your code can tell the difference between someone who is in the group and someone who has merely been asked.","Why are some people invited instead of added?","features.json",{"a":24,"q":25,"source":22},"The group itself has a member ceiling set by WhatsApp, and practical experience says that adding many people in quick succession draws attention regardless of the ceiling. Add in small batches with a pause between them, and if the group is large, publish an invite link and let people join at their own pace.","Is there a limit to how many I can add at once?",{"a":27,"q":28,"source":22},"Yes, technically, but think about whether you should. Someone who left a group and is immediately put back in is very likely to report the number, and repeated re-adds of the same person are a strong abuse signal. Send them the invite link instead and let them decide.","Can I re-add someone who left?",{"name":30,"slug":31,"url":32},"Group Participants","group-participants","\u002Fwhatsapp-api\u002Fgroup-participants\u002F",{"code":34,"filename":35,"lang":36},"\u002F\u002F Group Participants with the Wapito WhatsApp API.\n\u002F\u002F\n\u002F\u002F List who is actually in the group, add the missing people, remove the ones who left, and reconcile from the participants webhook.\n\u002F\u002F\n\u002F\u002F Run it with:\n\u002F\u002F   export WAPITO_TOKEN=\"wpt_...\"\n\u002F\u002F   node group-participants.mjs\n\nconst BASE_URL = 'https:\u002F\u002Fapi.wapito.com\u002Fv1';\nconst TOKEN = process.env.WAPITO_TOKEN;\n\n\u002F\u002F --- Read the current membership ---\n{\n  const url = BASE_URL + '\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants';\n  const options = {method: 'GET', headers: {Authorization: 'Bearer ' + TOKEN}};\n\n  try {\n    const response = await fetch(url, options);\n    const data = await response.json();\n    console.log(data);\n  } catch (error) {\n    console.error(error);\n  }\n}\n\n\u002F\u002F --- Add the people who are missing ---\n{\n  const url = BASE_URL + '\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants';\n  const options = {\n    method: 'POST',\n    headers: {Authorization: 'Bearer ' + TOKEN, 'Content-Type': 'application\u002Fjson'},\n    body: '{\"participants\":[\"+15551234567\",\"+15559876543\"]}'\n  };\n\n  try {\n    const response = await fetch(url, options);\n    const data = await response.json();\n    console.log(data);\n  } catch (error) {\n    console.error(error);\n  }\n}\n\n\u002F\u002F --- Remove someone who has left the team ---\n{\n  const url = BASE_URL + '\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants\u002F+15551234567';\n  const options = {method: 'DELETE', headers: {Authorization: 'Bearer ' + TOKEN}};\n\n  try {\n    const response = await fetch(url, options);\n    console.log(response.status);\n  } catch (error) {\n    console.error(error);\n  }\n}\n\n","group-participants.mjs","javascript",[38,39,40,41,42],"fetch never rejects on a 4xx or 5xx. Check response.ok yourself; an await fetch(...) that \"worked\" can still be a 402 plan_required with a JSON error body.","Do not let express.json() run before your webhook route. Signature verification needs the exact raw bytes, so mount express.raw({ type: \"application\u002Fjson\" }) on the webhook path and parse the JSON yourself afterwards.","Node 18+ has global fetch, but node-fetch v2, undici and axios all disagree about how they surface non-2xx responses. Pick one client per project or your error handling will be inconsistent.","Promise.all over a list of recipients defeats the send queue: the API will serialise them anyway and return 429 send_rate_limited for the overflow. Send sequentially with await, or use a queue with concurrency 1 per channel.","Large numbers in JSON.parse lose precision. Treat every WhatsApp id, group id and timestamp that arrives as a string as a string - never Number() it.","From Node.js this feature is an async reconciliation loop: fetch the live members, compute two diffs against your database, then await the adds and removes sequentially. The add endpoint returns a per-person array that you have to read even on a 200, and the participants webhook is what keeps the copy honest between runs.",{"family":45,"name":46,"slug":47,"url":48},"scripting","Node.js","nodejs","\u002Fwhatsapp-bot\u002Fnodejs\u002F",[50,51],"A Promise.all over the removal list fires every DELETE at once, and the API answers the overflow with 429 send_rate_limited; the ones that failed are then still in the group and your diff repeats them next run.","Checking response.ok on the add call tells you the batch was accepted, not that anyone joined. The per-participant statuses in the body are what to persist, and 'invited' means the person has a pending invite, not a seat.",[53,54],"npm install express (fetch is built in from Node 18)","process.env.WAPITO_TOKEN",{"language_hub":48,"operations":56,"pillar":32,"same_language_features":66},[57,60,63],{"title":58,"url":59},"GET \u002Fgroups\u002F{id}\u002Fparticipants","\u002Fdocs\u002Fapi\u002Fgroups\u002Flist-group-participants\u002F",{"title":61,"url":62},"POST \u002Fgroups\u002F{id}\u002Fparticipants","\u002Fdocs\u002Fapi\u002Fgroups\u002Fadd-group-participants\u002F",{"title":64,"url":65},"DELETE \u002Fgroups\u002F{id}\u002Fparticipants\u002F{pid}","\u002Fdocs\u002Fapi\u002Fgroups\u002Fremove-group-participant\u002F",[67,70,73,76,79],{"title":68,"url":69},"Create Group","\u002Fwhatsapp-api\u002Fcreate-group\u002Fnodejs\u002F",{"title":71,"url":72},"Group Admins","\u002Fwhatsapp-api\u002Fgroup-admins\u002Fnodejs\u002F",{"title":74,"url":75},"Group Invite Link","\u002Fwhatsapp-api\u002Fgroup-invite-link\u002Fnodejs\u002F",{"title":77,"url":78},"Group Settings","\u002Fwhatsapp-api\u002Fgroup-settings\u002Fnodejs\u002F",{"title":80,"url":81},"Group Join Requests","\u002Fwhatsapp-api\u002Fgroup-join-requests\u002Fnodejs\u002F",{"breadcrumb":83,"canonical":96,"description":97,"h1":98,"lastmod":99,"title":100},[84,87,90,93,94],{"name":85,"url":86},"Home","\u002F",{"name":88,"url":89},"WhatsApp API","\u002Fwhatsapp-api\u002F",{"name":91,"url":92},"Groups","\u002Fwhatsapp-api\u002Fgroups\u002F",{"name":30,"url":32},{"name":46,"url":95},"\u002Fwhatsapp-api\u002Fgroup-participants\u002Fnodejs\u002F","https:\u002F\u002Fwapito.com\u002Fwhatsapp-api\u002Fgroup-participants\u002Fnodejs\u002F","How to add group members in Node.js with the Wapito WhatsApp API. 4 steps with runnable code, a Express 5 webhook receiver and the errors to expect.","How to add group members in Node.js with the Wapito WhatsApp API","2026-09-16","Add Members in Node.js (WhatsApp API Tutorial) | Wapito",[102,105],{"title":103,"url":104},"Python","\u002Fwhatsapp-api\u002Fgroup-participants\u002Fpython\u002F",{"title":106,"url":107},"PHP","\u002Fwhatsapp-api\u002Fgroup-participants\u002Fphp\u002F","List who is actually in the group, add the missing people, remove the ones who left, and reconcile from the participants webhook.",[110,118,125,132],{"body":111,"note":112,"operationId":113,"operation_url":59,"snippet":114,"title":116,"webhook":117},"Always start from the real list rather than from your own copy. Members join by link, leave on their own, and are removed by other admins, so a database that has not seen a participants event in a while is usually out of date.","In Node.js the GET's parsed body is an array of participant objects; build a Map keyed on the identity string so the diff is a couple of filter calls. Because fetch resolves on any status, test response.ok first and read the JSON error when it is false, rather than iterating an error object as members.","listGroupParticipants",{"code":115,"lang":36},"const url = 'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants';\nconst options = {method: 'GET', headers: {Authorization: 'Bearer wpt_YOUR_TOKEN'}};\n\ntry {\n  const response = await fetch(url, options);\n  const data = await response.json();\n  console.log(data);\n} catch (error) {\n  console.error(error);\n}","Read the current membership",null,{"body":119,"note":120,"operationId":121,"operation_url":62,"snippet":122,"title":124,"webhook":117},"Send the numbers in a single call and read the per-participant result. Some will be added, some will be invited instead because their privacy settings forbid direct adds, and some will fail outright - the response says which is which.","In Node.js send the batch as body: JSON.stringify({ participants }) and then walk the returned array: each element has the number and a status such as added, invited or failed. Log the invited ones separately, because from the group's point of view they are not members yet and your next run will see them missing again.","addGroupParticipants",{"code":123,"lang":36},"const url = 'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants';\nconst options = {\n  method: 'POST',\n  headers: {Authorization: 'Bearer wpt_YOUR_TOKEN', 'Content-Type': 'application\u002Fjson'},\n  body: '{\"participants\":[\"+15551234567\",\"+15559876543\"]}'\n};\n\ntry {\n  const response = await fetch(url, options);\n  const data = await response.json();\n  console.log(data);\n} catch (error) {\n  console.error(error);\n}","Add the people who are missing",{"body":126,"note":127,"operationId":128,"operation_url":65,"snippet":129,"title":131,"webhook":117},"Removal is immediate and the person sees that they were removed. Do it from a scheduled job that reads your own source of truth, so nobody is removed because of a transient CRM sync failure.","In Node.js each removal is a separate fetch with method: 'DELETE' and the participant id encoded into the path with encodeURIComponent, since a linked identity can contain characters a raw template literal would leave ambiguous. Await them one at a time inside a for...of loop; a 404 for someone already gone is expected, not fatal.","removeGroupParticipant",{"code":130,"lang":36},"const url = 'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants\u002F+15551234567';\nconst options = {method: 'DELETE', headers: {Authorization: 'Bearer wpt_YOUR_TOKEN'}};\n\ntry {\n  const response = await fetch(url, options);\n  console.log(response.status);\n} catch (error) {\n  console.error(error);\n}","Remove someone who has left the team",{"body":133,"note":134,"operationId":117,"operation_url":117,"snippet":117,"title":135,"webhook":136},"Every join, leave, add and remove arrives as an event carrying the action and the participant, who may be a linked identity rather than a phone number. Apply it to your own records so the two never drift apart.","In Node.js the Express handler reads payload.data.action and payload.data.participant off the raw-body parse and applies it to your store; the participant may carry only a linked identity, so treat the phone field as optional. Acknowledge with res.sendStatus(200) before the write, or queue the write, so a slow database never triggers a redelivery.","Reconcile from the webhook","groups.participants","t2",{"code":139,"events":140,"filename":141,"framework":142,"install":143,"lang":36},"import crypto from 'node:crypto';\nimport express from 'express';\n\nconst app = express();\nconst SECRET = process.env.WAPITO_WEBHOOK_SECRET;\nconst EVENTS = new Set(['groups.participants']);\n\n\u002F** Checks the X-Wapito-Signature header: t=\u003Cms>,v1=\u003Chex hmac-sha256>. *\u002F\nfunction verify(raw, header) {\n  if (!header) return false;\n  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));\n  if (!parts.t || !parts.v1) return false;\n  if (Math.abs(Date.now() - Number(parts.t)) > 300_000) return false; \u002F\u002F 5 minute clock skew\n  const expected = crypto.createHmac('sha256', SECRET).update(`${parts.t}.`).update(raw).digest('hex');\n  const a = Buffer.from(expected, 'hex');\n  const b = Buffer.from(parts.v1, 'hex');\n  return a.length === b.length && crypto.timingSafeEqual(a, b);\n}\n\napp.post('\u002Fwapito', express.raw({ type: 'application\u002Fjson' }), (req, res) => {\n  if (!verify(req.body, req.get('X-Wapito-Signature'))) return res.sendStatus(401);\n  const payload = JSON.parse(req.body.toString('utf8'));\n  if (EVENTS.has(payload.event)) console.log(payload.event, payload.data);\n  res.sendStatus(200); \u002F\u002F answer 2xx fast; do the real work in a queue\n});\n\napp.listen(Number(process.env.PORT ?? 3000));\n",[136],"webhook.mjs","Express 5","npm install express",[145,147,149,151,153],{"label":46,"id":47,"lang":36,"code":115,"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\">const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> url\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> options\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {method: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'GET'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, headers: {Authorization: \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\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">try\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> fetch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(url, options);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> data\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> response.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">json\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(data);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">} \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">catch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (error) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">error\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(error);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":46,"id":47,"lang":36,"code":123,"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\">const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> url\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> options\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:#1F2328;--shiki-dark:#E6EDF3\">  method: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'POST'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  headers: {Authorization: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'Bearer wpt_YOUR_TOKEN'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'Content-Type'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'application\u002Fjson'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">},\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  body: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'{\"participants\":[\"+15551234567\",\"+15559876543\"]}'\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:#CF222E;--shiki-dark:#FF7B72\">try\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> fetch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(url, options);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> data\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> response.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">json\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(data);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">} \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">catch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (error) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">error\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(error);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":46,"id":47,"lang":36,"code":130,"html":150},"\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\">const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> url\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants\u002F+15551234567'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> options\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {method: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'DELETE'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, headers: {Authorization: \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\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">try\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> fetch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(url, options);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(response.status);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">} \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">catch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (error) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">error\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(error);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":46,"id":47,"lang":36,"code":34,"html":152},"\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:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F Group Participants 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 List who is actually in the group, add the missing people, remove the ones who left, and reconcile from the participants 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   node group-participants.mjs\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> BASE_URL\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:#CF222E;--shiki-dark:#FF7B72\">const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> TOKEN\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> process.env.\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">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 --- Read the current membership ---\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\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> url\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> BASE_URL\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> '\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> options\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {method: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'GET'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, headers: {Authorization: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'Bearer '\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 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:#CF222E;--shiki-dark:#FF7B72\">  try\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> fetch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(url, options);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> data\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> response.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">json\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(data);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  } \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">catch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (error) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">error\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(error);\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:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F --- Add the people who are missing ---\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\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> url\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> BASE_URL\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> '\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> options\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:#1F2328;--shiki-dark:#E6EDF3\">    method: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'POST'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    headers: {Authorization: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'Bearer '\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> TOKEN\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'Content-Type'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'application\u002Fjson'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">},\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    body: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'{\"participants\":[\"+15551234567\",\"+15559876543\"]}'\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:#CF222E;--shiki-dark:#FF7B72\">  try\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> fetch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(url, options);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> data\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> response.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">json\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(data);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  } \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">catch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (error) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">error\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(error);\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:#6E7781;--shiki-dark:#8B949E\">\u002F\u002F --- Remove someone who has left the team ---\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\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> url\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> BASE_URL\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> '\u002Fgroups\u002F120363041234567890@g.us\u002Fparticipants\u002F+15551234567'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> options\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {method: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'DELETE'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, headers: {Authorization: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'Bearer '\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 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:#CF222E;--shiki-dark:#FF7B72\">  try\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> response\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> fetch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(url, options);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(response.status);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  } \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">catch\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (error) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">error\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(error);\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\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":142,"id":47,"lang":36,"code":139,"html":154},"\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\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> crypto \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">from\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'node:crypto'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> express \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">from\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'express'\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\">const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> app\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> express\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> SECRET\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> process.env.\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">WAPITO_WEBHOOK_SECRET\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> EVENTS\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> new\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> Set\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">([\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'groups.participants'\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\"> verify\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">raw\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">header\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:#1F2328;--shiki-dark:#E6EDF3\">header) \u003C\u002Fspan>\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:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> parts\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> Object.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">fromEntries\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(header.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">split\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\">).\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">map\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((\u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">p\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\"> p.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">split\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\">)));\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\">parts.t \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">||\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> !\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">parts.v1) \u003C\u002Fspan>\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:#CF222E;--shiki-dark:#FF7B72\">  if\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (Math.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">abs\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(Date.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">now\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\"> Number\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(parts.t)) \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">>\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 300_000\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) \u003C\u002Fspan>\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:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> expected\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> crypto.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">createHmac\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\">, \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">SECRET\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">).\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">update\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\">parts\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">.\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">t\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}.`\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">).\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">update\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(raw).\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">digest\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'hex'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> a\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> Buffer.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">from\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(expected, \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'hex'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> b\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> Buffer.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">from\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(parts.v1, \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'hex'\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:#1F2328;--shiki-dark:#E6EDF3\"> a.\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">length\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ===\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> b.\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">length\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> &#x26;&#x26;\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> crypto.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">timingSafeEqual\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(a, b);\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:#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\">, express.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">raw\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">({ type: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'application\u002Fjson'\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }), (\u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">req\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">res\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>\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\">verify\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(req.body, req.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">get\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\">))) \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">return\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> res.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">sendStatus\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:#CF222E;--shiki-dark:#FF7B72\">  const\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> payload\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> JSON\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">parse\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(req.body.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toString\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'utf8'\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\">EVENTS\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">has\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(payload.event)) console.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(payload.event, payload.data);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  res.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">sendStatus\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\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">app.\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">listen\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">Number\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(process.env.\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">PORT\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> ??\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 3000\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",1790464899949]