MeWe Open API Developer Preview

Embedded Communication

Besides the REST API available for the Standalone Apps, Embedded apps have additional way of communication with the MeWe host application using the postMessage API. This enables secure, cross-origin communication which simplifies the authentication and provides additional functionalities for the developers in order to achieve better UX.

Overview

When your app is embedded within MeWe, it runs in an iframe and needs to communicate with the parent MeWe application. This communication is handled through the browser's postMessage API, which allows secure messaging between different origins.

Besides the AUTH types of messages which have a unique purpose, other messages follow a naming convention that indicates the direction of communication:

  • CLIENT prefix — Messages sent by your embedded app (the client)
  • HOST prefix — Messages sent by the MeWe application (the host)
Your App
(iframe)
CLIENT_*
HOST_*
MeWe
(host)
Communication via postMessage

The embedded communication protocol supports various message types for different purposes:

Authentication Messages

  • CLIENT_HANDSHAKE_REQUEST — Sent by your embedded app to initiate authentication
  • HOST_HANDSHAKE_RESPONSE — Sent by MeWe in response, containing the authentication token

Display Management Messages

  • CLIENT_DISPLAY_REQUEST — Request display information from MeWe
  • HOST_DISPLAY_RESPONSE — Receive display information including dimensions and state
  • CLIENT_DISPLAY_UPDATE — Request to update the app's display dimensions

Lifecycle Messages

  • HOST_APP_PAUSED — Notifies your app that it has been paused
  • HOST_APP_RESUMED — Notifies your app that it has been resumed
  • HOST_APP_CLOSED — Notifies your app that it has been closed
  • HOST_APP_MINIMIZED — Notifies your app that it has been minimized
  • HOST_APP_MAXIMIZED — Notifies your app that it has been maximized

CLIENT_HANDSHAKE_REQUEST

The CLIENT_HANDSHAKE_REQUEST message is sent by your embedded app to request loginRequestToken from the MeWe host application.

When to Send

Send this message during your app's initialization, typically when:

  • Your app detects it's running inside MeWe (e.g., via URL parameters)
  • You need to obtain a loginRequestToken for authentication
  • Your app first loads or when authentication is required

Message Format

window.parent.postMessage({ type: 'CLIENT_HANDSHAKE_REQUEST' }, '*');

Message Properties

Name
Type
Description
type*
string

Must be exactly "CLIENT_HANDSHAKE_REQUEST". This identifies the message type to the MeWe host application.

Example Implementation

// Send the handshake request
function requestAuthentication() {
  window.parent.postMessage({ type: 'CLIENT_HANDSHAKE_REQUEST' }, '*');
}

// Call during app initialization
requestAuthentication();

HOST_HANDSHAKE_RESPONSE

The HOST_HANDSHAKE_RESPONSE message is sent by MeWe in response to your CLIENT_HANDSHAKE_REQUEST request. It contains the loginRequestToken needed to authenticate your app.

When You Receive It

You'll receive this message after sending CLIENT_HANDSHAKE_REQUEST. MeWe will respond with the authentication token once the user has approved your app's permissions (which happens before the app launches for embedded apps).

Message Format

{
  type: 'HOST_HANDSHAKE_RESPONSE',
  loginRequestToken: 'string'
}

Message Properties

Name
Type
Description
type*
string

Always "HOST_HANDSHAKE_RESPONSE". Identifies this as the response message from MeWe.

loginRequestToken*
string

The authentication token that you'll exchange for an apiToken using the /api/dev/token endpoint.

Example Implementation

// Set up message listener
function setupMessageListener() {
  window.addEventListener('message', (event) => {
    const { type, loginRequestToken } = event.data;

    if (type === 'HOST_HANDSHAKE_RESPONSE' && loginRequestToken) {
      // Remove the listener once we receive the token
      window.removeEventListener('message', setupMessageListener);

      // Use the loginRequestToken to get an apiToken
      exchangeTokenForApiToken(loginRequestToken);
    }
  });
}

// Start listening for messages
setupMessageListener();

CLIENT_DISPLAY_REQUEST

The CLIENT_DISPLAY_REQUEST message is sent by your embedded app to request display information from the MeWe host application. This includes the app's dimensions, available space, and current state.

When to Send

Send this message when you need to:

  • Get the current dimensions of your app
  • Determine the available viewport space for your content
  • Check if the app is minimized or paused
  • Adjust your UI layout based on available space

Message Format

window.parent.postMessage({ type: 'CLIENT_DISPLAY_REQUEST' }, '*');

Message Properties

Name
Type
Description
type*
string

Must be exactly "CLIENT_DISPLAY_REQUEST". This identifies the message type to the MeWe host application.

Example Implementation

function requestDisplayInfo() {
  window.parent.postMessage({ type: 'CLIENT_DISPLAY_REQUEST' }, '*');
}

// Request display info when needed
requestDisplayInfo();

HOST_DISPLAY_RESPONSE

The HOST_DISPLAY_RESPONSE message is sent by MeWe in response to your CLIENT_DISPLAY_REQUEST. It contains detailed information about the app's display dimensions and current state.

When You Receive It

You'll receive this message after sending CLIENT_DISPLAY_REQUEST. Use this information to adjust your app's layout and understand the available space.

Message Format

{
  type: 'HOST_DISPLAY_RESPONSE',
  width: 400,
  height: 600,
  availableWidth: 368,
  viewportHeight: 568,
  isMinimized: false,
  isPaused: false
}

Message Properties

Name
Type
Description
type*
string

Always "HOST_DISPLAY_RESPONSE". Identifies this as the response message from MeWe.

width*
number

The current width of the app in pixels.

height*
number

The current height of the app in pixels.

availableWidth*
number

The available width for your content (usually same as viewport width but might account for space reserved by MeWe for app controls or spacing around the Embedded app).

viewportHeight*
number

The available viewport height for your content (usually same as viewport height but might account for space reserved by MeWe for app controls or spacing around the Embedded app).

isMinimized*
boolean

Indicates whether the app is currently minimized.

isPaused*
boolean

Indicates whether the app is currently paused (e.g., showing a close confirmation dialog).

Example Implementation

window.addEventListener('message', (event) => {
  const { type, width, height, availableWidth, viewportHeight, isMinimized, isPaused } = event.data;

  if (type === 'HOST_DISPLAY_RESPONSE') {
    // Adjust your layout based on available space
    updateLayout({
      appWidth: width,
      appHeight: height,
      contentWidth: availableWidth,
      contentHeight: viewportHeight,
      minimized: isMinimized,
      paused: isPaused
    });
  }
});

CLIENT_DISPLAY_UPDATE

The CLIENT_DISPLAY_UPDATE message is sent by your embedded app to request a change in the app's display dimensions.

When to Send

Send this message when you need to:

  • Resize the app to better fit your content
  • Adjust the app size based on user interactions
  • Optimize the display for different content types

Message Format

window.parent.postMessage(
  {
    type: 'CLIENT_DISPLAY_UPDATE',
    width: 500,  // Optional
    height: 700   // Optional
  },
  '*'
);

Message Properties

Name
Type
Description
type*
string

Must be exactly "CLIENT_DISPLAY_UPDATE". This identifies the message type to the MeWe host application.

width
number

The desired width in pixels. Must be at least 80px. If not provided, the current width is maintained.

height
number

The desired height in pixels. Must be at least 80px. If not provided, the current height is maintained.

Example Implementation

function resizeApp(newWidth, newHeight) {
  window.parent.postMessage({
    type: 'CLIENT_DISPLAY_UPDATE',
    width: newWidth,
    height: newHeight
  }, '*');
}

// Resize to fit content
resizeApp(600, 800);

HOST_APP_PAUSED

The HOST_APP_PAUSED message is sent by MeWe to notify your embedded app that it has been paused. This typically occurs when the app needs to be temporarily suspended, such as when a close confirmation dialog is shown.

When You Receive It

You'll receive this message when:

  • The user triggers a close action and a confirmation dialog is displayed
  • The app needs to be temporarily suspended for system reasons
  • The host application needs to pause your app's activity

Message Format

{
  type: 'HOST_APP_PAUSED'
}

Message Properties

Name
Type
Description
type*
string

Always "HOST_APP_PAUSED". Identifies this as a lifecycle event from MeWe.

Example Implementation

window.addEventListener('message', (event) => {
  const { type } = event.data;

  if (type === 'HOST_APP_PAUSED') {
    // Pause animations, timers, or other active processes
    pauseAnimations();
    clearTimers();
    // Save state if needed
    saveCurrentState();
  }
});

HOST_APP_RESUMED

The HOST_APP_RESUMED message is sent by MeWe to notify your embedded app that it has been resumed after being paused.

When You Receive It

You'll receive this message when:

  • The user cancels the close confirmation dialog
  • The app is resumed after being paused
  • The host application allows your app to continue activity

Message Format

{
  type: 'HOST_APP_RESUMED'
}

Message Properties

Name
Type
Description
type*
string

Always "HOST_APP_RESUMED". Identifies this as a lifecycle event from MeWe.

Example Implementation

window.addEventListener('message', (event) => {
  const { type } = event.data;

  if (type === 'HOST_APP_RESUMED') {
    // Resume animations, timers, or other active processes
    resumeAnimations();
    restartTimers();
    // Restore state if needed
    restoreState();
  }
});

HOST_APP_CLOSED

The HOST_APP_CLOSED message is sent by MeWe to notify your embedded app that it has been closed by the user.

When You Receive It

You'll receive this message when:

  • The user confirms closing the app
  • The app is being terminated
  • Cleanup is needed before the app is removed

Message Format

{
  type: 'HOST_APP_CLOSED'
}

Message Properties

Name
Type
Description
type*
string

Always "HOST_APP_CLOSED". Identifies this as a lifecycle event from MeWe.

Example Implementation

window.addEventListener('message', (event) => {
  const { type } = event.data;

  if (type === 'HOST_APP_CLOSED') {
    // Perform cleanup tasks
    cleanup();
    // Save any final state
    saveFinalState();
    // Stop all timers and listeners
    stopAllTimers();
    window.removeEventListener('message', messageHandler);
  }
});

HOST_APP_MINIMIZED

The HOST_APP_MINIMIZED message is sent by MeWe to notify your embedded app that it has been minimized.

When You Receive It

You'll receive this message when:

  • The user minimizes the app
  • The app is collapsed to save screen space

Message Format

{
  type: 'HOST_APP_MINIMIZED'
}

Message Properties

Name
Type
Description
type*
string

Always "HOST_APP_MINIMIZED". Identifies this as a lifecycle event from MeWe.

Example Implementation

window.addEventListener('message', (event) => {
  const { type } = event.data;

  if (type === 'HOST_APP_MINIMIZED') {
    // Optionally pause non-essential operations
    pauseNonEssentialOperations();
    // Update UI to reflect minimized state
    updateUIForMinimized();
  }
});

HOST_APP_MAXIMIZED

The HOST_APP_MAXIMIZED message is sent by MeWe to notify your embedded app that it has been maximized or restored from minimized state.

When You Receive It

You'll receive this message when:

  • The user maximizes the app
  • The app is restored from minimized state

Message Format

{
  type: 'HOST_APP_MAXIMIZED'
}

Message Properties

Name
Type
Description
type*
string

Always "HOST_APP_MAXIMIZED". Identifies this as a lifecycle event from MeWe.

Example Implementation

window.addEventListener('message', (event) => {
  const { type } = event.data;

  if (type === 'HOST_APP_MAXIMIZED') {
    // Resume any paused operations
    resumeOperations();
    // Update UI to reflect maximized state
    updateUIForMaximized();
    // Optionally request updated display info
    window.parent.postMessage({ type: 'CLIENT_DISPLAY_REQUEST' }, '*');
  }
});

Complete Authentication Flow

Here's a complete example showing how to use both authentication messages together:

async function authenticateEmbeddedApp() {
  return new Promise((resolve, reject) => {
    // Set up message listener first
    const handler = (event) => {
      const { type, loginRequestToken } = event.data;

      if (type === 'HOST_HANDSHAKE_RESPONSE' && loginRequestToken) {
        window.removeEventListener('message', handler);
        resolve({ loginRequestToken });
      }
    };

    window.addEventListener('message', handler);

    // Send the handshake request
    window.parent.postMessage({ type: 'CLIENT_HANDSHAKE_REQUEST' }, '*');

    // Optional: Set a timeout to handle cases where no response is received
    setTimeout(() => {
      window.removeEventListener('message', handler);
      reject(new Error('Authentication timeout'));
    }, 10000); // 10 second timeout
  });
}

// Usage
try {
  const { loginRequestToken } = await authenticateEmbeddedApp();

  // Exchange loginRequestToken for apiToken
  const response = await fetch('MEWE_HOST/api/dev/token?loginRequestToken=' + loginRequestToken, {
    headers: {
      'X-App-Id': 'YOUR_APP_ID'
    }
  });

  const { apiToken } = await response.json();
  // Use apiToken for authenticated API requests
} catch (error) {
  console.error('Authentication failed:', error);
}

Security Considerations

  1. Origin Validation: Always validate the origin of incoming messages when possible:

    window.addEventListener('message', (event) => {
      // Validate origin in production
      if (event.origin !== 'https://mewe.com') {
        return;
      }
      // Process message...
    });
    
  2. Message Type Validation: Always check the message type before processing:

    if (event.data.type !== 'HOST_HANDSHAKE_RESPONSE') {
      return; // Ignore unexpected message types
    }
    
  3. Token Security: Never expose your loginRequestToken or apiToken in client-side code logs or error messages.

Was this page helpful?