好友申請
好友申請由使用者在客戶端發起:A 向 B 發申請,B 同意或拒絕。傳送、同意和拒絕只能由使用者本人在客戶端操作,你的服務端只能查詢好友申請。
| 你想要 | 做法 |
|---|---|
| 在後臺檢視使用者收到、發出的申請 | 查詢好友申請 |
| 由服務端直接讓兩人成為好友 | 新增好友,不經過申請 |
| 由你的服務端決定能不能加好友 | 加好友前回撥,見下文 |
| 改變“要不要驗證” | 加好友方式 |
申請的處理流程
A 傳送申請後,按 B 的加好友方式處理:
| B 的加好友方式 | 結果 |
|---|---|
need_confirm(需要驗證,預設) | 生成一條待處理的申請,B 的線上裝置收到通知。B 同意後雙方成為好友,A 收到新好友的通知;B 拒絕後 A 收到被拒絕的通知 |
allow_any(允許任何人新增) | 不需要 B 同意,雙方直接成為好友。申請同樣記錄下來,狀態為“已成為好友”,B 能看到是誰加了自己 |
deny_any(拒絕任何人新增) | 申請發不出去,A 收到 403 friend_add_denied |
幾條規則:
| 規則 | 說明 |
|---|---|
| 互相申請 | B 已向 A 發出未過期的待處理申請,A 再向 B 申請時直接成為好友,即使 B 是 deny_any:B 的申請本身就表示同意 |
| 一對使用者只有一條申請 | A 對 B 的申請沒處理時再申請一次,會更新附言、預裝置註、來源和傳送時間,B 再收到一次通知,有效期重新計算。之前被拒絕或過期的也更新這一條 |
| 有效期 | 最近一次傳送後 30 天沒處理就過期(expired),不能再同意或拒絕。記錄在傳送 60 天后自動刪除 |
| 不能撤回 | 申請人不能撤回。A 把 B 加入黑名單時,A 發給 B 的待處理申請會被一併刪除 |
| 服務端直接新增 | 新增好友後,兩人之間的待處理申請改為 accepted,申請中預設的備註寫入申請人那一側 |
| 申請的內容 | 附言最長 256 個字元;可以預先給對方裝置註(最長 64 個字元),成為好友後自動寫入;可以帶新增來源(規則同好友物件)。附言和來源對方能看到 |
內容檢查:附言和新增來源傳送時經過內容安全檢查,備註不檢查。
- 沒透過時申請發不出去,A 收到
403 content_rejected,details.field為message或add_source,見呼叫方看到的錯誤。 - 附言命中替換規則的儲存替換後的文字,查到的附言中可能有
*;新增來源是標識,命中替換規則時直接拒絕。
加好友前回撥:開啟加好友前回撥後,A 發申請(包括會直接透過的)之前先請求你的服務端,也可以設定 B 同意時呼叫。服務端新增好友不呼叫。
- 順序:在內容檢查之後,在“是否已是好友、黑名單、加好友方式、好友數”等檢查之前。
- 被拒絕時 A 收到
403 permission_denied,申請不寫入,B 收不到;B 同意時被拒絕的,B 收到同樣的錯誤,申請保持待處理。 details.reason為app_rejected(你的服務端拒絕)或callback_unavailable(回撥失敗後按“拒絕”策略處理);details.app_reason是你給出的原因程式碼,message是你給出的提示(沒給時為“操作被拒絕”)。
傳送申請的限制
為了防止騷擾,傳送好友申請有以下限制,超出時 A 收到 429 rate_limited,Retry-After 響應頭為需要等待的秒數,details.reason 說明是哪一種限制:
| 限制 | details.reason |
|---|---|
| 每個使用者每分鐘最多傳送 20 個申請、每天最多 500 個 | request_rate |
| 同一個人對同一個人每天最多申請 5 次:連續申請 5 次後,約每 4.8 小時恢復 1 次 | pair_daily_limit |
| 申請被對方拒絕後,24 小時內不能再向對方申請 | declined_cooldown |
傳送時還會檢查雙方的關係:
| 情況 | A 收到 |
|---|---|
| 已經是好友 | 409 already_exists |
A 的好友數已滿,或 B 是 allow_any 而 B 的好友數已滿 | 409 limit_exceeded |
| A 拉黑了 B,或 B 拉黑了 A(應用關閉黑名單攔截時不檢查,見黑名單) | 403 user_blocked |
申請的狀態
status | 說明 |
|---|---|
pending | 待處理,且沒有過期 |
accepted | 已成為好友:對方同意了、對方的加好友方式為 allow_any 而自動透過、雙方互相申請,或者服務端直接把兩人新增為好友 |
declined | 已被拒絕 |
expired | 已過期:待處理的申請在最近一次傳送後 30 天內沒有處理 |
查詢好友申請
查詢一個使用者收到的或發出的好友申請,按傳送時間從新到舊排列,可以按狀態篩選。
GET
/{org_name}/{app_name}/users/{username}/friend-requests路徑引數
org_name、app_name 見接入概述。
| 引數 | 型別 | 說明 |
|---|---|---|
username | String | 使用者名稱 |
查詢引數
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
direction | String | 是 | received 為該使用者收到的申請,sent 為該使用者發出的申請 |
status | String | 否 | 按狀態篩選:pending、accepted、declined 或 expired,見申請的狀態。不傳時返回全部 |
limit | Number | 否 | 每頁條數,預設 20,取值 1 到 100 |
cursor | String | 否 | 下一頁的遊標,見分頁。翻頁時不要改變 direction 和 status |
請求示例
bash
curl "$IM_API/$ORG/$APP/users/alice/friend-requests?direction=received" \
-H "Authorization: Bearer $APP_TOKEN"響應
成功返回 200 OK,items 為本頁的申請,每項為好友申請物件;next_cursor 為下一頁的遊標,為 null 時沒有下一頁。已被刪除的使用者的申請不出現在列表中,一頁的條數可能少於 limit,是否還有下一頁只看 next_cursor。
收到的申請:
json
{
"items": [
{
"username": "dave",
"nickname": "戴夫",
"avatar_url": "",
"message": "你好,我是戴夫",
"add_source": "search",
"status": "pending",
"unread": true,
"requested_at": "2026-10-02T19:12:59.406Z",
"expires_at": "2026-11-01T19:12:59.406Z",
"handled_at": null
},
{
"username": "erin",
"nickname": "艾琳",
"avatar_url": "",
"message": "你好,我是艾琳",
"add_source": "qrcode",
"status": "accepted",
"unread": false,
"requested_at": "2026-10-02T19:08:09.923Z",
"expires_at": null,
"handled_at": "2026-10-02T19:09:09.491Z"
}
],
"next_cursor": null
}發出的申請(direction=sent)沒有 unread,另有申請人預設的備註 remark:
json
{
"items": [
{
"username": "alice",
"nickname": "爱丽丝",
"avatar_url": "",
"message": "你好,我是戴夫",
"remark": "小爱",
"add_source": "search",
"status": "pending",
"requested_at": "2026-10-02T19:12:59.406Z",
"expires_at": "2026-11-01T19:12:59.406Z",
"handled_at": null
}
],
"next_cursor": null
}錯誤
| HTTP 狀態碼 | code | 說明 |
|---|---|---|
| 400 | invalid_argument | direction 缺失或不是 received、sent;status 不是可選的值;limit 不在 1 到 100 之間;cursor 無效 |
| 404 | not_found | 使用者不存在或已刪除 |
資料結構
好友申請物件
站在 {username} 的角度描述一條申請:收到的申請中“對方”是申請人,發出的申請中“對方”是被申請人。
| 欄位 | 型別 | 說明 |
|---|---|---|
username | String | 對方的使用者名稱 |
nickname | String | 對方的暱稱,沒有設定時為空字串 |
avatar_url | String | 對方的頭像地址,沒有設定時為空字串 |
message | String | 申請人填寫的附言,沒有時為空字串 |
remark | String | 只在發出的申請中出現:申請人預先給對方設定的備註,沒有時為空字串 |
add_source | String | 新增來源,沒有時為空字串 |
status | String | 狀態:pending、accepted、declined 或 expired,見申請的狀態 |
unread | Boolean | 只在收到的申請中出現:使用者是否還沒有在客戶端檢視過這條申請。只有 pending 的申請可能為 true |
requested_at | String | 最近一次傳送的時間 |
expires_at | String | 過期時間,只有 pending 的申請有值,其他狀態為 null |
handled_at | String | 同意、拒絕或成為好友的時間,pending 和 expired 的申請為 null |
