If we clean your indentation up, you can quickly see why you aren't getting back anything for "message" regardless of what you were trying in there - it returns the response before any of the asynchronous stuff even executes:
docRef.get()
    .then(async (snapshot: any) => {
        // <-- this line won't run
        /* ... removed for conciseness */
    });
res.send({
    "code": "ok",
    "message": attachmentList
});
// <-- before this line (and the response is sent already!)
What you are looking to do is to assemble your array of attachments, and then return them:
docRef.get()
    .then((snapshot) => {
        return Promise.all(
            snapshot.docs.map(async (attachmentDocSnapshot) => {
                const { paths, created_at, content_types } = attachmentDocSnapshot.data();
                const urls = await downloadFile(paths);
                return {
                    content_types,
                    created_at,
                    id: attachmentDocSnapshot.id,
                    paths: urls
                };
            })
        );
    })
    .then((attachmentInfoList) => {
        res.json({                                  // .json() is more semantic
            "code": "OK",                           // for consistency, capitalized
            "message": attachmentInfoList
        });
    })
    .catch((err) => {
        console.error(`Failed to collect information about the attachments for Doc #${docRef.id}: `, error);
        res.status(500).json({                      // 500 Internal Server Error
            "code": "ERROR",
            "message": error.code || error.message  // Send back as little information about the error as possible
        });
    });
While the above code works, it's not pretty. So let's rework it into a child function:
async function getAttachmentInfoFromSnapshot(attachmentDocSnapshot) {
    const { paths, created_at, content_types } = attachmentDocSnapshot.data();
    const urls = await downloadFile(paths);
    return {
        content_types,
        created_at,
        id: attachmentDocSnapshot.id,
        paths: urls
    };
}
docRef.get()
    .then((snapshot) => Promise.all(
        snapshot.docs.map(getAttachmentInfoFromSnapshot)
    ))
    .then((attachmentInfoList) => {
        res.json({                                  // .json() is more semantic
            "code": "OK",                           // for consistency, capitalized
            "message": attachmentInfoList
        });
    })
    .catch((err) => {
        console.error(`Failed to collect information about the attachments for Doc #${docRef.id}: `, error);
        res.status(500).json({                      // 500 Internal Server Error
            "code": "ERROR",
            "message": error.code || error.message  // Send back as little information about the error as possible
        });
    });
Note: You could rewrite the above to use async/await syntax on the next level up, but if you do, make sure to wrap it all in a try/catch block to handle any errors along the way.