Dev:IMCore.framework

IMCore is a framework that helps to manage handling SMS, iMessage, and MMS along with ChatKit.framework. IMCore exists on MacOS (X) as well as iOS, unlike ChatKit (which only exists on iOS).

Connecting to IMDaemon
For any process that tries to use classes or functions from IMCore, imagent (the iMessages Daemon on iOS) checks permissions to verify that the process is allowed to access what it's trying to access. To bypass this and allow your app or tweak to access what it needs to, just do the following:

You can also conditionally check for the process to only allow your process access to IMCore. For example, if you'd like to only allow SpringBoard to access IMCore, then you can do the following:

However, even after you've hijacked the capabilities to always return full permissions, you must still sometimes connect to the IMDaemon to run your code. There are probably multiple methods to do this, but the following has worked perfectly for me:

Within the "connectToDaemon" block above is where you'll run your IMCore-exclusive code. Unless stated otherwise, just assume that the rest of the code on this page is being run inside that block.

Sending a Text
On the ChatKit.framework page, there's information about how to send a text with attachments. However, if you'd prefer not to use ChatKit, you can send a text exclusively with IMCore. Theoretically, you can also send attachments with IMCore as well, but I have yet to figure that out. Here's the code:

There are multiple functions in "IMMessage" that start with "instantMessageWithText" and have different parameters, so you can call whichever specific one fits best for your needs.

Sending a Tapback
Sending a tapback requires a significant bit of code, including the chat_identifier of the conversation in which you're sending the tapback, the guid of the text which you are reacting to, and the tapback type that you are sending. The tapback type is a long long between 2000 - 2005, inclusive. A 'Love' is 2000, 'Thumbs Up' is 2001, 'Thumbs Down' is 2002, 'Ha Ha' is 2003, 'Exclamation' is 2004, and 'Question' is 2005. To remove a tapback of a certain type, you'll just need to add 1000 to the tapback value. For example, if you want to remove a 'Ha ha', you'll just run the code below, but with the tapback value being 3003 instead of 2003.

Basically every function below is liable to unexpectedly return nil, in my testing, so I'd recommend adding a few retries here and there where needed. The code below is just the bare minimum, and will work only if everything goes perfectly (which it probably won't).

Typing Indicators
To sense when someone is typing or recently stopped typing, you'll just need to hook the following two functions:

To send a typing indicator is actually fairly simple (as opposed to detecting them). All you'll need is the address of the conversation for which you want to send a typing indicator (e.g. the full phone number or email address). If you wanted to send a typing indicator for the conversation with the phone number "+11231231234", this is the code you'd run:

Getting Pinned Chats
This is only available in iOS 14+ and MacOS 10.16 (11.0)+. However, this snippet doesn't work on MacOS. The [pinnedController pinnedConversationIdentifierSet] method returns an NSOrderedList of pinning identifiers, not addresses. We have to use ChatKit to parse those pinning identifiers to get us the actual addresses of the conversations to which those pinning identifiers correspond.

Setting a conversation as read
Once again, very straightforward; you just need the address of the conversation that you want to set as read.