消息API

学习如何使用纸飞机消息API发送和接收消息,支持文本、图片、视频等多种格式。

API参考 消息 通讯 v8.0

概述

纸飞机消息API提供了一套完整的消息发送、接收和管理功能,支持多种消息类型,包括文本、图片、视频、音频、文件、位置等。API采用RESTful设计,同时提供WebSocket接口用于实时消息推送。

所有消息API端点都需要使用HTTPS协议,并在请求头中包含有效的访问令牌。

主要功能

  • 发送和接收多种类型的消息
  • 支持一对一聊天和群组聊天
  • 消息状态跟踪(已发送、已送达、已读)
  • 消息撤回和编辑
  • 消息转发
  • 消息搜索
  • 实时消息推送(WebSocket)

消息生命周期

纸飞机消息的典型生命周期包括:

  1. 发送方创建并发送消息
  2. 服务器接收消息并进行端到端加密
  3. 服务器将消息存储并推送给接收方
  4. 接收方接收并解密消息
  5. 接收方发送已读回执
  6. 根据消息设置(如阅后即焚),消息可能会自动删除

消息类型

纸飞机支持多种消息类型,每种类型都有特定的数据结构和处理方式。

支持的消息类型

类型 类型ID 描述
文本消息 text 纯文本消息,支持基本格式化
图片消息 photo 图片文件,支持缩略图
视频消息 video 视频文件,支持缩略图和时长信息
音频消息 audio 音频文件,支持时长信息
文件消息 document 任意类型的文件
位置消息 location 地理位置信息
联系人消息 contact 联系人信息
语音通话 voice_call 语音通话邀请
视频通话 video_call 视频通话邀请
贴纸消息 sticker 表情贴纸
投票消息 poll 投票和调查
引用回复 reply 引用并回复特定消息

消息结构

所有消息都包含以下基本字段:

{
  "id": "msg1234567890",
  "chat_id": "chat1234567890",
  "sender_id": "user1234567890",
  "type": "text",
  "content": {
    // 根据消息类型不同而变化
  },
  "timestamp": 1625097600000,
  "status": "read",
  "edited": false,
  "forwarded": false,
  "reply_to_message_id": null,
  "expire_in": 0
}

消息内容在传输和存储过程中都是端到端加密的,服务器无法查看消息的实际内容。

API端点

所有消息API的基础URL为:https://api.paperplane.com/v8/messages

发送消息

发送新消息到指定的聊天会话。

请求

POST /messages/send
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

{
  "chat_id": "chat1234567890",
  "type": "text",
  "content": {
    "text": "Hello, this is a test message!"
  },
  "reply_to_message_id": null,
  "expire_in": 0,
  "disable_notification": false
}

响应

{
  "ok": true,
  "result": {
    "id": "msg1234567890",
    "chat_id": "chat1234567890",
    "sender_id": "user1234567890",
    "type": "text",
    "content": {
      "text": "Hello, this is a test message!"
    },
    "timestamp": 1625097600000,
    "status": "sent",
    "edited": false,
    "forwarded": false,
    "reply_to_message_id": null,
    "expire_in": 0
  }
}

发送图片消息示例

POST /messages/send
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

{
  "chat_id": "chat1234567890",
  "type": "photo",
  "content": {
    "file_id": "file1234567890",
    "caption": "Check out this photo!",
    "width": 1280,
    "height": 720
  }
}

获取消息

获取指定聊天会话的消息列表。

请求

GET /messages?chat_id=chat1234567890&limit=50&offset=0
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

参数说明

参数 类型 必需 描述
chat_id string 聊天会话ID
limit integer 返回消息的最大数量,默认50,最大100
offset integer 偏移量,用于分页
before string 返回此消息ID之前的消息
after string 返回此消息ID之后的消息
search string 搜索关键词

响应

{
  "ok": true,
  "result": {
    "messages": [
      {
        "id": "msg1234567890",
        "chat_id": "chat1234567890",
        "sender_id": "user1234567890",
        "type": "text",
        "content": {
          "text": "Hello, this is a test message!"
        },
        "timestamp": 1625097600000,
        "status": "read",
        "edited": false,
        "forwarded": false,
        "reply_to_message_id": null,
        "expire_in": 0
      },
      // 更多消息...
    ],
    "total_count": 120,
    "has_more": true
  }
}

更新消息

更新已发送的消息内容(仅支持文本消息)。

请求

PUT /messages/{message_id}
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

{
  "content": {
    "text": "This is the updated message content!"
  }
}

响应

{
  "ok": true,
  "result": {
    "id": "msg1234567890",
    "chat_id": "chat1234567890",
    "sender_id": "user1234567890",
    "type": "text",
    "content": {
      "text": "This is the updated message content!"
    },
    "timestamp": 1625097600000,
    "edit_timestamp": 1625098000000,
    "status": "read",
    "edited": true,
    "forwarded": false,
    "reply_to_message_id": null,
    "expire_in": 0
  }
}

消息更新后,所有接收方都会看到更新后的内容,并会显示消息已被编辑的标记。

删除消息

删除已发送的消息。

请求

DELETE /messages/{message_id}
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

{
  "delete_for_all": true
}

参数说明

参数 类型 必需 描述
delete_for_all boolean 是否为所有人删除消息,默认为false(仅自己)

响应

{
  "ok": true,
  "result": {
    "message_id": "msg1234567890",
    "deleted": true,
    "deleted_for_all": true
  }
}

为所有人删除消息的功能有时间限制,通常只能在发送后48小时内使用。

转发消息

转发消息到其他聊天会话。

请求

POST /messages/forward
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

{
  "message_id": "msg1234567890",
  "chat_id": "chat9876543210",
  "disable_notification": false
}

响应

{
  "ok": true,
  "result": {
    "id": "msg9876543210",
    "chat_id": "chat9876543210",
    "sender_id": "user1234567890",
    "type": "text",
    "content": {
      "text": "Hello, this is a test message!"
    },
    "timestamp": 1625099000000,
    "status": "sent",
    "edited": false,
    "forwarded": true,
    "forward_from": {
      "message_id": "msg1234567890",
      "chat_id": "chat1234567890",
      "sender_id": "user1234567890",
      "sender_name": "John Doe"
    },
    "reply_to_message_id": null,
    "expire_in": 0
  }
}

WebSocket实时通讯

纸飞机提供WebSocket接口,用于实时接收消息和更新消息状态。

连接WebSocket

wss://api.paperplane.com/v8/ws?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

事件类型

事件类型 描述
message 收到新消息
message_status 消息状态更新
message_edit 消息被编辑
message_delete 消息被删除
typing 对方正在输入
read_receipt 收到已读回执
connection_status 连接状态更新

示例:接收新消息

{
  "type": "message",
  "data": {
    "id": "msg1234567890",
    "chat_id": "chat1234567890",
    "sender_id": "user1234567890",
    "type": "text",
    "content": {
      "text": "Hello, this is a test message!"
    },
    "timestamp": 1625097600000,
    "status": "sent",
    "edited": false,
    "forwarded": false,
    "reply_to_message_id": null,
    "expire_in": 0
  }
}

WebSocket连接会自动处理重连和心跳检测,确保实时通讯的稳定性。

错误处理

消息API使用标准HTTP状态码表示请求结果,并在响应体中提供详细的错误信息。

常见错误码

状态码 错误代码 描述
400 INVALID_MESSAGE_TYPE 不支持的消息类型
400 MESSAGE_TOO_LONG 消息内容过长
401 UNAUTHORIZED 未授权或令牌过期
403 CHAT_FORBIDDEN 没有权限访问该聊天
403 MESSAGE_DELETE_TIME_LIMIT 超过消息删除时间限制
404 MESSAGE_NOT_FOUND 消息不存在
404 CHAT_NOT_FOUND 聊天会话不存在
429 RATE_LIMITED 发送消息过于频繁
500 SERVER_ERROR 服务器内部错误

错误响应示例

{
  "ok": false,
  "error": {
    "code": "MESSAGE_TOO_LONG",
    "message": "Message text is too long. Maximum allowed length is 4096 characters.",
    "status_code": 400
  }
}

代码示例

以下是使用不同编程语言调用消息API的示例代码。

JavaScript (使用Fetch API)

// 发送文本消息
async function sendTextMessage(chatId, text) {
  try {
    const response = await fetch('https://api.paperplane.com/v8/messages/send', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${localStorage.getItem('accessToken')}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        chat_id: chatId,
        type: 'text',
        content: {
          text: text
        }
      })
    });
    
    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.error?.message || 'Failed to send message');
    }
    
    const data = await response.json();
    return data.result;
  } catch (error) {
    console.error('Error sending message:', error);
    throw error;
  }
}

// 使用WebSocket接收消息
function connectWebSocket() {
  const token = localStorage.getItem('accessToken');
  const ws = new WebSocket(`wss://api.paperplane.com/v8/ws?token=${token}`);
  
  ws.onopen = () => {
    console.log('WebSocket connected');
  };
  
  ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    
    switch (data.type) {
      case 'message':
        console.log('New message received:', data.data);
        // 处理新消息
        break;
      case 'message_status':
        console.log('Message status updated:', data.data);
        // 处理消息状态更新
        break;
      case 'typing':
        console.log('User is typing:', data.data);
        // 处理正在输入状态
        break;
      // 处理其他事件类型
    }
  };
  
  ws.onclose = () => {
    console.log('WebSocket disconnected');
    // 可以在这里实现重连逻辑
    setTimeout(connectWebSocket, 5000);
  };
  
  ws.onerror = (error) => {
    console.error('WebSocket error:', error);
  };
  
  return ws;
}

// 使用示例
sendTextMessage('chat1234567890', 'Hello from JavaScript!')
  .then(message => console.log('Message sent:', message))
  .catch(error => console.error('Failed to send message:', error));

const ws = connectWebSocket();

Python (使用Requests和websocket-client库)

import requests
import json
import websocket
import threading
import time

# 发送文本消息
def send_text_message(chat_id, text, token):
    url = 'https://api.paperplane.com/v8/messages/send'
    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }
    data = {
        'chat_id': chat_id,
        'type': 'text',
        'content': {
            'text': text
        }
    }
    
    try:
        response = requests.post(url, headers=headers, data=json.dumps(data))
        response.raise_for_status()
        
        result = response.json()
        return result['result']
    except requests.exceptions.HTTPError as http_err:
        error_data = response.json()
        print(f'HTTP error occurred: {error_data.get("error", {}).get("message", "Unknown error")}')
        raise
    except Exception as err:
        print(f'Other error occurred: {err}')
        raise

# WebSocket消息处理
def on_message(ws, message):
    data = json.loads(message)
    
    if data['type'] == 'message':
        print(f'New message received: {data["data"]}')
        # 处理新消息
    elif data['type'] == 'message_status':
        print(f'Message status updated: {data["data"]}')
        # 处理消息状态更新
    elif data['type'] == 'typing':
        print(f'User is typing: {data["data"]}')
        # 处理正在输入状态
    # 处理其他事件类型

def on_error(ws, error):
    print(f'WebSocket error: {error}')

def on_close(ws):
    print('WebSocket disconnected')
    # 实现重连逻辑
    time.sleep(5)
    connect_websocket(token)

def on_open(ws):
    print('WebSocket connected')

def connect_websocket(token):
    ws_url = f'wss://api.paperplane.com/v8/ws?token={token}'
    ws = websocket.WebSocketApp(
        ws_url,
        on_open=on_open,
        on_message=on_message,
        on_error=on_error,
        on_close=on_close
    )
    
    # 在后台线程中运行WebSocket
    ws_thread = threading.Thread(target=ws.run_forever)
    ws_thread.daemon = True
    ws_thread.start()
    
    return ws

# 使用示例
if __name__ == '__main__':
    token = 'your_access_token_here'
    
    # 发送消息
    try:
        message = send_text_message('chat1234567890', 'Hello from Python!', token)
        print(f'Message sent: {message}')
    except Exception as e:
        print(f'Failed to send message: {e}')
    
    # 连接WebSocket
    ws = connect_websocket(token)
    
    # 保持程序运行
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print('Program terminated')
        ws.close()

最佳实践

遵循以下最佳实践,确保您的应用高效、安全地使用纸飞机消息API。

消息处理

  • 实现消息队列机制,处理发送失败的情况
  • 使用指数退避算法处理API限流
  • 合理设置消息缓存策略,减少API调用
  • 优先使用WebSocket接收实时消息,而不是轮询
  • 实现消息分页加载,避免一次性加载过多消息

文件处理

  • 在发送大文件前,先上传文件获取file_id
  • 根据网络条件动态调整图片和视频的压缩质量
  • 实现文件下载进度显示
  • 缓存常用的图片和文件,减少重复下载

用户体验

  • 显示消息发送状态(发送中、已发送、已送达、已读)
  • 实现"正在输入"状态提示
  • 提供消息搜索功能
  • 支持消息通知和静默模式
  • 实现消息草稿功能

安全性

  • 不要在客户端存储敏感消息内容
  • 实现消息内容的本地加密存储
  • 定期清理过期的消息和文件缓存
  • 验证消息来源,防止伪造消息

纸飞机的端到端加密确保了消息的安全性,但您仍应采取措施保护用户设备上的消息数据。

常见问题

1. 如何处理消息发送失败?

当消息发送失败时,您应该:

  • 检查网络连接状态
  • 验证访问令牌是否有效
  • 实现重试机制,使用指数退避算法
  • 将失败的消息存储在本地,待网络恢复后重新发送

2. 如何实现消息的离线存储?

您可以使用本地数据库(如SQLite、Realm或Room)存储消息。对于敏感消息,建议在存储前进行加密。当用户重新上线时,可以将本地消息与服务器同步。

3. 如何优化大量消息的加载性能?

优化大量消息加载的策略包括:

  • 实现分页加载,每次只加载少量消息(如50条)
  • 使用虚拟列表,只渲染可视区域内的消息
  • 延迟加载消息中的图片和文件
  • 实现消息预加载,在用户滚动到底部前加载下一页

4. 如何处理WebSocket断开连接的情况?

处理WebSocket断开连接的最佳实践包括:

  • 实现自动重连机制,使用指数退避算法
  • 在重连时验证令牌是否仍然有效
  • 维护消息的发送状态,确保断开期间的消息能够正确发送
  • 在用户界面上显示连接状态

5. 如何实现消息搜索功能?

消息搜索可以通过以下方式实现:

  • 使用API的搜索参数进行服务器端搜索
  • 在客户端维护消息索引,实现本地搜索
  • 支持按发送者、日期、消息类型等条件筛选
  • 实现搜索建议和自动完成功能

6. 如何处理阅后即焚消息?

处理阅后即焚消息的步骤包括:

  • 在消息发送时设置expire_in字段
  • 在客户端跟踪消息的阅读时间
  • 在消息过期后自动删除本地存储的消息
  • 向服务器发送消息删除请求

有问题或建议?

帮助我们改进文档,提供反馈或寻求支持

相关文档

群组API

学习如何创建和管理群组聊天,包括成员管理、权限设置等功能。

阅读更多

文件上传API

了解如何上传图片、视频、音频和其他文件到纸飞机服务器。

阅读更多

通知API

学习如何管理消息通知,包括推送设置、免打扰模式等功能。

阅读更多