Remove need to press "Tap to Load Preview" for iPhone OpenGraph SMS Message - ios

I am trying to be able to send SMS messages with links that contain OpenGraph preview images which will load in the iOS "Messages" application and will display the thumbnail without the user having to press [Tap To Load Preview] first... How can this be achieved?
For this, I am sending a text SMS message to an iPhone X which is running iOS 10 and opened with the Messages app.
The text message body contains a URL that points to a resource (a HTML web page) whose body contains OpenGraph metadata with an og:image tag. Eg:
<meta property="og:image" content="https://www.apple.com/v/iphone/home/t/images/home/og.png?201610171354" />
For presentation purposes, we are trying to make it so that the image will load first and immediately, without the user having to tap the button in order to to see it...
Expected Behavior:
Actual Behavior:
As a side note, on the Android clients we have tested, where OpenGraph is supported the image will display instantly without the user being prompted to do anything. The same is true for any other OpenGraph supported application tested, including Facebook.
For reference, here are some of the methods I've tested to try to get this working for us (as well as combinations therein):
Tried serving the image directly with no intermediate redirects, also tried with redirects.
Tried serving PNG and JPG images.
Tried serving the images from URL's containing no more than 20 characters where the URL has the ".jpg" and ".png" parameters and no additional GET parameters. Also tried when the extensions aren't part of the link.
Tried serving the image from the server by referencing its IP directly instead of using a public domain name.
Tried with GET parameters as well, with random numbers to clarify a totally unique URL each time.
Tried serving the image from HTTPS and HTTP links.
Tried serving with dynamically generated images, which should entail a brief delay of some milliseconds while the image is rendered and served.
Tried an enforced sleep in the script that responds to the URL page as well as for the image request to induce an intentional delay of some milliseconds and experimented with various settings for that.
Tried serving the image with a variety of different dimensions, portrait and landscape as well as extremely large and extremely small and other variants between (50x50, 60x50, etc and up).
Always ensured that the image is <1 MB in size, but also tested larger images anyway to see if they would work.
Tried serving images from the same canonical source that the phone or Message service might already 'recognise' as 'trusted' as we have already loaded the preview from those those in the past (testing if such a feature exists, which it probably doesn't).
Tried specifically, all suggestions as noted Apple Technical Note "Best Practices for Link Previews in Messages" see https://developer.apple.com/library/content/technotes/tn2444/_index.html
Tried moving the OG tags outside of the <head> of the page.
Tried stripping of the page of all tags except for pertinent og:image tags.
Tried removing HTTP headers for the response to the GET to the image resource so that just the image itself is returned. Tried then adding back the Content-Type header alone.
Tried priming the request to the image to respond with various HTTP specification cache-invalidating related headers..
Tried sending from various phone numbers US and Australian, also tried changing the "From" field for the SMS message itself to strings like "VERIZON", "Verizon", "Telstra", "APPLE", "Apple", "Facebook", "Uber", "China".
Tried sending the messages from handheld phone as well as from the Twilio Messaging API service.
None of the above work for an iPhone X.

There is no way to do this with SMS. If you send it as an iMessage it will automatically display the preview.
On iPhones the preview is generated on the device rather than server-side. When a user taps preview their device sends 4 GET requests to the server. If the preview was generated automatically there would be a security vulnerability. You could send a text to any iPhone user and get their IP Address.
With iMessages the preview is generated automatically but there is no security vulnerability. The device sending the link sends 4 GET requests to the server, generates the preview and then transmits the preview to the recipient via iMessages. As a result, the receiving device has no need to send a request to the server to generate a preview. And their IP Address is not known to the owner of a webserver.
On Google's Android Messaging app the preview is generated server side. There is one GET request sent to the web server. But it originates from the Android Messages server. So again the owner of the webserver does not receive the recipient's IP Address from their receipt of the text.

Related

Images in emails are inconsistently being cached in iOS Outlook App

While testing images being loaded from an email in my iOS Outlook app, I see inconsistencies with how the app caches them. These images are loading from external sources (i.e. HTML img tag with src pointing to a server, not images that are embedded/attached). The app makes several requests to the same image source as you navigate around. Some of these requests contain the HTTP_IF_NONE_MATCH header but there is a lot of inconsistency. I don't think it's caching them correctly. I've included more details below. it looks like it's causing my image to be loaded several times when the person is browsing the email/their inbox.
The reason this is a problem for me is that I'm building an email tracking tool that relies on a pixel tracker inside the email. I'm trying to determine how many times my email is opened by its various recipients. So this inconsistency is causing misfires for the tool unfortunately. While I realize that could be considered consequential limitation of relying on the app, I'm wondering if the lack of image caching is a larger issue that could be addressed. It is effectively firing requests to load the image repeatedly so that is eating up mobile data unnecessarily.
Is there a way to improve its caching somehow? I'm also looking for any other ways to determine requests coming from the same phone. Here's what I see in my server log when dealing with an email that contains my pixel tracker.
Push notification for email received on iPhone
Click the app to load the inbox -> Tracker request fired for 1st time (i.e. image loaded for first time)
Open email -> Tracker request fired for 2nd time (without any HTTP_IF_NONE_MATCH header)
Go back to inbox -> Tracker request fired for 3rd time but this time it includes HTTP_IF_NONE_MATCH header. Note previous requests did not include this header even though it's the same URL so some inconsistency indicating it did not cache it
Open email for the second time -> Tracker request fired for 4th time but it did not include the HTTP_IF_NONE_MATCH header (inconsistency with 3rd time, which had header)
Go back to inbox -> No request fired
Open email for third time -> Tracker request fired for 5th time and it included HTTP_IF_NONE_MATCH header (so inconsistency between this and 4th request, which did not include it)
From here on, repeating any of the above steps would trigger requests but would always include the HTTP_IF_NONE_MATCH header successfully. I also tested changing folders, refreshing the inbox, replying to emails etc. While this triggered tracker requests as well, they also included the appropriate header.
However, I noticed that closing the app (by swiping it off) and then opening it again effectively caused the behaviour to reset. The 1st, 2nd and 4th requests would still not include the header while the others would. Note the same happens on data vs wifi.
Generally speaking, it looks like the iOS app is repeatedly loading the images that it should have already cached. Outlook desktop clients work great because it only fires 1 request to load the pixel. For the Outlook Android app, it seems to do a better job caching the image. It makes 2 or 3 requests the first couple of times you open the email but the 2nd/3rd requests always include the header. After that, it stops loading the image altogether so it must be caching it on the phone somehow. Since the Android app functions fairly differently, this is what lead me to believe it may be an issue that could be resolved in the app itself. However, as I said above, I'm looking for alternative ways to determine how to track the user.
Another way I normally rely on is to set a cookie to indicate an open just happened by that device. I then simply skip these false positives to avoid the repeated requests. However, because of the nature of iOS apps needing to whitelist third-party cookies of web requests within the code, each subsequent request is not sending my cookie along either. Here's a related question as well. I confirmed the Safari settings do not block 3rd party cookies in case it conflicts.
Alternatively, if there's another way to tell a unique device, I could figure out how to skip repeated opens for that phone on the server. I checked the rest of the request headers. The only thing that's somewhat identifiable is a combination of user-agent and IP address but that seems very unreliable to me. Two people in the same office with the same corporate phone could be on the same wifi so I think that would fire false negatives instead.
Is there another way to determine the device is opening it multiple times? Ideally if it sent a unique identifier or something, that would be very useful.
Is there a way to force the app to cache the image (this would heavily reduce the misfires) via say some response header?

Captive portal without internet on Android

Good day.
I need Captive Portal on the WiFi hotspot that will work without internet and popup a notification or open a login page automatically.
I am using Mikrotik with RouterOS 6.27.
I created hotspot and then added a RegExp in DNS like
.* = HOTSPOT_IP_ADDRESS
It works fine in Windows and iOS since their captive portal detection is based on getting the response from some website. Afaik - any response.
But for Android it must be some special response, with empty content or status code 204 - I am still not sure.
I tried to emulate google pages which give 204 or empty response and did redirection to my server with this emulation pages but it did not help Android to show notification.
So I need help to make captive portal notification in Android without internet.
Thanks.
Everytime your phone gets associated to the APs it will send an initial test URL request. It's a feature of Android to detect that it is trapped and offer to take the user to the splash page so the user can login and release from the trap.
Just make sure that Android's test URL file is allowed to pass the walled garden.
For reference, default Android 4.0.1 AOSP test URLs is http://clients3.google.com/generate_204, which always returns a 204 response code. Even if DNS has been interfered with since in that case a 200 code will be returned instead of the expected 204.
Also, there are some variations with fetching http://www.google.com/blank.html, which will return a 200 code with zero-length response body. So if you get a non-empty body this would be another way to figure out that you are behind a walled garden.

How to share text or image from ios app to Yammer

I need to share the text or image from one ios app to Yammer social network.
I am able to do login using iOS SDK of Yammer but not getting how can I share text or image from ios app to Yammer. I got the code to share text from browser but not from application.
Anybody has any idea??
Thanks in advance for your help and efforts.
This is documented on the Yammer API page. In order to post text and attach image
https://developer.yammer.com/v1.0/docs/messages-json-post
Parameters:
body - The text of the message body.
attachmentn and pending_attachmentn - Yammer provides two methods to associate attachments with a message. Both make use of multi-part HTTP upload (see RFC1867).
The first method is the easiest, simply use file form elements with names attachment1 through attachment20. If there are a several attachments or the attachments are large it may take some time for a message to POST causing your application to appear to hang.
An alternative way is to use the Pending Attachments resource (see below for details) allowing attachments to be uploaded in parallel. Apps that support HTTP chunked transfer encoding can monitor the progress of each upload. On success each pending attachment’s response body includes an id. These pending attachment ids are to be submitted with the message using form elements pending_attachment1 through pending_attachment20. Finally, if form elements for both attachmentN and pending_attachmentN are present only the pending_attachmentN elements will be honored.
I never used Yammer, but I wrote another app like Yammer used the given API, Yamme site should provide an API to share.

Html File In Messages App Not Viewing correctly

I have code that is generating an HTML file that is being sent via iMessage to another iPhone user. However, in the messages App on the receiving end, when they click on the HTML file, the formatting is super bare. (I know the HTML file works, because I forward it to a computer and it displays fine) There's none of the images displayed on the HTML file when viewed in the Messages App, and I have a Youtube video embedded that is not being displayed. My best guess is that the Messages app is stripping away all of this information... So how could I go about displaying my HTML file correctly? Could I somehow force it to open in Safari? I tried converting the HTML file to a PDF with no luck. Thanks.
Edit
Not possible. iMessage sends text messages as SMS, images or videos as MMS, which may incur extra cost to your user if they are not on WIFI. Never seen a HTML being sent with image and video before.
You can send the HTML file via email. And if you provide a link in your email, the Mail app will open it in Safari automatically.
There are many answers on sending mail from iPhone apps: one here

HTML5 application cache on iPad offline app - not working if server is unavailable?

I'm developing a small HTML5 web application for iPad that is intended to work in fullscreen mode (ie. it has the proprietary Apple meta tag, it is added to Home Screen):
<meta name="apple-mobile-web-app-capable" content="yes" />
The application basically fetches some data via AJAX and presents it to the user. The AJAX data are external (from a different domain, different server). I have the system setup for cross-origin requests, they work in online mode. In other words: the static data lie on server A, the dynamic data - on server B.
I created a proper cache manifest file, listing all static content of the site (HTML, CSS, images, JS) and then having the NETWORK: * section at the end - this way all the dynamic content (AJAX) is always retrieved from the network. The application fails "gracefully" if the requests fail, by displaying some fake content.
With the above setup, the following happens:
If I run the application while online, everything works ;)
If I disable the WiFi on iPad (pure offline mode), everything works as expected - the application falls back to the offline content
If I connect to the network again, but take the static-content server offline (the one that has everything cached), the application won't start; after spending a while in splash-screen, it shows me the a popup with <app> could not be opened because it could not connect to the server.; I can either choose Close or Retry.
The point 3 of the above is the one that drives me crazy because it was the only reason I started fiddling with application cache. Why doesn't the iPad web app fall back to cached content if the manifest file is not reachable? (not 404, the server is offline)
Is the answer to HTML5 iphone offline webapp completely incorrect? If not, how can I achieve this behavior on iPad?
Point 2 and 3 are completely different scenarios, so we cannot expect the same behavior.
In point 3, the device cannot fall back to the cached content when in online mode because if it do so, there will be no way to know for the user whether he is connected to the server or not.
I mean, in offline mode, the user knows it, and knows that he is with cached data. But in online mode, he expects to get the stuff from the server. If the server is not available, the user should be aware of this. If the server is not available and he is sent directly to cached data, the server error will be hidden to him, thinking that he is connected when he is actually not.
For example, web browsers can cache pages to be seen in offline mode. But if we are in online mode and try to open an unavailable page, we expect to see the error message, not a cached version of the page without any warning. We can go to offline mode to see the cached page if we want, but the correct behavior is to show the error to the user.

Resources