SMeetMini Apps

SMeet Mini Apps

Operations

What to watch and what to do once the Mini App is live: limits that answer 429, a pause that answers maintenance, a window that cannot reach your page, and keys that have to change.

Limits#

WhatLimit
Opening the window10 a minute per person; 50 a second per Mini App
Login codes (authorize())60 a minute per person
Exchange and session checks50 a second per key, 200 a second per Mini App
Results to the bot (submitToBot())1 a second and 20 a minute per person in a Mini App; 10 a second per Mini App; 20 a second per owner
A result16 KiB of JSON
A bridge message64 KiB; 20 requests a second per page
A request to the author API64 KiB
Testers20 per Mini App
Keys2 active per environment

Over a limit, the page gets RATE_LIMITED and your server gets 429 RATE_LIMITED with retry_after. A result waits in the bot's queue for 7 days at most, like every update; a bot that has not received it by then loses it.

The platform may set other limits for a single Mini App: opening it, login codes of a person in it, the calls of your server per key and per Mini App, results per Mini App and results a minute per person in it; and another total rate of results for all Mini Apps of one owner. The limits of a person across every Mini App, one result a second per person, and the totals of the platform are the same for every Mini App.

Limits of an installation#

Whoever runs a SMeet installation sets the defaults in the environment of the bots service. A rate is a number of requests a second or a minute, a burst a whole number of requests at once. The limits the platform administrator sets for one Mini App or one owner replace only the defaults of their own group; an empty set returns to the defaults.

VariableDefaultWhatSet for
BOTS_MINIAPPS_LIMITS_LAUNCHESPERSECONDPERAPP, BOTS_MINIAPPS_LIMITS_BURSTLAUNCHESPERAPP50, 50openings a second per Mini Appone Mini App
BOTS_MINIAPPS_LIMITS_CODESPERMINUTEPERPERSONINAPP60login codes a minute per person in one Mini Appone Mini App
BOTS_MINIAPPS_LIMITS_AUTHORCALLSPERSECONDPERKEY, BOTS_MINIAPPS_LIMITS_BURSTAUTHORCALLSPERKEY50, 50calls of the author API a second per keyone Mini App
BOTS_MINIAPPS_LIMITS_AUTHORCALLSPERSECONDPERAPP, BOTS_MINIAPPS_LIMITS_BURSTAUTHORCALLSPERAPP200, 200calls of the author API a second per Mini Appone Mini App
BOTS_MINIAPPS_LIMITS_SUBMISSIONSPERMINUTEPERPERSON20results a minute per person in one Mini Appone Mini App
BOTS_MINIAPPS_LIMITS_SUBMISSIONSPERSECONDPERAPP, BOTS_MINIAPPS_LIMITS_BURSTSUBMISSIONSPERAPP10, 10results a second per Mini Appone Mini App
BOTS_MINIAPPS_LIMITS_SUBMISSIONSPERSECONDPEROWNER, BOTS_MINIAPPS_LIMITS_BURSTSUBMISSIONSPEROWNER20, 20results a second of all Mini Apps of one ownerone owner
BOTS_MINIAPPS_LIMITS_LAUNCHESPERMINUTEPERPERSON10openings a minute per person, every Mini App togetherthe installation
BOTS_MINIAPPS_LIMITS_CODESPERMINUTEPERPERSON60login codes a minute per person, every Mini App togetherthe installation
BOTS_MINIAPPS_LIMITS_SUBMISSIONSPERSECONDPERPERSON1results a second per person in one Mini Appthe installation
BOTS_MINIAPPS_LIMITS_LAUNCHESPERSECOND, BOTS_MINIAPPS_LIMITS_AUTHORCALLSPERSECOND, BOTS_MINIAPPS_LIMITS_SUBMISSIONSPERSECOND200, 1000, 100openings, calls of the author API and results a second, all Mini Apps togetherthe installation

Errors and what to do#

WhereCodeWhat to do
PageNOT_READY from connect()the window shows an error screen; the person retries there
PageLAUNCH_CLOSEDstop; SMeet tells the person why
PageMAINTENANCEsay the app is unavailable for a while; keep the draft
PageCODE_EXPIRED, NETWORKcall the method again
PageQUEUE_FULL, RATE_LIMITEDkeep the draft and its requestId; repeat later. A RATE_LIMITED after three presses of Cancel in a row lasts until the person opens the app again (Errors)
ServerINVALID_CREDENTIALSthe key is wrong or revoked; fix the configuration, do not retry
ServerAPP_MISMATCH, ENVIRONMENT_MISMATCHthe key belongs to another app or environment
ServerCODE_*the page signs in again
ServerACCESS_DENIED, checkSession with active: falsethe person may not use the app now; show why, by reason
ServerTEMPORARILY_UNAVAILABLE, RATE_LIMITED, 502, 503, 504repeat the same request with the same key after retry_after
ServerMINI_APPS_MAINTENANCE, reason: maintenancethe platform is paused; repeat later
BotACCESS_REVISION_CONFLICT, BOT_STOPPED_OR_BLOCKEDthe conversation changed or ended: do not resend

Every code: the bridge, the author API, the Bot API.

Diagnostics#

Diagnostics on the Mini App's screen in My bots shows the checks of both addresses (the domain and embedding) and the numbers of the last seven UTC days, today included, for the production and the test version:

LineWhat it counts
Openingswindows opened
Pages that became readypages that called ready()
Pages that did not become ready in timepages that did not call ready() within 15 seconds
Blocked from showing in a framepages that did not connect within 15 seconds of loading, as when embedding is refused (When the window shows an error)
Loginslogin codes your server exchanged
Results sent to the botresults the bot's queue accepted
Requests over the limitsrequests refused with RATE_LIMITED

Below the table, the refusals by code: the codes SMeet refused a person's opening, login code or result with, and the codes your server got from the author API. The numbers name no people. The numbers of windows, logins and results are those of the last hourly roll-up; the refusals and the requests over the limits, those of the last minute. No data yet means every number is zero.

The screen reads the numbers as diagnostics of the Mini App: from and to are the UTC days YYYY-MM-DD of the period; opens, ready, readyTimeouts, embedBlocked, logins, submissions and rateLimited are each {"production": n, "test": n}; refusals is {"production": {"CODE": n}, "test": {"CODE": n}}.

The icon in the catalog#

The catalog shows the icon to everyone, signed in or not, from https://messenger.scrile.com/graphql/image-thumbnails/mini-app-icons/<appId>/<size>, a PNG of 48, 64, 96, 128, 192 or 256 pixels (96 when the size is left out). It answers only for a published Mini App of SMeet's public space, and only with a PNG, JPEG, GIF or WebP icon; for anything else, an SVG icon included, it answers 404, and the catalog shows the first letter of the title. A new icon keeps the address, so browsers may show the old one for a minute; a Mini App that is paused, blocked or no longer published loses its icon there within a minute. Inside SMeet, the consent screen shows the icon of the version the person opens, the test version included; the bot's profile shows the icon of the published version.

Rotating keys#

An environment has up to two active keys, so a key changes without a pause:

  1. Issue a second key in Keys of your server. It is shown once; put it into the server's environment.
  2. Restart or redeploy the server with the new key, and check that sign-in works.
  3. Revoke the old key. From that moment it gets 401 INVALID_CREDENTIALS.

Sessions made with the old key stay valid until they expire. When a key may have leaked, revoke it at once, even before the new one is deployed: sign-in stops until then, the person's data stays safe. The token of the bot is separate and is changed in My bots (Managing your bot).

Pausing and deleting#

  • Pause the mini app stops it: nobody can open it, and open windows close. Resume the mini app brings it back. A paused app cannot be sent for review.
  • Delete the mini app is final. Open windows close on every device, the keys of your server stop working, testers lose access, and results the bot has not received yet are cancelled. The bot and its chats stay.
  • An app blocked by SMeet cannot be deleted, and a new app for the same bot is created blocked. The letter about a block names the reason; questions go to support@scrile.com.

A pause of the platform#

SMeet can pause Mini Apps or bots for maintenance. Meanwhile:

  • the page gets MAINTENANCE from its calls, and new windows do not open;
  • exchangeLaunchCode answers 503 MINI_APPS_MAINTENANCE with retry_after 30;
  • checkSession answers active: false, reason: maintenance;
  • revokeSession keeps working.

Keep drafts and their requestId, tell the person the app is unavailable for a while, and let them repeat later. Nothing is lost on SMeet's side: results already accepted wait in the bot's queue.

When the window shows an error#

The window saysWhat happenedWhat to check
"The app is not responding or does not allow embedding"the page did not connect within 15 seconds of loadingthe frame-ancestors header, that the address answers 2xx without a redirect, that the SDK is loaded in <head> of the page
"The app is not responding"the page connected but did not call ready() within 15 secondscall ready() as soon as the first screen is drawn, before slow requests
"The page left <domain> or is not responding"the page went to another origin, or stopped answering for over 2 secondslinks to other sites go through openExternalLink; no long synchronous work in the page

The first two screens offer Retry (the first one also Open in browser without signing in); the third offers Back to the app. The person can also Reload from the menu.

Request ids#

Every answer of the author API carries X-Request-Id, and every error also request_id in its body. Log it with the method and the code, and quote it when you write to support@scrile.com. An answer of SMeet's proxy (429, 413) has an empty request_id.

Logs#

Login codes, verifiers, session tokens, keys, attempt secrets and the bodies that carry them never go into a log, yours or a library's. Log the method, the path without the query string, the status, the code and request_id. People's form data belongs in your database, not in your logs.