If you use iMessage, you can access and query the database where all of the messages are stored. All you need is a Mac and some basic SQL skills to begin!
Using prisma.$queryRaw, I was able to write a basic query that returned the data I needed. However, I also needed the query to filter and order the data.
You can represent types with both shared and type-specific attributes as a discriminated union in TypeScript. Let's model that relationship in a database.