使用者、好友與線上狀態
本頁介紹與“人”有關的功能:本人的資料、其他使用者的資料、好友和好友申請、黑名單、線上狀態,以及本人的登入裝置。
- 使用者資料(
im.users):本人資料隨登入取得並儲存在本地,可以修改暱稱、頭像和自定義屬性;其他使用者的資料按需批次獲取並快取,列表介面直接同步讀取。 - 好友(
im.friends):好友列表和黑名單完整儲存在本地,以可訂閱的列表提供,其他裝置上的變化實時同步過來;好友申請按頁查詢。 - 線上狀態(
im.presence):訂閱要顯示的人,狀態變化時收到事件;也可以查詢一次。 - 登入裝置(
im.devices):檢視本人當前線上的裝置和全部登入裝置,踢掉其他裝置。
這些方法都要在登入之後呼叫(見初始化與登入)。可訂閱的列表、同步讀取的狀態和事件的通用規則見事件與錯誤。
| 要做什麼 | 看哪裡 |
|---|---|
| 顯示和修改本人的暱稱、頭像 | 本人資料 |
| 在列表中顯示別人的暱稱和頭像 | 在列表中顯示暱稱和頭像 |
| 顯示好友列表、判斷是不是好友 | 顯示好友列表、檢查與某人的關係 |
| 加好友、處理“新朋友” | 傳送申請、收到的申請和未讀數 |
| 拉黑 | 黑名單 |
| 顯示線上、離線 | 訂閱要顯示的人 |
| 檢視和踢掉本人的其他登入裝置 | 本人的登入裝置 |
本人資料
讀取本人資料
im.users.me() 同步返回本地儲存的本人資料,未登入時為 null。資料在其他裝置上被修改、或被你的服務端修改時,SDK 自動更新本地的資料併發出 me.changed 事件。
const me = im.users.me();
render(me?.nickname || me?.username);
im.on('me.changed', (profile) => {
render(profile?.nickname || profile?.username);
});需要確認拿到的是服務端最新的資料時,呼叫 im.users.refreshMe()。
修改暱稱、頭像和自定義屬性
im.users.updateMe() 只提交傳入的欄位,沒有傳的欄位保持不變。清空暱稱或頭像時傳空字串;自定義屬性按項合併,值為 null 的鍵被刪除,整個 attributes 為 null 時清空全部屬性。修改成功後本地資料隨即更新,併發出 me.changed。
const updated = await im.users.updateMe({
nickname: '张三',
attributes: { sign: '今天也要加油', city: null }, // 设置 sign,删除 city
});
console.log(updated.version);暱稱和頭像要經過內容安全檢查,不透過時以 content_rejected 拒絕,details.field 為 nickname 或 avatar_url。各欄位的格式要求見服務端的使用者管理。
多臺裝置可能同時修改資料時,可以帶上讀取到的 version,資料已被別處修改時以 version_conflict 拒絕,不做任何修改:
const current = im.users.me();
try {
await im.users.updateMe({ nickname: '张三', version: current?.version });
} catch (err) {
if (err instanceof DRError && err.code === 'version_conflict') {
await im.users.refreshMe(); // 取得最新的资料,让用户重新确认
}
}設定頭像
頭像要先以用途 user_avatar 上傳,得到公開地址後再寫入資料。上傳的圖片會被縮放到長邊不超過 640 畫素,詳見檔案。
async function changeAvatar(file: File) {
const info = await im.files.upload(file, { purpose: 'user_avatar' });
await im.users.updateMe({ avatar_url: info.url });
}應用在執行策略中開啟了 media_url_only 時,只能使用本應用上傳的頭像地址(或允許的主機的 https 地址),其他地址以 invalid_argument 拒絕,details.reason 為 url_not_allowed。
本人是否被禁言
你的服務端可以對使用者全域性禁言。im.users.myMute 給出本人在單聊(chat)、群聊(group)、聊天室(room)三個範圍的禁言,沒有禁言的為 null,變化時發出 me.muteChanged:
im.on('me.muteChanged', ({ scope, muted, expires_at }) => {
if (muted) showToast(`你已被禁言${expires_at ? `,到 ${new Date(expires_at).toLocaleString()} 解除` : ''}`);
});只用於顯示
服務端沒有查詢本人禁言的介面,myMute 只反映本次連線期間收到的變化:重新整理頁面、重新開啟之後它為空,即使使用者仍在禁言中。不要據此禁用輸入框;傳送時以服務端返回的 user_muted 錯誤為準。
其他使用者的資料
在列表中顯示暱稱和頭像
im.users.get(username) 同步返回快取中的資料。快取中沒有或已過期(預設 10 分鐘,可用建立選項 userCacheTtlMs 修改)時,它返回已有的值(可能是 undefined),並在後臺獲取;獲取到之後發出 users.changed,事件載荷中列出資料有變化的使用者名稱。
會話列表、成員列表這類一次顯示很多人的介面,應該用 get 加 users.changed 重新渲染,不要逐個 await。50 毫秒內的多次後臺獲取會合併成一次請求,每次最多 100 人。
function nameOf(username: string): string {
const profile = im.users.get(username);
return profile?.nickname || username;
}
im.on('users.changed', ({ usernames }) => {
render(usernames.map(nameOf));
});要按“好友備註、群暱稱、暱稱、使用者名稱”的順序顯示名字,可以用 @deeprespond/im-web/render 中的 displayName(im, username),它同樣同步讀取、在資料到達後隨事件更新。
查詢資料
確實需要等待結果時(如開啟某人的資料頁),呼叫 im.users.fetch()。結果是以小寫使用者名稱為鍵的 Map,不存在或已刪除的使用者不在結果中。快取未過期的直接返回快取,force: true 時一律向服務端查詢。
const profiles = await im.users.fetch(['lisi', 'wangwu']);
const lisi = profiles.get('lisi');
if (!lisi) showToast('用户不存在');資料快取在本地,頁面重新整理後仍然有效。好友修改資料時服務端不推送,所以別人的資料最多在快取時間之後才更新。
好友
顯示好友列表
im.friends.list() 返回好友的可訂閱列表,包含全部好友,按備註、暱稱、使用者名稱中第一個非空的排序(中文按拼音)。登入後 SDK 自動同步好友列表,之後好友的增刪改(包括在其他裝置上的操作)都實時反映到列表中。列表不再顯示時呼叫 dispose()。
const friends = im.friends.list();
const unsubscribe = friends.subscribe(() => {
const { items, loading } = friends.getSnapshot();
if (!loading) render(items.map((f: Friend) => f.remark || f.nickname || f.username));
});
// 页面离开时
unsubscribe();
friends.dispose();只需要判斷某人是不是好友,或讀取他的備註時,用同步的 im.friends.get(username),不是好友時為 undefined。im.friends.listInfo 給出好友數和上限:
const info = im.friends.listInfo;
if (info) render(`好友 ${info.count} / ${info.max_count}`);React 中用 useLiveList:
import type { Friend } from '@deeprespond/im-web';
import { useLiveList } from '@deeprespond/im-web-react';
export function FriendList() {
const { snapshot } = useLiveList<Friend>((im) => im.friends.list(), []);
if (snapshot.loading) return <p>加载中…</p>;
return (
<ul>
{snapshot.items.map((f) => (
<li key={f.username}>{f.remark || f.nickname || f.username}</li>
))}
</ul>
);
}檢查與某人的關係
在使用者資料頁上顯示“加好友”“等待驗證”“已拉黑”等狀態時,用 im.friends.check(),一次最多 100 人。本人和不存在的使用者不在結果中。
const [relation] = await im.friends.check(['lisi']);
if (relation?.is_friend) render('发消息');
else if (relation?.request === 'sent') render('等待验证');
else if (relation?.request === 'received') render('对方已向你发出申请');
else render('加好友');blocked 只表示本人是否拉黑了對方;對方是否拉黑了本人不會告訴你。
設定備註和自定義屬性
備註和自定義屬性只屬於本人這一側,對方看不到。自定義屬性可以用來實現星標好友、好友分組;按項合併,值為 null 的鍵被刪除。
await im.friends.update('lisi', { remark: '老李', attributes: { star: '1', group: '同事' } });刪除好友
刪除後雙方都不再是好友,對方的好友列表也會同步移除本人。刪除本來就不是好友的人同樣成功。
await im.friends.remove('lisi');好友申請
傳送申請
const result = await im.friends.requests.send({
username: 'lisi',
message: '我是张三,项目组的',
remark: '李四', // 成为好友后自动设置的备注
add_source: 'search', // 添加来源,由你定义,会展示给对方
});
if (result.status === 'accepted') showToast('已成为好友');
else showToast('已发送,等待对方验证');結果取決於對方的加好友方式:對方需要驗證時 status 為 pending;對方允許任何人新增,或對方此前已向本人發出了申請時,雙方直接成為好友,status 為 accepted,friend 為新好友;對方拒絕任何人新增時以 friend_add_denied 拒絕。
常見的錯誤:
code | 說明 |
|---|---|
already_exists | 已經是好友。SDK 按成功處理,返回 status: 'accepted',不會以這個錯誤拒絕 |
friend_add_denied | 對方設定了拒絕任何人新增 |
user_blocked | 雙方有一方把另一方拉黑了 |
limit_exceeded | 本人的好友數已滿,或對方允許任何人新增而對方的好友數已滿 |
rate_limited | 傳送過於頻繁,details.reason 為 request_rate(每分鐘 20 個、每天 500 個)、pair_daily_limit(對同一個人每天 5 次)或 declined_cooldown(被拒絕後 24 小時內) |
content_rejected | 附言或新增來源未透過內容安全檢查 |
permission_denied | 你的服務端透過加好友前回撥拒絕了這次申請,details.reason 為 app_rejected 或 callback_unavailable |
timeout | 網路錯誤或超時,SDK 查詢後確認申請沒有發出 |
傳送申請不會自動重發:網路錯誤或超時後,SDK 先查詢雙方的關係,已經成為好友或申請已經發出的按成功返回;確認沒有發出的以 timeout 拒絕,由使用者決定是否再發。遇到 rate_limited 時請按 details.reason 提示使用者。
申請發出後不能撤回。申請的完整規則(有效期 30 天、重複申請會更新原來的申請等)見服務端的好友申請。
收到的申請和未讀數
im.friends.requests.unreadCount 同步給出收到的、還沒有檢視過的申請數(最多統計到 100,超過 99 時可以顯示“99+”),變化時發出 friendRequests.changed:
im.on('friendRequests.changed', ({ unread_count }) => {
render(unread_count > 99 ? '99+' : String(unread_count || ''));
});開啟“新朋友”頁面時查詢收到的申請,展示之後標記為已讀:
const page = await im.friends.requests.received();
render(page.items.map((r: FriendRequest) => `${r.nickname || r.username}:${r.message}(${r.status})`));
await im.friends.requests.markRead();- 不帶
cursor和status時返回 SDK 記憶體中的第一頁,不發請求。SDK 在登入、重連和收到申請相關的通知時會重新整理這一頁,所以它是最新的。帶status篩選或翻頁時向服務端查詢。 markRead()不帶引數時,把當前第一頁中未讀的申請標為已讀;也可以傳入read_until(最新一條已展示的申請的requested_at)。
發出的申請用 im.friends.requests.sent() 查詢,規則相同。申請在最近一次傳送後 30 天內未處理即過期,狀態變為 expired。
同意或拒絕
const friend = await im.friends.requests.accept('wangwu', { remark: '王五' });
await im.friends.requests.decline('zhaoliu');同意後雙方成為好友,好友列表隨即更新;拒絕後對方 24 小時內不能再向本人申請。申請已過期時以 not_found 拒絕。同意時雙方任何一方的好友數已滿,以 limit_exceeded 拒絕。
黑名單
把某人加入黑名單後,他不能給本人發單聊訊息、不能向本人發好友申請、不能邀請本人入群;本人發給他的、尚未處理的好友申請被一併撤回。拉黑不解除好友關係,也不通知對方。詳見服務端的黑名單。
await im.friends.blacklist.add('spammer');
if (im.friends.blacklist.has('spammer')) render('已拉黑');
const blacklist = im.friends.blacklist.list(); // 按拉黑时间从新到旧
blacklist.subscribe(() => render(blacklist.getSnapshot().items));
await im.friends.blacklist.remove('spammer');黑名單最多 1000 人。應用在執行策略中關閉了黑名單攔截(user_blacklist_enabled)時,不能再拉黑別人,add 以 permission_denied 拒絕;檢視和移出照常可用。
加好友方式
每個使用者可以設定別人向自己傳送好友申請時怎樣處理:
| 取值 | 說明 |
|---|---|
need_confirm | 需要驗證:生成待處理的申請,本人同意後成為好友 |
allow_any | 允許任何人新增:不需要本人同意,直接成為好友 |
deny_any | 拒絕任何人新增:對方的申請以 friend_add_denied 失敗 |
const { friend_add_mode, effective_friend_add_mode } = await im.friends.settings.get();
render(friend_add_mode === null ? `跟随应用默认(${effective_friend_add_mode})` : friend_add_mode);
await im.friends.settings.set('need_confirm');
await im.friends.settings.set(null); // 清除本人的设置,改用应用的默认值使用者沒有設定過時使用應用執行策略中的預設值(預設 need_confirm)。
線上狀態
線上狀態需要應用在執行策略中開啟 presence_enabled(預設關閉)。執行策略還決定能看到誰的狀態:presence_scope 為 friends(預設)時只能看到好友的,為 all 時可以看到任何使用者的;presence_last_seen_visible 關閉後看不到最近離線時間(last_seen_at 為 null)。可以從 im.config 讀取這幾項,決定介面上是否顯示線上狀態:
const config = im.config;
const showPresence = config?.presence_enabled === true;關閉了線上狀態時,subscribe 和 query 以 permission_denied(details.reason 為 presence_disabled)失敗。
訂閱要顯示的人
im.presence.subscribe() 登記要持續關注的人,返回取消這次訂閱的函式。狀態變化時發出 presence.changed,之後用同步的 im.presence.get(username) 讀取:
const visible = ['lisi', 'wangwu'];
const stop = im.presence.subscribe(visible);
im.on('presence.changed', ({ items, reset }) => {
for (const username of visible) {
const state = im.presence.get(username);
render(username, state === undefined ? '未知' : state.online ? `在线(${state.platforms.join('、')})` : '离线');
}
});
// 不再显示时
stop();- 按需訂閱:只訂閱當前看得到的人,如會話列表中可見的好友、開啟的單聊對方。同一個人被訂閱多次時計數,全部取消後才真正退訂。
- 延遲:訂閱的變化合並 2 秒後才發給服務端,取消後 30 秒才退訂(期間又需要的不退訂),所以快速滾動列表不會產生大量請求。
- 上限:一個瀏覽器最多同時訂閱 3000 人。
- 多個標籤頁:同一瀏覽器的多個標籤頁共用一個連線,訂閱由 SDK 合併,各標籤頁的
subscribe互不影響。 - 重新連線:斷線重連後 SDK 自動重新訂閱,期間
presence.changed的reset為true,表示之前的狀態都已清除。
get 在以下情況返回 undefined,介面應顯示為“未知”而不是“離線”:還沒有收到訂閱結果;對方不存在或看不到;重新連線後還沒有重新訂閱完;presence_scope 為 friends 而對方已不是好友。
沒能訂閱的人以 presence.subscribeFailed 事件報告:
im.on('presence.subscribeFailed', ({ usernames, reason }) => {
// reason:denied(不存在或看不到)、limit_exceeded(超出上限)、presence_disabled(应用关闭了在线状态)
console.warn('在线状态订阅失败', reason, usernames);
});服務端的限流(訂閱按使用者每分鐘 30 次)由 SDK 等待後自動重試,不報事件。
在 React 中可以用 usePresence:
import { usePresence } from '@deeprespond/im-web-react';
export function OnlineDot({ username }: { username: string }) {
const states = usePresence([username]);
const state = states.get(username);
return <span className={state === undefined ? 'unknown' : state.online ? 'online' : 'offline'} />;
}查詢一次
不需要持續更新時(如開啟資料頁時顯示一次),用 im.presence.query() 查詢,一次最多 100 人。查詢的結果不會更新 get 讀到的狀態。
const [state] = await im.presence.query(['lisi']);
if (state && !state.online && state.last_seen_at) render(`最近在线:${new Date(state.last_seen_at).toLocaleString()}`);離線的判定有延遲:裝置異常斷網時,服務端要在連線空閒超時之後才判定離線,見服務端的線上狀態。
本人的登入裝置
當前線上的裝置
im.devices.online() 同步返回本人當前保持著連線的裝置(包括這臺),變化時發出 devices.changed,可以用來顯示“電腦已登入”:
im.on('devices.changed', ({ devices }) => {
const others = devices.filter((d) => !d.current);
render(others.length > 0 ? `${others.map((d) => d.platform).join('、')} 已登录` : '');
});本人在新裝置上登入時發出 devices.newLogin,可以提示使用者:
im.on('devices.newLogin', ({ device_name, platform, created_at }) => {
showToast(`你的账号于 ${new Date(created_at).toLocaleString()} 在 ${device_name || platform} 上登录`);
});全部登入裝置與踢下線
im.devices.sessions() 返回本人全部有效的登入(包括目前沒有連線的裝置),按最近活躍時間從新到舊,current 標出這臺裝置。im.devices.kick() 讓指定的裝置下線:
const sessions = await im.devices.sessions();
render(sessions.map((s: LoginSession) => `${s.device_name || s.platform}${s.current ? '(本机)' : ''}`));
const target = sessions.find((s) => !s.current);
if (target) await im.devices.kick(target.session_id);被踢的裝置立即下線,需要重新登入。指定的是當前裝置時等同於退出登入。同時登入的裝置數受執行策略的限制,超出時最早的裝置會被擠下線,見服務端的登入與憑證。
介面參考
im.users.me()
同步返回本地儲存的本人資料。
返回值:SelfProfile | null,未登入時為 null。變化時發出 me.changed。
im.users.refreshMe()
向服務端獲取本人資料,更新本地儲存的資料。
返回值:Promise<SelfProfile>。
im.users.updateMe()
修改本人資料,只提交傳入的欄位。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
patch.nickname | string | 否 | 暱稱,最長 64 個字元;空字串表示清空 |
patch.avatar_url | string | 否 | 頭像地址;空字串表示清空 |
patch.attributes | Record<string, string | null> | null | 否 | 自定義屬性,按項合併:值為 null 的鍵被刪除;整個欄位為 null 時清空。最多 32 項,合計不超過 4 KB |
patch.version | number | 否 | 讀取到的資料版本號,與服務端不一致時不修改 |
返回值:Promise<SelfProfile>,修改後的資料。
可能的錯誤:
code | 說明 |
|---|---|
local_validation | nickname 或 avatar_url 不是字串 |
invalid_argument | 欄位格式不對;頭像地址不被允許(details.reason 為 url_not_allowed) |
content_rejected | 暱稱或頭像未透過內容安全檢查 |
version_conflict | version 與服務端不一致 |
im.users.myMute
只讀屬性:本人在三個範圍的全域性禁言 { chat, group, room },每項為 GlobalMute | null。只反映本次連線期間收到的變化,變化時發出 me.muteChanged。
im.users.get()
同步返回快取中的使用者資料;沒有或過期時在後臺獲取,獲取後發出 users.changed。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
username | string | 是 | 使用者名稱 |
返回值:UserProfile | undefined。
im.users.fetch()
批次查詢使用者資料,快取未過期的直接使用快取。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
usernames | string[] | 是 | 使用者名稱,超過 100 個時分批查詢 |
opts.force | boolean | 否 | 為 true 時不使用快取 |
返回值:Promise<Map<string, UserProfile>>,鍵為小寫的使用者名稱;不存在或已刪除的使用者不在結果中。
im.friends.list()
返回全部好友的可訂閱列表(LiveList<Friend>),按備註、暱稱、使用者名稱中第一個非空的排序。快照的 hasMore 總是 false。不再使用時呼叫 dispose()。
未登入時丟擲 not_signed_in。
im.friends.get()
同步返回一位好友,不是好友時為 undefined。變化時發出 friends.changed。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
username | string | 是 | 使用者名稱 |
返回值:Friend | undefined。
im.friends.listInfo
只讀屬性:{ count: number; max_count: number } | null,好友數和好友數上限;好友列表還沒有同步時為 null。
im.friends.check()
檢查本人與其他使用者的關係。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
usernames | string[] | 是 | 1 到 100 個使用者名稱 |
返回值:Promise<FriendCheck[]>,按請求中的順序;本人和不存在的使用者不在結果中。
可能的錯誤:local_validation(usernames 為空或超過 100 個)。
im.friends.update()
修改好友的備註和自定義屬性。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
username | string | 是 | 好友的使用者名稱 |
p.remark | string | 否 | 備註,最長 64 個字元;空字串表示清空 |
p.attributes | Record<string, string | null> | null | 否 | 自定義屬性,按項合併;整個欄位為 null 時清空。最多 16 項,合計不超過 1 KB |
remark 和 attributes 至少給出一項。
返回值:Promise<Friend>。
可能的錯誤:local_validation(兩項都沒有給出)、not_found(不是好友)、invalid_argument(備註或自定義屬性不符合規則)。
im.friends.remove()
刪除好友,雙方的好友列表都會移除對方。不是好友時同樣成功。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
username | string | 是 | 好友的使用者名稱 |
返回值:Promise<void>。
im.friends.requests.send()
傳送好友申請。不自動重發,規則見傳送申請。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
p.username | string | 是 | 對方的使用者名稱 |
p.message | string | 否 | 附言,最長 256 個字元 |
p.remark | string | 否 | 成為好友後給對方設定的備註,最長 64 個字元 |
p.add_source | string | 否 | 新增來源,如 search、qrcode |
返回值:Promise<{ status: 'pending' | 'accepted'; friend?: Friend }>。
可能的錯誤:friend_add_denied、user_blocked、limit_exceeded、rate_limited、content_rejected、permission_denied、not_found(對方不存在)、timeout,見傳送申請。
im.friends.requests.received()
查詢收到的好友申請,按傳送時間從新到舊。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
p.status | RequestStatus | 否 | 只列出這種狀態的申請:pending、accepted、declined、expired |
p.cursor | string | null | 否 | 下一頁的遊標,取自上一頁的 next_cursor |
p.limit | number | 否 | 每頁條數 |
返回值:Promise<Page<FriendRequest>>。不帶 cursor 和 status 時返回 SDK 記憶體中的第一頁。
im.friends.requests.sent()
查詢本人發出的好友申請,引數和返回值同 im.friends.requests.received()。
im.friends.requests.unreadCount
只讀屬性:收到的未讀申請數,最多 100。變化時發出 friendRequests.changed。
im.friends.requests.markRead()
把收到的申請標為已讀。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
p.read_until | string | 否 | 已展示的最新一條申請的 requested_at,這個時間及以前的申請標為已讀。省略時按 SDK 記憶體中第一頁的未讀申請計算 |
返回值:Promise<void>。
im.friends.requests.accept()
同意好友申請,雙方成為好友。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
username | string | 是 | 申請人的使用者名稱 |
p.remark | string | 否 | 給申請人設定的備註 |
返回值:Promise<Friend>,新好友。
可能的錯誤:not_found(申請不存在或已過期)、limit_exceeded(好友數已滿)、permission_denied(被加好友前回撥拒絕)。
im.friends.requests.decline()
拒絕好友申請。對方 24 小時內不能再向本人申請。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
username | string | 是 | 申請人的使用者名稱 |
返回值:Promise<void>。
可能的錯誤:not_found(申請不存在、已同意或已過期)。
im.friends.blacklist.list()
返回黑名單的可訂閱列表(LiveList<BlacklistEntry>),按拉黑時間從新到舊。不再使用時呼叫 dispose()。
im.friends.blacklist.has()
同步判斷本人是否拉黑了某人。變化時發出 blacklist.changed。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
username | string | 是 | 使用者名稱 |
返回值:boolean。
im.friends.blacklist.add()
把使用者加入黑名單。已在黑名單中時同樣成功。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
username | string | 是 | 使用者名稱 |
返回值:Promise<void>。
可能的錯誤:permission_denied(應用關閉了黑名單攔截)、limit_exceeded(黑名單已滿 1000 人,details.reason 為 blacklist_limit)、not_found(使用者不存在)、invalid_argument(拉黑自己)。
im.friends.blacklist.remove()
把使用者移出黑名單。不在黑名單中時同樣成功。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
username | string | 是 | 使用者名稱 |
返回值:Promise<void>。
im.friends.settings.get()
查詢本人的加好友方式。
返回值:Promise<{ friend_add_mode: FriendAddMode | null; effective_friend_add_mode: FriendAddMode }>。friend_add_mode 為本人的設定,沒有設定過時為 null;effective_friend_add_mode 為實際生效的方式。
im.friends.settings.set()
設定本人的加好友方式。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
mode | FriendAddMode | null | 是 | need_confirm、allow_any、deny_any;null 清除設定,改用應用的預設值 |
返回值:Promise<void>。
im.presence.subscribe()
登記要持續關注線上狀態的人。同步執行,不等待服務端的結果。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
usernames | string[] | 是 | 使用者名稱 |
返回值:() => void,取消這次訂閱的函式,可以重複呼叫。
可能的錯誤(同步丟擲):not_signed_in、permission_denied(presence_disabled)。客戶端已 destroy() 時什麼也不做,返回的函式同樣什麼也不做。
im.presence.get()
同步返回已訂閱的人的線上狀態。變化時發出 presence.changed。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
username | string | 是 | 使用者名稱 |
返回值:PresenceState | undefined,未知時為 undefined。
im.presence.query()
查詢一次線上狀態,不訂閱。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
usernames | string[] | 是 | 1 到 100 個使用者名稱 |
返回值:Promise<PresenceState[]>;看不到的使用者不在結果中。
可能的錯誤:local_validation(為空或超過 100 個)、permission_denied(presence_disabled)、rate_limited。
im.devices.online()
同步返回本人當前線上的裝置。變化時發出 devices.changed。
返回值:readonly OnlineDevice[]。
im.devices.sessions()
查詢本人全部有效的登入裝置。
返回值:Promise<LoginSession[]>,按最近活躍時間從新到舊。
im.devices.kick()
讓本人的一臺裝置下線;指定的是當前裝置時等同於退出登入。裝置已經下線時同樣成功。
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
session_id | string | 是 | 登入裝置的 session_id |
返回值:Promise<void>。
可能的錯誤:local_validation(session_id 為空)、not_found(不是本人的登入裝置)。
相關事件
| 事件 | 載荷 | 說明 |
|---|---|---|
me.changed | SelfProfile | null | 本人資料變化 |
me.muteChanged | { scope, muted, expires_at } | 本人的全域性禁言變化;scope 為 chat、group 或 room |
users.changed | { usernames: string[] } | 這些使用者的快取資料有變化 |
friends.changed | { upserted: string[]; removed: string[] } | 好友列表變化 |
blacklist.changed | { upserted: string[]; removed: string[] } | 黑名單變化 |
friendRequests.changed | { lists: Array<'received' | 'sent'>; unread_count: number } | 好友申請或未讀數變化,SDK 記憶體中的第一頁已重新整理 |
presence.changed | { items: PresenceState[]; reset: boolean; cleared?: string[] } | 線上狀態變化;reset 為 true 時全部狀態已清除,cleared 中的人的狀態已清除 |
presence.subscribeFailed | { usernames: string[]; reason } | 沒能訂閱;reason 為 denied、limit_exceeded 或 presence_disabled |
devices.changed | { devices: OnlineDevice[] } | 本人線上的裝置變化 |
devices.newLogin | { session_id, device_name, platform, login_method, created_at } | 本人在新裝置上登入 |
資料結構
SelfProfile
本人資料。
| 欄位 | 型別 | 說明 |
|---|---|---|
username | string | 使用者名稱 |
nickname | string | 暱稱,沒有時為空字串 |
avatar_url | string | 頭像地址,沒有時為空字串 |
attributes | Record<string, string> | null | 自定義屬性,沒有時為 null |
has_password | boolean | 是否設定過密碼 |
version | number | 資料的版本號,每次修改加一 |
服務端返回的其他欄位原樣保留。
UserProfile
其他使用者的公開資料。
| 欄位 | 型別 | 說明 |
|---|---|---|
username | string | 使用者名稱 |
nickname | string | 暱稱,沒有時為空字串 |
avatar_url | string | 頭像地址,沒有時為空字串 |
attributes | Record<string, string> | null | 自定義屬性 |
GlobalMute
| 欄位 | 型別 | 說明 |
|---|---|---|
expires_at | string | null | 解除禁言的時間,永久禁言為 null |
Friend
本人視角的一位好友。
| 欄位 | 型別 | 說明 |
|---|---|---|
username | string | 好友的使用者名稱 |
nickname | string | 好友的暱稱 |
avatar_url | string | 好友的頭像地址 |
remark | string | 本人給好友設定的備註,沒有時為空字串 |
attributes | Record<string, string> | null | 本人給好友設定的自定義屬性 |
add_source | string | 新增來源,沒有時為空字串 |
created_at | string | 成為好友的時間 |
FriendRequest
站在本人的角度描述一條好友申請:收到的申請中“對方”是申請人,發出的申請中“對方”是被申請人。
| 欄位 | 型別 | 說明 |
|---|---|---|
username | string | 對方的使用者名稱 |
nickname | string | 對方的暱稱 |
avatar_url | string | 對方的頭像地址 |
message | string | 附言,沒有時為空字串 |
add_source | string | 新增來源 |
status | RequestStatus | pending 待處理、accepted 已成為好友、declined 已拒絕、expired 已過期 |
unread | boolean | 只在收到的申請中出現:是否還沒有檢視過 |
remark | string | 只在發出的申請中出現:預先給對方設定的備註 |
requested_at | string | 最近一次傳送的時間 |
expires_at | string | null | 過期時間,只有 pending 的申請有值 |
handled_at | string | null | 同意、拒絕或成為好友的時間 |
FriendCheck
| 欄位 | 型別 | 說明 |
|---|---|---|
username | string | 對方的使用者名稱 |
is_friend | boolean | 是否好友 |
blocked | boolean | 本人是否拉黑了對方 |
request | 'sent' | 'received' | null | 雙方之間未過期的待處理申請:sent 為本人發出,received 為對方發來 |
BlacklistEntry
| 欄位 | 型別 | 說明 |
|---|---|---|
username | string | 被拉黑的使用者名稱 |
nickname | string | 暱稱 |
avatar_url | string | 頭像地址 |
created_at | string | 拉黑的時間 |
FriendAddMode
'need_confirm' | 'allow_any' | 'deny_any',見加好友方式。
PresenceState
| 欄位 | 型別 | 說明 |
|---|---|---|
username | string | 使用者名稱 |
online | boolean | 是否線上 |
platforms | string[] | 線上的平臺,如 web、ios、windows;離線時為空陣列 |
last_seen_at | string | null | 最近一次離線的時間;線上、30 天內沒有上線過,或應用不允許檢視時為 null |
version | number | 狀態的版本號 |
OnlineDevice
本人當前線上的一臺裝置。
| 欄位 | 型別 | 說明 |
|---|---|---|
session_id | string | 登入裝置的會話 ID,與 LoginSession 的相同 |
platform | string | 平臺 |
connected_at | string | 建立連線的時間 |
current | boolean | 是否為當前這臺裝置 |
LoginSession
本人的一次有效登入。
| 欄位 | 型別 | 說明 |
|---|---|---|
session_id | string | 會話 ID,用於 kick() |
device_id | string | 裝置標識 |
device_name | string | 裝置名稱,沒有時為空字串 |
platform | string | 平臺:ios、android、harmony、windows、macos、linux、web、mini_program 或 other |
current | boolean | 是否為當前這臺裝置 |
sdk_version | string | 客戶端版本 |
login_method | string | 登入方式:ticket 憑證登入,password 密碼登入 |
ip | string | 登入時的 IP |
created_at | string | 登入時間 |
last_active_at | string | 最近一次登入或續期的時間 |
expires_at | string | null | 會話的過期時間,null 表示不過期 |
TypeScript 型別中只宣告瞭前五個欄位,其餘欄位同樣存在,可以按索引讀取。
