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

WhatsApp Flow端点加密交互测试异常问题求助

WhatsApp Flow data-exchange 动作跳转异常排查求助

我正在使用Meta UI构建WhatsApp Flow,在Meta UI Flow Builder中测试data-exchange动作时,无法正常跳转到指定屏幕。我的实现逻辑如下:

  • 用Google Scripts作为端点,接收Meta发送的加密payload(使用我上传至Meta服务器的公钥加密)
  • Google Scripts调用Lambda函数解密数据,根据业务逻辑生成跳转响应
  • 将响应加密后返回给Meta,引导Flow跳转到下一个屏幕

Google Scripts 端点代码

var mainss = SpreadsheetApp.openById('11wVWWD17CvhHChcTnJ4r6MbI6F1GUHCpDXhQZWxMwDA');
var flowsLog = mainss.getSheetByName('Flow Log')


function doPost(e) {

  try {
    // Extract the payload
    var requestBody = e.postData.contents;
    flowsLog.appendRow([new Date(), "Received data", JSON.stringify(requestBody)]);

    //Preserve encryption values
    var encryptionVariables = JSON.parse(requestBody);

    // Check for error notification
    if (encryptionVariables.action === 'data_exchange' && encryptionVariables.data.hasOwnProperty('error_key')) {
      flowsLog.appendRow([new Date(), "Error Notification", JSON.stringify(encryptionVariables)]);
      
      // Respond to acknowledge the error notification
      var errorAckResponse = {
        "data": {
          "acknowledged": true
        }
      };
      
      return ContentService.createTextOutput(JSON.stringify(errorAckResponse))
                           .setMimeType(ContentService.MimeType.JSON);
    }

  //Decrypt payload call Lambda through Gateway API
  var decryptedPayload = decryptData(encryptionVariables);
  var decryptedData = JSON.parse(decryptedPayload.decrypted_data);
  var action = decryptedData.action;

  
  flowsLog.appendRow([new Date(), "Descrypted Data", JSON.stringify(decryptedData)]);
  

  // Check for a health check request
  if (action === 'ping') {
    return ContentService.createTextOutput(JSON.stringify({
      'version': '3.0',
      'data': {
        'status': 'active'
      }
    })).setMimeType(ContentService.MimeType.JSON);
  } else if (action === 'data_exchange') {

    // Extract the current screen ID
    var screen = decryptedData.screen
    var data = decryptedData.data

    
    // Initialize variables for the next screen and response data
    var nextScreen = '';
    var responseData = {};

    // Determine the next screen and response data based on the current screen
    //switch (screen) {}
      
    //Forcing some data to test the flow
    var response = {
      "rawData": {
        "version": "3.0",
        "screen": "SESSION_ONE",
        "data": responseData
      },
      "encrypted_aes_key": encryptionVariables.encrypted_aes_key,
      "initial_vector": encryptionVariables.initial_vector
    };
    

    //Encrypt data calling Lambda Function
    var encryptedData = encryptData(response);


    flowsLog.appendRow([new Date(), "Raw Data", JSON.stringify(response.rawData)]);
    flowsLog.appendRow([new Date(), "Encrypted Data", encryptedData]);

    // 返回响应
    return ContentService.createTextOutput(encryptedData).setMimeType(ContentService.MimeType.TEXT);


  } else {
    return ContentService.createTextOutput("ERROR in Request")

  }
  }catch(e){
        flowsLog.appendRow([new Date(), "Error in endpoint", e])
        Logger.log(e);

  }
}

日志示例

  • 从Meta接收的数据:
"{\"encrypted_flow_data\":\"ikGRIjrW1sBzHECFHvVFkTXcsiVR24eW2Jvd5gmPvrkTp38NA4kG4mLCBB3qWyi36r5IX6BVBZ415Tar0fBHmWiyEEirVjmyPF1N\\/WEcVEHcgCuHAOC0Vj2z1tRSBQOSMfQdUbsGqWncMpWEEztD\\/a8CfrD5WTRWFG52p0twN6XnbnuX20DOjHoOMMGgAuPr8rB4rE88UkXS4XOBuSbxomS89UBPZsVfn4ZSe8xj70dVuAmNqmBOvZQVlLr2edOENssLTb6dj0cTvdGOEAia6HbyxZoOXNzMp5q38guT7Jw=\",\"encrypted_aes_key\":\"q4Ww1XFn0TadlE5H0pnJ6PzX3lXfeZwqYSZPKop\\/jWCweaY9d+Z1pMjfM1UX3te\\/GdHIpa8sa1chPSLOgxiYDbAcQ3uiJqlfOKLbdCuz\\/HTvVoTvrn3e\\/BJl9ALHeqOCqqIwGuHz2YcXvqc7zD4asU3mczrRa8Xvo8+YY89qebfF62F4f77ApXjT3LT\\/ynn7hYkxbMKo02bdIbteZAwSh+OMFVoMJo6vwOmH3fvbLSzcA80C8QIf7WVKQ7imik5+u2wETQOUDZ2Drmeyyh+xc\\/bTDi+GrSEpfXrI4jtnbd4YxPZLSlcaXAooK6ot9DP4ioOGSTxCCsAmz8ht87mHGQ==\",\"initial_vector\":\"SFWNZlzEXH6Cs0JeWMcJJQ==\"}"
  • 解密后的数据:
{"version":"3.0","action":"data_exchange","screen":"WELCOME_SCREEN_EVENTS","data":{"event_type":"${form.event_type}","house":"${form.house}","event_date":"${form.date}"},"flow_token":"flows-builder-adacf0e2"}
  • 原始响应数据:
{"version":"3.0","screen":"SESSION_ONE","data":{"event_type":"2","house":"1","event_date":"30/11/2023"}}
  • 加密后的响应数据:
4/qcTvBZpQmZtKVPjow0jpISGTG3SicgOmCoxJKYUnhJqWylgZY2sNzp0ICFb1J3STDZugVWuolrmfAOSeTS6mCLUGj4sBStAZrTBz1p0NNlXW/XXVBe/a5c3d3iSiAO0YZdaQRvKuKW47YZHbFcUxuTX6AWiBZ3j6dADvLElwpPBg==

Flow Builder 要求的跳转响应格式

// 跳转到屏幕:SESSION_ONE
{
    "version": "3.0",
    "screen": "SESSION_ONE",
    "data": {
        "event_type": "Sesión fotográfica",
        "house": "Casa Kali",
        "event_date": "22\/12\/2023"
    }
}

Lambda 加密函数核心代码

# 加密rawData
cipher = Cipher(algorithms.AES(key), modes.GCM(flipped_iv))
encryptor = cipher.encryptor()
encrypted = encryptor.update(json.dumps(raw_data).encode("utf-8")) + encryptor.finalize() + encryptor.tag
encrypted_response_b64 = b64encode(encrypted).decode("utf-8")

# 生成响应
response = {
    'encrypted_response': encrypted_response_b64
}

# 修改:仅返回encrypted_response
return {
    'statusCode': 200,
    'body': json.dumps(encrypted_response_b64)
}

已知情况

已确认Lambda加解密功能正常,解密加密后的响应可得到正确的原始响应数据,但在Flow Builder中测试时,始终无法跳转到指定的SESSION_ONE屏幕,恳请协助排查问题。

内容的提问来源于stack exchange,提问作者Darío Magaña

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:25:55