What this application does
Connect with Bayezid is a web development and digital marketing studio in Bangladesh. This application supports three things, and nothing else:
- Messenger support for our own Facebook Page. Someone messages the Page with a question about our services and receives an answer — most of them written in advance, in Bangla and English.
- Conversions API for our own website. Website events already reported by the Meta Pixel are also sent server-side, so a blocked browser event is not a lost conversion. Both copies carry the same event ID, so Meta counts one sale once.
- Business Login for clients. A client who has hired us to manage their advertising connects their own Meta business assets so we can work on them, and disconnects whenever they choose.
It is not a consumer product, it has no app store listing, and it does not publish content on anyone's behalf.
Callback URLs
All four are served by a single Cloudflare Worker on bayezid-agency-api.sayadmdbayezidhosan.workers.dev. Every one verifies a Meta signature before it reads the request.
| Purpose | URL | Verification |
|---|---|---|
| Webhook verification GET |
/api/messenger/webhook |
Answers hub.challenge only when hub.verify_token matches the configured value; 403 otherwise. |
| Webhook events POST |
/api/messenger/webhook |
X-Hub-Signature-256, HMAC-SHA256 over the raw request body, compared in constant time. |
| Deauthorize callback | /api/facebook/deauthorize |
signed_request, HMAC-SHA256 over the encoded payload. An unsigned request changes nothing. |
| Data deletion request | /api/facebook/data-deletion |
signed_request, as above. Returns a confirmation code and a status URL. |
Related public URLs
- Deletion status page — sayadbayezid.com/data-deletion-status.html, the address the deletion callback hands out with a confirmation code.
- Client login — sayadbayezid.com/facebook-business-login.html, the only redirect URI this app uses.
- Privacy policy — sayadbayezid.com/privacy-policy.html · Meta-specific policy
- Terms — sayadbayezid.com/terms-of-service.html · Business integration & data policy
Webhook fields, and what each is used for
Subscribed on the Page object for our own Facebook Page. Nothing is subscribed that is not used.
| Field | What we do with it |
|---|---|
messages | Read the customer's question so the assistant can answer it. |
messaging_postbacks | The Get Started button and menu taps, so a person can choose a service instead of typing. |
messaging_referrals | Records which advertisement or link a conversation came from, so an ad's real cost per enquiry can be measured. |
messaging_optins | Opt-ins through a plugin, recorded so consent is on file. |
message_echoes | Stops the assistant talking over a person. When a human on our team answers from the Page inbox, the echo tells the application to stay out of that conversation. |
message_deliveries · message_reads | Confirms a reply reached the customer, so a broken integration is visible rather than silent. |
message_reactions | Recorded; never replied to. |
messaging_policy_enforcement | How Meta tells us the Page is restricted. Recorded so it is not missed. |
Events are stored as a small operational log: the message identifier, the Page identifier, the event type and whether a reply succeeded. Message text is not stored.
Permissions, and why each is needed
| Permission | Why it is required |
|---|---|
pages_messaging | To receive a message sent to our Page and to send the reply. Without it there is no Messenger support. |
pages_manage_metadata | To subscribe the Page to the webhook fields above. |
pages_read_engagement | To read the Page's own profile details used in replies. |
public_profile | Business Login: to show a connecting client which account they signed in with. |
email | Business Login: to contact the client about the work they hired us for. |
ads_management · ads_read | Advertising clients only, on accounts they have granted us. Reading performance, and creating or adjusting campaigns we have been engaged to manage. |
business_management | To see which assets a client has shared with us, so we work only on those. |
What is stored, and for how long
| Data | Why | Kept |
|---|---|---|
| Page-scoped ID of someone who messages the Page | To reply to the right conversation and to know whether a colleague already answered. | Until deletion is requested |
| Name, phone, email and website — only when a person types them into the enquiry form and agrees | So we can call back about the work they asked about. | Until deletion is requested |
| Which advertisement a conversation came from | To measure which campaigns produce enquiries. | Until deletion is requested |
| Client access token, from Business Login | To manage the assets that client engaged us to manage. | Encrypted at rest; removed on deauthorisation |
| Website conversion events | Conversions API delivery, deduplicated against the browser Pixel. | Sent to Meta; a delivery receipt without personal data is retained |
Message content is not stored. Contact details are never taken without the person being shown what will be kept and agreeing to it. Nothing collected here is sold, rented, or shared with any third party.
External services
Measurement on this website connects to Meta at three addresses, and to nothing else. Each is listed below with what is sent to it, when, and how it is authenticated. No data goes anywhere until a Pixel ID and a Conversions API access token are configured; with neither set, every route here is inert.
1. The Pixel library — connect.facebook.net
The browser loads Meta's tracking library, fbevents.js. It is
a JavaScript file request: no data about the visitor is sent to this
address in order to fetch it.
On this site the file is normally fetched server-side, cached at the
edge, and served from /api/pixel.js on our own backend
instead. The reason is practical rather than evasive: every mainstream
content blocker carries a rule for connect.facebook.net, and
when it matches, the library never loads and the browser half of every
event disappears with no error anywhere. Serving the identical file from
our own address means that particular rule does not match it.
www.facebook.com/tr, and a blocker filtering that request
still filters it. That is precisely why the Conversions API below exists
as well: the two halves fail independently, and neither is a substitute for
the other. If our proxy is unavailable the page falls back to Meta's own
copy, which is the position every site is in by default.
2. The Conversions API — graph.facebook.com
Website events are also sent server-to-server, to
graph.facebook.com/v26.0/{pixel_id}/events.
What is sent: the event name, the time, a deduplication event ID,
the action source, the page URL, the visitor's IP address and user agent, the
Meta browser and click cookies (_fbp, _fbc), and —
only where the person has actually given them, such as a newsletter signup —
their email address and phone number hashed with SHA-256 before the
request is built. The plain address never leaves this backend. Where an
event has a monetary value, the value and currency are included.
When: on page view, on the events configured for a URL path, and on a completed registration.
Authentication: an access token held as a platform secret. It is not in the code repository, not in the database, never rendered into a page, and never returned by any endpoint or error message.
3. The noscript fallback — www.facebook.com/tr
Not implemented here, deliberately. The usual arrangement is a 1×1
image inside a <noscript> block, which reports a page
view for a visitor whose JavaScript is switched off. This site does not
have one: the measurement loader is itself JavaScript, so a visitor in that
position was never being counted anyway, and adding an image beacon would
be the only thing on the page tracking someone who cannot use the features
it would be measuring. It is listed here because its absence is a choice,
not an oversight.
Deduplication, and why both halves exist
Each event is sent twice on purpose — once by the browser Pixel, once by the Conversions API — carrying the same event ID, so Meta collapses the pair into a single conversion. Without that, one sale is counted twice, the reported cost per purchase is half the real figure, and every bidding decision made from it is wrong in the direction that costs money.
The backend records whether the browser half actually fired for each event, so a Pixel that is being blocked shows up as a number rather than as silence. A delivery receipt is kept for each event — event name, ID, page, and what Meta replied — with the contact fields replaced by a count before the row is written. A hash of a known address still confirms that person is in the log, so no hash is stored either.
Service provider and terms
Meta Platforms, Inc. Processing at these three addresses happens on Meta's servers under Meta's terms:
Deleting a person's data
Three routes, all of which work:
- Through Facebook. Removing this app from a Facebook account sends a signed deletion request to
/api/facebook/data-deletion. Everything held for that person is removed and a confirmation code is returned with a status URL. - By checking a code. sayadbayezid.com/data-deletion-status.html answers for a confirmation code. It is public on purpose: the person asking has just deleted their account and has nothing left to authenticate with.
- By asking. info@sayadbayezid.com — say what to remove and it is removed.
Security
- Every Meta callback verifies its signature before acting. A forged request cannot delete, disconnect, or trigger anything.
- Signature comparison is constant-time; a near-miss reveals nothing through timing.
- Only
HMAC-SHA256is accepted. A request naming a weaker algorithm is refused rather than trusted. - Tokens and keys are stored as platform secrets, never in the code repository, never written to the database in plain text, and never returned by any endpoint or included in any error message.
- Client access tokens are encrypted at rest.
- The Conversions API token stays server-side and is never sent to a browser.
- Contact details are returned only to an authenticated administrator, never in bulk, and never by a public endpoint.
How to verify this integration
- Webhook verification — a
GETto the webhook URL with the correcthub.verify_tokenreturns the challenge; a wrong one returns 403. - Webhook events — a
POSTwith a validX-Hub-Signature-256is accepted; without it, or with a wrong signature, it is refused and nothing is written. - Messenger — message the Page and a reply arrives. Reply from the Page inbox and the assistant stops for that conversation.
- Deletion — remove the app from a Facebook account; the callback returns a confirmation code, and the status page confirms the removal for that code.
For anything not covered here, write to info@sayadbayezid.com and we will answer with whatever detail is needed.