You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PubNub Message Actions API时遭遇500内部服务器错误求助

PubNub addMessageAction 调用返回500内部服务器错误排查与解决

问题背景

开发聊天功能时,使用PubNub的Message Actions API为已发布消息添加isRead动作,调用pubnub.addMessageAction时持续返回500内部服务器错误。

错误响应详情

{
  "error": true,
  "operation": "PNAddActionOperation",
  "statusCode": 500,
  "errorData": {
    "original": null,
    "response": {
      "req": {
        "method": "POST",
        "url": "https://ps18.pndsn.com/v1/message-actions/my_sub_key/channel/my_channel_name/message/17053072012353411?uuid=my_user_uuid&pnsdk=PubNub-JS-Web%2F7.4.5&l_hist=791&l_pres=1733",
        "data": {
          "type": "isRead",
          "value": true
        },
        "headers": {
          "content-type": "application/json"
        }
      },
      "xhr": {},
      "text": "<html>\r\n<head><title>500 Internal Server Error</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>500 Internal Server Error</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n<!-- a padding to disable MSIE and Chrome friendly error page -->\r\n",
      "statusText": "Internal Server Error",
      "statusCode": 500,
      "status": 500,
      "statusType": 5,
      "info": false,
      "ok": false,
      "redirect": false,
      "clientError": false,
      "serverError": true,
      "error": {
        "status": 500,
        "method": "POST",
        "url": "https://ps18.pndsn.com/v1/message-actions/my_sub_key/channel/my_channel_name/message/17053072012353411?uuid=my_user_uuid&pnsdk=PubNub-JS-Web%2F7.4.5&l_hist=791&l_pres=1733"
      },
      "created": false,
      "accepted": false,
      "noContent": false,
      "badRequest": false,
      "unauthorized": false,
      "notAcceptable": false,
      "forbidden": false,
      "notFound": false,
      "unprocessableEntity": false,
      "headers": {
        "content-length": "588",
        "content-type": "text/html"
      },
      "header": {
        "content-length": "588",
        "content-type": "text/html"
      },
      "type": "text/html",
      "links": {},
      "body": null
    },
    "status": 500
  },
  "category": "PNUnknownCategory"
}

关联代码

let pubnub;

const pubnub_publish_key = 'demo'
const pubnub_subscribe_key = 'demo'

const user_id = 'test_user_id'

const my_channel_name = 'test_channel'

const setupPubNub = () => {
  // Initialize PubNub with the publish and subscribe keys and the current user's ID
  pubnub = new PubNub({
    publishKey: pubnub_publish_key,
    subscribeKey: pubnub_subscribe_key,
    userId: user_id,
    reconnectPolicy: 'linear'
  });

  await pubnub.subscribe({
    channels: [my_channel_name],
    presence: true,
  });
  
  fetchMessages(my_channel_name)

  const listener = {
    status: (statusEvent) => {
      if (statusEvent.category === "PNConnectedCategory") {
        console.log("Connected")
      }
    },
    message: (messageEvent) => {
      console.log(messageEvent)
    },
    presence: function(presenceEvent) {
      console.log(presenceEvent)
    }
  };

  pubnub.addListener(listener);
};

window.onload = setupPubNub;
window.onbeforeunload = (event) => {
  pubnub.unsubscribeAll();
}


// Asynchronous function to fetch messages from a channel
const fetchMessages = async(channelName) => {
  try {
    // Fetch messages from the channel
    await pubnub.fetchMessages({
      channels: [channelName],
      count: 100,
      stringifiedTimeToken: true,
    }, (status, response) => {
      if (status.error) {
        throw new Error(JSON.stringify(status));
      } else {
        // Encode the channel name (becaues it contains a colon)
        const encodedChannelName = encodeURIComponent(channelName)
        if (response) {
          // Get the messages from the response
          const messages = response.channels[encodedChannelName]

          // If there are messages
          if (messages) {
            // Wrap the loop in an async function
            (async() => {
              // For each message
              for (let i = 0; i < messages.length; i++) {
                let {
                  uuid,
                  timetoken,
                  message: {
                    text: messageText
                  }
                } = messages[i];

                //other code goes here to insert the message text and time to ket to the ui. Removed it becasue it doesn't matter for the error i am getting

                // If this is the last message
                if (i == messages.length - 1) {
                  let lastMessageTimetoken = messages[i]?.timetoken

                  //logs the last message data properly
                  console.log(channelName, lastMessageTimetoken)

                  const isRead = messages[i].message?.isRead ? true : await updateIsRead(channelName, lastMessageTimetoken);

                  console.log(isRead)
                }
              }
            })();
          }
        }
      }
    });
  } catch (error) {
    // Log any errors that occurred
    console.error(`Error in fetchMessages: ${error.message}`);
  }
}

//this is where i get the error
const updateIsRead = async(channelName, timetoken) => {
  if (typeof channelName !== 'string' || typeof timetoken !== 'string') {
    console.error('Invalid parameters');
    return;
  }
  await pubnub.addMessageAction({
      channel: channelName,
      messageTimetoken: timetoken,
      action: {
        type: 'isRead',
        value: true,
      },
    },
    function(status, response) {
      if (status.error) {
        return status
      } else {
        return response
      }
    }
  );
}

排查与解决建议

  • 修正异步代码混用问题:

    1. setupPubNub未标记为async却使用await,会直接导致初始化失败,需改为async setupPubNub。
    2. fetchMessages和updateIsRead同时混用await与回调函数,会导致异步流程混乱,建议统一使用Promise风格(去掉回调,直接用await接收返回值)。
  • 检查timetoken有效性:
    确认从fetchMessages返回的timetoken是完整的有效字符串(PubNub timetoken通常为17位及以上),无效的timetoken会导致服务器解析失败触发500错误。

  • 替换Demo密钥:
    公共demo密钥存在功能限制,大概率不支持Message Actions,需替换为自己的PubNub套餐密钥,并确保Message Actions权限已开启。

  • 通道名称处理:
    addMessageAction的channel参数需传入原始未编码的通道名,SDK会自动处理特殊字符编码,传入已编码名称会导致服务器无法识别通道。

  • 升级SDK版本:
    当前使用的7.4.5版本可能存在已知bug,建议升级到最新稳定版后重试。


内容的提问来源于stack exchange,提问作者seriously

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 01:09:50