Why do I get a custom audience successful response without actual success? - facebook

I am developing an App with the Facebook Custom Audiences API and my match rate is 0% despite a successful response message. I go through each step the same way it is in their documents but none ever match.
First I create the audience through the API, and then add I add a description with the API, both of those work. I even get a successful response when I submit array of email addresses:
{"audience_id":"XXX","num_received":460,"num_invalid_entries":0,"invalid_entry_samples":[]}"
But when I look at the audience in facebook, the audience has the error message "Not ready audience too small." I figured this must be an issue with my hashing steps, which I had copied directly from their documentation. I submitted their example email "mary#example.com" into my app
Facebook example hash: f1904cf1a9d73a55fa5de0ac823c4403ded71afd4c3248d00bdcd0866552bb79
My app's hash value : f1904cf1a9d73a55fa5de0ac823c4403ded71afd4c3248d00bdcd0866552bb79
I even entered the test email address into my app multiple times, so position in the array has nothing to do with the hashing.
My final test was to upload the list manually, to see if there are in fact zero matches. There were 100 matches almost immediately. what gives?
Is there any reason for me to get a successful response besides issues with the hashing?

I'd say the issue was Facebook returning a "success" message because it received the hashed values successfully and can process those hashes without issue. This doesn't imply that the matching is done on Facebook's end or that they got matches.
Rather than have your connection wait while it processes your hashes, Facebook will just make sure everything's OK, return that success message, and then process the hashes offline. This means it could take some time for the hashes to be matched to Facebook users. Oftentimes it's pretty quick, but I've seen it take hours sometimes.
Facebook's audience management API documentation states that it could take up to an hour to add someone to an audience. That applies to each batch of hashes you're sending (since each batch is limited to 10,000 hashes).

Related

Are URLs in emails indexed by search engines so they become publicly searchable?

I have read a few questions on here about e-mail clients prefetching URLs in e-mails. An answer to this seems to be to add a new confirmation page, where the user has to click a button to confirm the desired action.
But, this answer states the following:
As of Feb 2017 Outlook (https://outlook.live.com/) scans emails
arriving in your inbox and it sends all found URLs to Bing, to be
indexed by Bing crawler.
This effectively makes all one-time use links like
login/pass-reset/etc useless.
(Users of my service were complaining that one-time login links don't
work for some of them and it appeared that BingPreview/1.0b is hitting
the URL before the user even opens the inbox)
Drupal seems to be experiencing the same problem:
https://www.drupal.org/node/2828034
My major concern is with this statement:
As of Feb 2017 Outlook (https://outlook.live.com/) scans emails
arriving in your inbox and it sends all found URLs to Bing, to be
indexed by Bing crawler.
If this is the case, any URL in an e-mail meant to confirm an action, e.g. confirming a login, subscription, or unsubscription, can end up searchable in a search engine, if that's whats meant by indexed in the quote above. In this case, it's Bing. Not even a dedicated confirmation page where the user confirms the desired action truly mitigates this.
Scenario #1
If I email the user a login link with a one-time token in the URL, that URL will end up in Bing. This token will have a short lifetime, lets say 5 minutes, so I doubt anyone will manage to search on Bing and find the URL before the user clicks it or it expires.
Scenario #2
The user gets an e-mail with a link to confirm a subscription. This link is perhaps valid for 24 hours. This might(?) be long enough for someone else to stumble over the link on a search engine and accidentally (or on purpose) confirm the subscription on behalf of the user.
Scenario #2 is not uncommon, it's even best practice to use double opt-in as far as I am aware.
Scenario #3
Unsubscribe URLs in the bottom of newsletters. Maybe valid for forever? You don't want this publicly searchable in an search engine.
Assume all the one-time confirmation links land on a confirmation page where the user confirms the desired action.
Is it truly the issue that URLs in e-mails are indexed by search engines, at least Bing? And will they actually end up publicly searchable? If not, what is meant by indexed in the quote above?
I'll add for the sake of completion that I don't think I've had much of a problem with this in my own use of the web, so my gut feeling is that this is unlikely the case.
Is it truly the issue that URLs in e-mails are indexed by search engines, at least Bing?
I can't definitely say if they are being indexed or not, only Bing could answer this question, but they are surely being visited, at least with a simple GET request. I just tested this sending myself a link to a page on my website that logs the requests that are made against it, and indeed I'm seeing a GET coming from 207.46.13.181 (reverse DNS says msnbot-207-46-13-181.search.msn.com), which suggests that an automated program from search.msn.com is crawling the link. This leads me to believe that yes, they are trying to index the link's content somehow, but it's only my opinion really.
And will they actually end up publicly searchable? If not, what is meant by "indexed" in the quote above?
Well, again, impossible to say unless you work for Bing. In any case, "indexing" means exactly what you think it does: parsing the content of a page to potentially include it in search results.
The real question here is: does this somehow represent a security problem or will it compromise my website's functionality?
It surely has the potential to: if your confirmation/reset/subscription/whatever process only relies on a single GET request with the appropriate GET parameter, then you should definitely revisit the strategy, as it obviously allows anyone to perform the action (even maliciously for example enumerating possible IDs for your GET parameters).
If the link you are trying to send contains sensible information or can be used to alter important data for an user of your website, then you should at least put it behind a login page only giving access to the interested user. This way, anyone who wants to access it (including search engines) will be redirected to a login page if not already logged in.
If the link you are trying to send is just some kind of harmless confirmation link (e.g. subscribe/unsubscribe from a newsletter), then at least use a form inside the web page to do the actual confirmation through a POST request (possibly also using a CSRF token), otherwise you will unequivocally end up with false positives.

Facebook "pre-filling" policy unclear with regards to empty message and the link parameter

I'm trying to get publish_actions permissions approved for an iPhone app and been denied twice. The first time was because, as the policy says not to, we were populating the message parameter automatically when posting to the user's wall using the graph api. So we removed the message field entirely and kept only the link parameter.
The app was rejected again with the same message so I figured I'd try to get a definitive answer here before I get three strikes on app submission.
Both the 2.3 platform policy video and written policy explicitly say do not pre-fill the message parameter but say nothing about the link parameter. Beyond simply not pre-filling any of the message parameter must we also provide a way for the user to enter a message? If so that is not clear in the policy.
Graph Api Publish Documentation:
https://developers.facebook.com/docs/graph-api/reference/v2.1/user/feed#publish
"Pre-fill" Video: https://developers.facebook.com/docs/apps/review/prefill
I was rejected three times with the same response - which was you can not pre-populate the message field. But with the second and third submission, I was not pre-populating the message field. Of course I was expecting the Facebook reviewer to operate the application according to my instructions to see this. They don't, and the refusal was because they could not tell from my submission that this was the case. The response they give is not hand typed, but a stamped response given when they click "REFUSE!".
The solution is not only to get the application to behave according to policy, but to provide clear pictures with the step by step instructions of how your application shows the user the post, allows for the user to input a message, and the finished post on his time line.

Is there any way to get a list of users for a custom audience?

Getting other details is easy, but there doesn't seem to be any API accessible way to get a list of users (or even approximate users) for the audience. You can add them, and delete them (?!) but not enumerate all the users in the list.
Is that truly the case, or am I missing something?
According to the documentation here: https://developers.facebook.com/docs/reference/ads-api/custom-audience-targeting/ you should be able to see an approximate count.
There is no way to get the users back from the custom audience list by design.
For the audiences you never upload raw contact data. You always have to hash it via SHA256 and send the feed to Facebook that way. Since you have not provided the actual contact information like email, phone number facebook won't give those back to you it would be an information breach in a way.
If what you are asking is whether you can retrieve back the hashes that you have sent, I have not been able to find a way it on the API so I assume they think that you already have that list since you uploaded it in the first place.
https://developers.facebook.com/docs/marketing-api/audiences-api/

iphone app - preventing spam

I've developed an app that allows users to upload some photos and share them on Facebook/Dropbox/Twitter etc. Recently it went live in the app store.
However, I'm having a problem now: a bot is creating accounts and uploading many photos on my server. I've temporarily disabled the app, but now I'm looking for an efficient way to prevent this bot from doing this.
The bot's ip address is changing very often so it's impossible to block the ip. He creates accounts with a very realistic name and email address so it's hard to find out which users are real and which are created by the bot.
I was thinking of using a captcha, but I'm not sure if my app will be rejected by Apple if I implement this. I'm preferably looking for a way so I can prevent him from doing his work and so I don't have to resend the app to Apple again.
Could anyone give me some advice on what I could possibly do?
Thanks!
This is how I solved a similar problem:
I implemented a token-generator, which generates a one-time token for every single data transfer with the server, so even one for login-data, sending a file etc. This token is generated by a secret algorithm and can be verified server side, since you know how you generate one.
After one token is used, put it in a temporary list for the next X minutes/hours/days (depending on how many data transfers your server can handle). When a user tries to send data with a used token (i.e. the token matches one in the "banned" list), you can be sure that someone's trying to spam you -> mark the account as "spammer" and decide what you wish to do.
The algorithm must produce a different token each time (the best way would be a one-way hash), but you have to assure specific "properties", with which you can proof its authenticity.
So one very simple example:
Your algorithm in the client is generating a number between 1000000000000000000000 and 99999999999999999999999, this number is then multiplied with 12456564 and incremented by 20349.
The server becomes a specific command and data, and the generated token. Now it checks, whether (number - 20349)%12456564 is 0. If it's 0, it was likely generated by your "secret" algorithm.
It's a very basic example but you get the idea…

How to Avoid Posting a Duplicate when Publishing to Facebook?

With the Graph API, I publish a story by POSTing to the /me/feed connection. I get back a success or an error result from Facebook. So far so good. Once in a while, the API takes a long time and the connection times out. In that case, I don't know for sure if the request succeeded of failed (i.e. maybe the request never reached Facebook, or maybe it succeeded and the result never made it back to me). How do you handle this situation?
More details:
I publish a lot of posts to Facebook and Twitter, so the timeout situation happens often. With Twitter, the solution is easy. If the request times out the first time, I simply try again. Twitter detects duplicates, so if the post was successfully published the first time, then I'll get a "duplicate status" error on the second request and I know that I don't need to retry any more.
But Facebook doesn't detect duplicates, so if I retry the publish request, I risk having two copies of the post published to the user wall, which is not nice. On the other hand, if I don't retry, I risk having the post not published at all. Thoughts?
I get back a success or an error result from Facebook.
Hmmm. When I post to the Graph API, I get back an error or the id of the post. I never see any success message. What SDK are you using around the API?
Once in a while, the API takes a long time and the connection times
out.
Usually when things are running slowly, it's due to the channelUrl not being specified. See https://developers.facebook.com/docs/reference/javascript/
It is important for the channel file to be cached for as long as
possible. When serving this file, you must send valid Expires headers
with a long expiration period. This will ensure the channel file is
cached by the browser which is important for a smooth user experience.
Without proper caching, cross domain communication will become very
slow and users will suffer a severely degraded experience.