Quickstart
For this quickstart guide, you will integrate the Avatar Creator into a website using Streamoji Avatars APIs. It takes less than 5 minutes!
Note: You can use this method for integrating with any stack that supports REST and postMessage.
Embed the Avatar Creator into a web page
- Create a new
.htmlfile in a text editor. - Copy and paste the code below into the file and save it.
- Open the file in a web browser.
- Enter your Client-Id and Client-Secret from the developer console.
- Click Get Auth Token to generate a session token.
- Click Open Streamoji Avatars. The Avatar Creator iFrame opens.
- Create an avatar.
- After creating the avatar, you'll receive the avatar URL. You can then use the Download Avatar button to fetch the final GLB file.
See the example code for details.
Example code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Streamoji Integration</title>
<style>
html,
body,
.frame {
width: 1080px;
height: 800px;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans,
Droid Sans, Helvetica Neue, sans-serif;
padding: 20px;
font-size: 14px;
border: none;
}
.auth-container {
margin: 20px 0;
padding: 15px;
border: 1px solid #ddd;
border-radius: 8px;
max-width: 500px;
}
.auth-container input[type="text"] {
width: 100%;
padding: 8px;
margin: 5px 0 15px 0;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.security-warning {
color: #ef4444;
font-size: 12px;
margin-top: -10px;
margin-bottom: 10px;
display: block;
}
#tokenDisplay {
word-break: break-all;
background: #f4f4f4;
padding: 10px;
border-radius: 4px;
font-family: monospace;
margin: 10px 0;
font-size: 12px;
display: none;
}
</style>
</head>
<body>
<h2>Streamoji avatars iframe example</h2>
<ul>
<li>Click the "Open Streamoji avatars" button.</li>
<li>Create an avatar and click the "Done" button when you're done customizing.</li>
<li>After creation, this parent page receives the URL to the avatar.</li>
<li>The Streamoji avatars window closes and the URL is displayed.</li>
</ul>
<div class="auth-container">
<label for="clientId">Client-Id:</label>
<input type="text" id="clientId" placeholder="Enter your Client-Id" />
<label for="clientSecret">Client-Secret:</label>
<input type="text" id="clientSecret" placeholder="Enter your Client-Secret" />
<span class="security-warning">(this must be called from your backend ideally)</span>
<label for="userId">User-Id:</label>
<input type="text" id="userId" value="user_789" placeholder="Enter User-Id" />
<label for="userName">User-Name:</label>
<input type="text" id="userName" value="John Doe" placeholder="Enter User-Name" />
<input type="button" value="Get Auth Token" onClick="getAuthToken()" />
<div id="tokenDisplay"></div>
</div>
<input type="button" value="Open Streamoji Avatars" onClick="displayIframe()" />
<p id="avatarUrl">Avatar URL:</p>
<input type="button" id="downloadBtn" value="Download Avatar" onClick="downloadAvatar()" style="display: none;" />
<iframe id="frame" class="frame" allow="camera *; microphone *; clipboard-write" hidden></iframe>
<script>
const frame = document.getElementById('frame');
let authToken = '';
let currentAvatarId = '';
window.addEventListener('message', subscribe);
document.addEventListener('message', subscribe);
async function getAuthToken() {
const clientId = document.getElementById('clientId').value;
const clientSecret = document.getElementById('clientSecret').value;
const userId = document.getElementById('userId').value;
const userName = document.getElementById('userName').value;
const tokenDisplay = document.getElementById('tokenDisplay');
if (!clientId || !clientSecret || !userId || !userName) {
alert('Please enter all fields');
return;
}
try {
tokenDisplay.style.display = 'block';
tokenDisplay.innerText = 'Fetching token...';
const response = await fetch(
"https://us-central1-streamoji-265f4.cloudfunctions.net/getAuthToken",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"Client-Secret": clientSecret,
"Client-Id": clientId,
},
body: JSON.stringify({ userId, userName }),
}
);
const data = await response.json();
if (!data.success) {
throw new Error(data.error || "Auth token generation failed");
}
authToken = data.authToken;
tokenDisplay.innerText = 'Token: ' + authToken;
} catch (error) {
console.error('Error fetching token:', error);
tokenDisplay.innerText = 'Error: ' + error.message;
}
}
function subscribe(event) {
const json = parse(event);
if (json?.source !== 'streamojiavatars') {
return;
}
if (json.eventName === 'v1.frame.ready') {
frame.contentWindow.postMessage(
JSON.stringify({
target: 'streamojiavatars',
type: 'subscribe',
eventName: 'v1.**'
}),
'*'
);
}
if (json.eventName === 'v1.avatar.exported') {
const url = json.data.url;
console.log('Avatar URL: ' + url);
document.getElementById('avatarUrl').innerHTML = 'Avatar URL: ' + url;
document.getElementById('frame').hidden = true;
try {
const urlObj = new URL(url);
currentAvatarId = urlObj.searchParams.get('avatarId');
if (currentAvatarId) {
document.getElementById('downloadBtn').style.display = 'inline-block';
}
} catch (e) {
console.error('Error parsing avatar URL:', e);
}
}
}
async function downloadAvatar() {
if (!currentAvatarId || !authToken) {
alert('Avatar ID or Auth Token missing');
return;
}
const downloadBtn = document.getElementById('downloadBtn');
const originalValue = downloadBtn.value;
try {
downloadBtn.value = 'Downloading...';
downloadBtn.disabled = true;
const url = 'https://glb.streamoji.com/api/avatars/' + currentAvatarId + '.glb?token=' + authToken;
const response = await fetch(url, { method: 'GET' });
if (!response.ok) {
throw new Error('Download failed: ' + response.status);
}
const blob = await response.blob();
const downloadUrl = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = downloadUrl;
a.download = 'avatar-' + currentAvatarId + '.glb';
document.body.appendChild(a);
a.click();
a.remove();
window.URL.revokeObjectURL(downloadUrl);
} catch (error) {
console.error('Error downloading avatar:', error);
alert('Error: ' + error.message);
} finally {
downloadBtn.value = originalValue;
downloadBtn.disabled = false;
}
}
function parse(event) {
try {
return JSON.parse(event.data);
} catch (error) {
return null;
}
}
function displayIframe() {
let src = 'https://avatars.streamoji.com/createAvatar?iframe=true&bodyType=Full';
if (authToken) {
src += '&token=' + authToken;
}
frame.src = src;
document.getElementById('frame').hidden = false;
}
</script>
</body>
</html>