Client guide

Web & Mini Program development guide

A complete path through floo-web: choose a build, initialise and authenticate, manage contacts and groups, exchange every message type, receive events, and add voice & video.

Use lanying-im-web for desktop browsers, lanying-im-uniapp for H5 and multi-vendor Mini Programs, or lanying-im-miniprogram for a native WeChat Mini Program. These builds follow the same feature model, but transport and packaging settings differ.

Prerequisites and build selection

BuildTargetsConfiguration
lanying-im-webDesktop browsers and traditional front-end applicationsSet ws to false.
lanying-im-uniappH5 plus WeChat, Alipay, Baidu, ByteDance, QQ, DingTalk, and other uni-app targetsSet ws to true.
lanying-im-miniprogramNative WeChat Mini ProgramsUse the Mini Program package and platform network/storage adapters.
  1. Create an application in the console and copy its App ID.
  2. Download the matching floo-web or floo-uniapp release.
  3. For voice & video, install the runtime dependencies used by the Web demo, including webrtc-adapter.
  4. Choose one application-wide SDK instance; do not create a separate instance per view.

Initialise the SDK

SDK configurationjs
const config = {
  //dnsServer: "https://dns.lanying.chat/v2/app_dns",
  appid: "YOUR_APP_ID",
  ws: false, // true for uni-app, false for web
  autoLogin: true
  };

The module form is the preferred integration. The script form remains available for legacy pages, but the upstream demo documents an initialisation race that requires retry handling.

Module integrationjs
import flooim from 'floo-3.0.0';

const im = flooim(config);

Register, sign in, restore, and sign out

Register a userjs
im.userManage.asyncRegister(this.user).then(() => {
  console.log("注册成功");
}).catch(ex => {
  console.log(ex.message);
});
Password sign-injs
im.login({
  name, // User name
  password,
});

With autoLogin enabled, the SDK restores the previous session from local storage. In production, clear application-specific SDK state rather than unrelated origin storage, and coordinate sign-out with push-token unbinding on mobile containers.

Read the conversation listjs
const list = im.userManage.getConversationList();
console.log(list);

Contacts and relationship requests

TaskAPI
Send a contact requestrosterManage.asyncApply({ user_id, alias })
Accept or declinerosterManage.asyncAccept / asyncDecline
Delete a contactrosterManage.asyncDeleteRoster({ user_id })
Read cached contactsrosterManage.getAllRosterDetail()
Track changesonRosterListUpdate
Block and unblockrosterManage block-list APIs
Apply and observejs
im.rosterManage.asyncApply({ user_id, alias })
  .then(() => {
    console.log("请求已发送成功!");
});

Groups and membership

Group work includes the group lifecycle, membership, roles, invitations, join requests, mute and block lists, announcements, shared files, and per-group notification settings. Load group details before rendering a chat so policy and permissions are current.

Create a groupjs
im.groupManage
  .asyncCreate({
    name,
    type, // Whether the group is public: 0 or 1
    avatar,
    description,
    user_list, // User IDs
  })
  .then(() => {
    console.log("群创建成功");
  });
LifecycleAPI
Join / leaveasyncApply({ group_id, reason }) / asyncLeave({ group_id })
DestroyasyncDestroy({ group_id })
Joined groupsasyncGetJoinedGroups()
Group detailsasyncGetGroupInfo(group_id)
Cached membersgetGroupMembers(group_id)
AdministrationgroupManage announcement, role, mute, block-list, and shared-file APIs

Build messages

ContentRequired fields
Textcontent plus uid or gid
Imagetype=image and attachment with dName, fLen, width, height, url
Filetype=file and file attachment metadata
Locationtype=location and attachment with lat, lon, addr
Voice & video signallingtype=rtc and config with action and callId
CustomA documented custom content type plus extension payload
Text-message fieldsjs
const message = {
  uid,  // User ID; used only for direct chat
  gid,  // Group ID; used only for group chat
  content, // Message text
  priority, // Message distribution priority from 0 to 10. Regular chat-room users default to 5 and messages may be dropped; administrators default to 0 and messages are retained. Choose other values for your business needs.
}
The sample above is preserved exactly from the legacy integration guide, including punctuation. Verify generated reference types before adopting it in a new codebase; corrections belong in the upstream sample source.

Send, forward, recall, and receive

Send to a contact or groupjs
im.sysManage.sendRosterMessage(message);
// or
im.sysManage.sendGroupMessage(message);
Receive chat messagesjs
im.on({
  onRosterMessage: function(message) {
    console.log(message);
  }
});

im.on({
  onGroupMessage: function(message) {
    console.log(message);
  }
});
  • Use onMessageStatusChanged to reconcile local pending messages with server state.
  • Handle recall and deletion events by message ID and make each handler idempotent.
  • Forward and recall through sysManage; enforce the server recall window in the UI.
  • Persist message IDs and conversation IDs rather than relying on rendered-list indexes.
Group mentionjs
im.sysManage.sendMentionMessage({
  gid,
  txt, // Mention text
  mentionAll, // Whether to mention everyone
  mentionList, // [id,id ...]
  mentionedMessage, // Mention content
  pushMessage, // Push notification
  senderNickname // Sender nickname
});

Typing state is ephemeral and should not be stored as a chat message. Search results are grouped by contact and group; debounce UI input and keep the original SDK result identifiers when navigating to a message.

Voice & video lifecycle

Start or join a calljs
Caller starts the voice or video call
im.rtcManage.initRTCEngine(message);
// or the recipient accepts and joins the call
im.rtcManage.joinRoom(message);
  1. Register onRosterRTCMessage before sending or accepting an invitation.
  2. Use sendRTCMessage for call signalling and the engine APIs for media state.
  3. Publish local tracks only after room join succeeds; subscribe after remote sources arrive.
  4. On every exit path, unpublish, unsubscribe, leave the room, destroy the engine, and remove listeners.

Web troubleshooting

SymptomCheck
flooim export not foundFor the documented Babel setup, use sourceType: unambiguous.
third/long is missingConfirm dependency installation completed; the legacy guide notes fsevents-related installation failures.
No default export in Vite/Vue 3Use the CommonJS compatibility plugins documented by the upstream demo.
No voice or videoUse HTTPS or localhost, verify permissions, adapter dependencies, and console feature enablement.
Duplicate eventsRegister listeners once and remove the exact handler during teardown.