WhatsApp Business API - WhatsApp Flow

489 views Asked by At

I am building WhatsApp Flow to retrieve orders. I am receiving the request and decrypting the message successfully. But I have trouble to encrypt response to WhatsApp. I got error: Invalid response from endpoint. I am using Python 3.9 and Pipedream. Some help?

See my encrypt code bellow:

from base64 import b64decode, b64encode
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import json

def handler(pd: "pipedream"):
    # Getting the decrypted AES key and IV
    aes_key_b64 = pd.steps["Decrypt_WhatsApp_Key"]["$return_value"]["decrypted_aes_key"]
    iv_b64 = pd.steps["trigger"]["event"]["body"]["initial_vector"]

    # Decoding AES key and base64 IV to bytes
    aes_key = b64decode(aes_key_b64)
    iv = b64decode(iv_b64)

    # Preparing the inverted IV
    iv_flipped = flip_iv(iv)

    # Preparing response
    response = {
        "version": "3.0",
        "screen": "SUCCESS",
        "data": {
            "extension_message_response": {
                "params": {
                    "flow_token": pd.steps["Decrypt_WhatsApp_Message"]["$return_value"]["flow_token"],
                    "status": pd.steps["shopify_developer_app"]["$return_value"]["orders"][0]["id"]
                }
            }
        }
    }

    response = json.dumps(response)

    # Encrypting the response
    cipher = Cipher(algorithms.AES(aes_key), modes.GCM(iv_flipped))
    encryptor = cipher.encryptor()
    encrypted = encryptor.update(response.encode("utf-8")) + encryptor.finalize() + encryptor.tag
    encrypted_response = b64encode(encrypted).decode("utf-8")

    # Response return 
    return {
        "status": 200,
        "body": encrypted_response,
        "headers": {
            "Content-Type": "application/json"
        }
    }

def flip_iv(iv):
    flipped_bytes = []
    for byte in iv:
        flipped_byte = byte ^ 0xFF
        flipped_bytes.append(flipped_byte)
    return bytes(flipped_bytes)```
1

There are 1 answers

0
gafi On

You need to return the response as plain text. Here's and example for Django

return HttpResponse(encrypted_response, content_type='text/plain')

For Pipedream it should be like this

return {
  status: 200,
  headers: { "content-type": "text/plain" },
  body: encrypted_response
}