Skip to main content

Internet Access

Spectacles offers APIs to access the internet so you can access external APIs, open WebSocket connections, download media, and more.

Privacy Note: Accessing the internet in a Lens will disable access to privacy-sensitive user information in that Lens, such as the camera frame, location, and audio. For testing and experimental purposes however, extended permissions are available to access both the camera frame and the open internet at the same time. Note that lenses built this way may not be released publicly. Please see Extended Permissions doc for more information.

The RemoteServiceModule enables developers to access the internet via HTTPS requests. There are two methods available to make these requests: fetch and performHttpRequest. For most cases we recommend using fetch.

Fetch

Spectacles offers the standardized Fetch API to make HTTPS requests on the open internet. This API is based on the MDN reference.

Prerequisites

  • Lens Studio v5.3.0 or later
  • Spectacles OS v5.58.6621 or later

This API is only available on Spectacles.

Usage

To use the Fetch API add the RemoteServiceModule to your project and include it in your scripts as per the examples below.

The Fetch API will only work in the Preview window if the Device Type Override is set to Spectacles. Otherwise all requests will return 404.

To send a request, invoke the fetch method.

For example:

@component
export class FetchExampleGET extends BaseScriptComponent {
@input remoteServiceModule: RemoteServiceModule;

// Method called when the script is awake
async onAwake() {
let request = new Request('[YOUR URL]', {
method: 'GET',
});
let response = await this.remoteServiceModule.fetch(request);
if (response.status == 200) {
let text = await response.text();
// Handle response
}
}
}

Fetch can also send Get, Post, Delete, and Put requests.

Below is a more detailed example that issues a Post request with headers and parses the response in JSON.

@component
export class FetchExamplePOST extends BaseScriptComponent {
@input remoteServiceModule: RemoteServiceModule;

async onAwake() {
let request = new Request('[YOUR URL]', {
method: 'POST',
body: JSON.stringify({ user: { name: 'user', career: 'developer' } }),
headers: {
'Content-Type': 'application/json',
},
});

let response = await this.remoteServiceModule.fetch(request);
if (response.status != 200) {
print('Failure: response not successful');
return;
}

let contentTypeHeader = response.headers.get('Content-Type');
if (!contentTypeHeader.includes('application/json')) {
print('Failure: wrong content type in response');
return;
}

let responseJson = await response.json();
let username = responseJson.json['user']['name'];
let career = responseJson.json['user']['career'];
}
}

If you'd like even more detail, see here for a sample project that fully utilizes Fetch API.

Compatibility

The Fetch API supports all methods in the standard, with the following exceptions:

  1. The Request constructor does not support taking another Request as input; it only takes a URL.

  2. Request and Response bodies can be retrieved via bytes, text, and json. The body, blob, and arrayBuffer properties are not yet supported.

  3. Other properties related to web browser functionality are not supported. The full list of supported/unsupported properties is provided in the tables below.

    RequestResponseHeaders
    Request(input, options)Response()Headers()
    bodybodyappend()
    bodyUsedbodyUseddelete()
    cacheheadersentries()
    credentialsokforEach()
    destinationredirectedget()
    headersstatusgetSetCookie()
    integritystatusTexthas()
    isHistoryNavigationtypekeys()
    keepaliveurlset()
    methodarrayBuffer()values()
    modeblob()
    redirectbytes()
    referrerclone()
    referrerPolicyformData()
    signaljson()
    urltext()
    arrayBuffer()
    blob()
    bytes()
    clone()
    formData()
    json()
    text()

PerformHttpRequest

The performHttpRequest method can also be used to send HTTPS requests.

PerformHttpRequest is a simpler API with less functionality, provided for compatibility reasons. We recommend using fetch instead.

To use performHttpRequest, create a RemoteServiceHttpRequest, configure it, and send it via the RemoteServiceModule.

For example:

@component
export class GetCatFacts extends BaseScriptComponent {
@input
remoteServiceModule: RemoteServiceModule;

// Method called when the script is awake
onAwake() {
// Create a new HTTP request
let httpRequest = RemoteServiceHttpRequest.create();
httpRequest.url = 'https://catfact.ninja/facts'; // Set the URL for the request
httpRequest.method = RemoteServiceHttpRequest.HttpRequestMethod.Get; // Set the HTTP method to GET

// Perform the HTTP request
this.remoteServiceModule.performHttpRequest(httpRequest, (response) => {
if (response.statusCode === 200) {
// Check if the response status is 200 (OK)
print('Body: ' + response.body);
}
});
}
}

The RemoteServiceHttpRequest can send Get, Post, Delete, and Put requests. The URL for the request must be specified, and be sure to set the apiSpecId to “http” as shown below.

Headers can be set via setHeader(name, value). Below is an example that utilizes request headers for authorization:

var httpRequest = RemoteServiceHttpRequest.create();
httpRequest.url = '[YOUR URL]';
httpRequest.method = RemoteServiceHttpRequest.HttpRequestMethod.Post;
httpRequest.setHeader('Content-Type', 'application/x-www-form-urlencoded');
httpRequest.setHeader('Authorization', `Basic ${encodedCredentials}`);
httpRequest.body = 'grant_type=client_credentials';

script.remoteServiceModule.performHttpRequest(httpRequest, function (response) {
print('Status code: ' + response.statusCode);
print('Content type: ' + response.contentType);
print('Body: ' + response.body);
print('Headers: ' + response.headers);
print('Header(date): ' + response.getHeader('date'));
print('Header(contenttype): ' + response.getHeader('content-type'));
});

Accessing Remote Media

To download media (Image, Video, glTF, and audio), utilize the makeResourceFromUrl method to create a Resource out of the URL, then pass that resource into the appropriate method in RemoteMediaModule. For example:

@component
export class GetHttpImage extends BaseScriptComponent {
@input
remoteServiceModule: RemoteServiceModule;

// Import the RemoteMediaModule
private remoteMediaModule: RemoteMediaModule = require('LensStudio:RemoteMediaModule');

// Method called when the script is awake
onAwake() {
// Create a new HTTP request
let httpRequest = RemoteServiceHttpRequest.create();
httpRequest.url =
'https://developers.snap.com/img/spectacles/spectacles-2024-hero.png'; // Set the URL for the request
httpRequest.method = RemoteServiceHttpRequest.HttpRequestMethod.Get; // Set the HTTP method to GET

// Perform the HTTP request
this.remoteServiceModule.performHttpRequest(httpRequest, (response) => {
if (response.statusCode === 200) {
// Check if the response status is 200 (OK)
let textureResource = response.asResource(); // Convert the response to a resource
this.remoteMediaModule.loadResourceAsImageTexture(
textureResource,
(texture) => {
// Assign texture to a material
print(texture);
},
(error) => {
print('Error loading image texture: ' + error); // Print an error message if loading fails
}
);
}
});
}
}

The RemoteMediaModule can be used this way to load the following media types:

Media TypeMethodReturned Class
ImageloadResourceAsImageTextureAsset.Texture
VideoloadResourceAsVideoTextureAsset.Texture
glTFloadResourceAsGltfAssetAsset.GltfAsset
audioloadResourceAsAudioTrackAssetAsset.AudioTrackAsset

Internet Availability

Spectacles allows you to detect and respond to changes of internet availability status. This can help you avoid frozen, empty, or broken experiences and clearly indicate that the internet is needed for some functionality to work.

Prerequisites

  • Lens Studio v5.7.0 or later
  • Spectacles OS v5.60.x or later

The isInternetAvailable method of DeviceInfoSystem checks the current status of the internet connection. It returns a boolean value: True if internet is available. False if internet is not available.

This function is typically used to determine the initial state of the internet connection upon lens starts. It can also be used to determine internet availability at an arbitrary time.

The onInternetStatusChanged is an event, retrieved from DeviceInfoSystem, that triggers whenever there is a change in the internet connection status. It allows the application to respond dynamically to changes in connectivity.

Features as Text-to-Speech, Speech-to-Text, Connected Lenses, Web View, Bitmoji Module, Location Cloudstorage, Map, Leaderboard, requires Internet Connection.

@component
export class NewScript extends BaseScriptComponent {
@input textObject: Text;

onAwake() {
this.textObject.text = global.deviceInfoSystem.isInternetAvailable()
? 'Internet is available'
: 'No internet';

global.deviceInfoSystem.onInternetStatusChanged.add((args) => {
this.textObject.text = args.isInternetAvailable
? 'UPDATED: Internet is available'
: 'UPDATED: No internet';
});
}
}
Was this page helpful?
Yes
No