# Messages

## **SendMessageTo**

Sends a message from one phone number to another. This is the recommended export for most use cases as it auto-resolves the sender's phone IMEI and channel ID.

```lua
---@param from string The sender's phone number
---@param to string|string[] The recipient phone number(s) - can be a single string or array
---@param message string The message content
---@param attachments string|nil Optional: JSON string of attachments array
---@return table|nil Result object with channelId, messageId, targetSource, timestamp, or nil if failed
local result = exports.yseries:SendMessageTo(
    "0881111",           -- from (sender's phone number)
    "0882222",           -- to (recipient's phone number)
    "Hello there!"       -- message
)

if result then
    print("Message sent! ChannelId: " .. result.channelId)
    print("MessageId: " .. result.messageId)
    print("Timestamp: " .. result.timestamp)
end
```

**Returns:**

```lua
{
    channelId = "abc123def456",
    messageId = 12345,
    targetSource = 1,  -- Target player source ID (if online, nil if offline)
    timestamp = 1703123456
}
```

**Examples:**

```lua
-- Send a message with location attachment
local locationAttachments = json.encode({
    {
        location = {
            x = -1037.0,
            y = -2738.0
        }
    }
})
local result = exports.yseries:SendMessageTo(
    "0881111",
    "0882222",
    "Meet me here!",
    locationAttachments
)
```

**Attachment Types:**

The `attachments` parameter accepts a JSON-encoded string containing an array of attachment objects:

* **Photo:** `[{ photo = "https://example.com/image.jpg" }]`
* **Location:** `[{ location = { x = -1037.0, y = -2738.0 } }]`

**Notes:**

* **Sender number**: Can be non-existent (e.g., payphone, system message). The sender's phone IMEI is automatically resolved if the phone exists, otherwise the message will be sent without an IMEI.
* **Recipient number(s)**: **MUST exist and be valid**. The function will return `nil` if any recipient phone number doesn't exist.
* Channel ID is automatically resolved if a conversation already exists between the two numbers
* If no existing channel is found, a new one will be created automatically
* For group messages (multiple recipients), a new channel will always be created
* Returns `nil` if the message fails to send (e.g., invalid parameters, recipient doesn't exist, database error)

***

## **SendMessage**

Advanced export for sending messages with full control over all parameters. Use `SendMessageTo` for most use cases.

```lua
---@param participants string[] Array of recipient phone numbers
---@param message string The message content
---@param senderDeviceNumber string The sender's phone number
---@param senderPhoneImei string The sender's phone IMEI
---@param channelId string|nil Optional: Channel ID if sending to an existing channel
---@param attachments string|nil Optional: JSON string of attachments array
---@return table|nil Result object with channelId, messageId, targetSource, timestamp, or nil if failed
local result = exports.yseries:SendMessage(
    {"0882222"},           -- participants (array of phone numbers)
    "Hello there!",        -- message
    "0881111",            -- senderDeviceNumber
    "imei123456",         -- senderPhoneImei
    nil,                  -- channelId (nil for new conversation)
    nil                   -- attachments (nil for no attachments)
)
```

**Returns:**

```lua
{
    channelId = "abc123def456",
    messageId = 12345,
    targetSource = 1,  -- Target player source ID (if online, nil if offline)
    timestamp = 1703123456
}
```

**Note:**

* If `channelId` is provided, the message will be added to that existing channel
* If `channelId` is `nil`, the function will look for an existing channel between the sender and recipient(s)
* If no existing channel is found, a new channel will be created automatically
* Returns `nil` if the message fails to send
