Собеседник ответил на конкретное сообщение — своё, ваше или участника группы. В уведомлении есть текст ответа и ссылка на исходное сообщение.
typeWebhook |
incomingMessageReceived |
typeMessage |
quotedMessage |
| Флаг настроек | incomingWebhook |
| Каналы | MAX, Telegram, WhatsApp, почта |
Пример
Школа спросила Марию в MAX «Записать вас на субботу?», Мария ответила на это сообщение:
{
"typeWebhook": "incomingMessageReceived",
"instanceData": {"idInstance": 7100000001, "wid": "79990000001@c.us", "typeInstance": "v3", "channel": "max"},
"timestamp": 1791823690,
"idMessage": "117428957302164485",
"eventId": "msg:8695836:117428957302164485",
"senderData": {
"chatId": "8695836", "chatName": "Мария", "chatType": "user",
"sender": "8695836", "senderName": "Мария", "senderType": "user",
"senderContactName": "", "senderPhoneNumber": 0
},
"messageData": {
"typeMessage": "quotedMessage",
"extendedTextMessageData": {
"text": "Да, в субботу удобно",
"stanzaId": "117428956522361912",
"participant": "457747484"
},
"quotedMessage": {
"stanzaId": "117428956522361912",
"participant": "457747484",
"typeMessage": "textMessage",
"textMessage": "Записать вас на субботу?"
}
}
}
Поля
| Поле | Описание |
|---|---|
extendedTextMessageData.text |
текст ответа |
extendedTextMessageData.stanzaId |
idMessage сообщения, на которое ответили |
extendedTextMessageData.participant |
автор исходного сообщения; "", если площадка не сообщила |
quotedMessage.stanzaId, quotedMessage.participant |
то же — для совместимости с Green API |
quotedMessage.textMessage |
текст исходного сообщения или подпись к файлу; есть, только если площадка его отдала |
quotedMessage.typeMessage |
textMessage — когда есть textMessage |
Остальные поля конверта — в статье Формат уведомления.
Ответ файлом и другим содержимым
Ответить можно не только текстом. Тогда typeMessage — вид содержимого (imageMessage, locationMessage и т. д.), а quotedMessage лежит рядом:
"messageData": {
"typeMessage": "imageMessage",
"fileMessageData": {
"downloadUrl": "https://api.gratio.net/media/7100000001/8695836/117428960974949548/0/d8f9…",
"caption": "Вот чек об оплате", "fileName": "117428960974949548.jpg", "jpegThumbnail": "",
"isAnimated": false, "mimeType": "image/jpeg", "forwardingScore": 0, "isForwarded": false
},
"quotedMessage": {
"stanzaId": "117428956522361912", "participant": "457747484",
"typeMessage": "textMessage", "textMessage": "Пришлите, пожалуйста, чек"
}
}
Поэтому проверяйте наличие quotedMessage, а не только typeMessage == "quotedMessage".
В других каналах
| Канал | participant |
Текст исходного сообщения |
|---|---|---|
| MAX | id автора | есть |
| Telegram | "" |
нет — только stanzaId |
адрес автора, "79991234567@c.us" |
есть | |
| Почта | ""; stanzaId — письмо из заголовка In-Reply-To |
нет |
В группе participant — участник, чьё сообщение процитировали. Голос в опросе WhatsApp тоже приходит ответом цитатой на опрос — см. Опрос.
Как обработать
Связать ответ с вашим сообщением — например, подтвердить запись:
def on_reply(body: dict) -> None:
if body["typeWebhook"] != "incomingMessageReceived":
return
data = body["messageData"]
quoted = data.get("quotedMessage")
if quoted is None:
return
question = find_sent(quoted["stanzaId"]) # ваша таблица отправленных: idMessage → вопрос
if question is None:
return
text = data.get("extendedTextMessageData", {}).get("text", "")
save_answer(question, body["senderData"]["chatId"], text)
Что дальше
- sendMessage — ответить цитатой:
quotedMessageId. - Ссылка и пересланное — пересланные сообщения и превью ссылок.
- Текст — обычное текстовое сообщение.
