All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.stormbit.vksdk.objects.Message.kt Maven / Gradle / Ivy

The newest version!
package com.github.stormbit.vksdk.objects

import com.github.stormbit.vksdk.objects.attachments.AttachmentType
import com.github.stormbit.vksdk.objects.attachments.Audio
import com.github.stormbit.vksdk.objects.attachments.Document
import com.github.stormbit.vksdk.objects.attachments.Photo
import com.github.stormbit.vksdk.objects.attachments.Video
import com.github.stormbit.vksdk.objects.attachments.Voice
import com.github.stormbit.vksdk.objects.models.Keyboard
import com.github.stormbit.vksdk.objects.models.MessagePayload
import com.github.stormbit.vksdk.objects.models.ServiceAction
import com.github.stormbit.vksdk.utils.mediaString
import com.github.stormbit.vksdk.vkapi.methods.Attachment
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.util.concurrent.CopyOnWriteArrayList
import com.github.stormbit.vksdk.objects.models.Message as MessageModel

@Suppress("unused")
class Message {
    var messageId: Int = 0
        private set

    val senderType: SenderType get() = getSenderType(peerId)
    var serviceActionType: ServiceAction.Type? = null

    var timestamp: Int = 0
        private set

    var chatId: Int = 0
    var chatIdLong: Int = 0

    var peerId: Int = 0
    var randomId: Int = 0
    var stickerId: Int = 0
    var replyTo: Int? = null

    var keyboard: Keyboard? = null

    var payload: MessagePayload = MessagePayload("{}")

    var text: CharSequence = ""


    /**
     * Attachments in format of received event senderType LongPoll server
     *
     * @see: https://vk.com/dev/using_longpoll_2
     */
    internal var receivedAttachments = Attachments()
    internal var receivedForwards: List = emptyList()
    internal var receivedReplyMessage: MessageModel.Forward? = null

    internal val attachmentTypes = CopyOnWriteArrayList()

    /**
     * Attachments in format [photo62802565_456241137, photo111_111, doc100_500]
     */
    @PublishedApi internal val attachmentsToSend = CopyOnWriteArrayList()
    @PublishedApi internal val forwardedMessagesToSend = CopyOnWriteArrayList()

    /**
     * Constructor for received message
     *
     * @param messageId message id
     * @param peerId peer id
     * @param timestamp timestamp
     * @param text message text
     * @param attachments message items
     * @param randomId random id
     */
    constructor(messageId: Int, peerId: Int, timestamp: Int, text: String, attachments: Attachments, randomId: Int, payload: MessagePayload) {
        this.messageId = messageId
        this.peerId = peerId
        this.timestamp = timestamp
        this.text = text
        this.receivedAttachments = attachments
        this.stickerId = attachments.getStickerId()
        this.randomId = randomId
        this.payload = payload
    }

    /**
     * Constructor for received message
     *
     * @param message Message model
     */
    constructor(message: MessageModel) {
        this.messageId = message.id
        this.peerId = message.peerId
        this.timestamp = message.date
        this.text = message.text
        this.randomId = message.randomId ?: 0
        this.receivedForwards = message.forwardedMessages
        this.receivedReplyMessage = message.replyMessage

        if (message.attachments.isNotEmpty()) {
            val attachs = ArrayList()

            message.attachments.forEach {
                var attach: String? = null
                var type: AttachmentType? = null

                if (it.photo != null) {
                    attach = it.photo.mediaString
                    type = it.type
                    attachmentTypes.add(AttachmentType.PHOTO)
                }

                if (it.video != null) {
                    attach = it.video.mediaString
                    type = it.type
                    attachmentTypes.add(AttachmentType.VIDEO)
                }

                if (it.audio != null) {
                    attach = it.audio.mediaString
                    type = it.type
                    attachmentTypes.add(AttachmentType.AUDIO)
                }

                if (it.document != null) {
                    attach = it.document.mediaString
                    type = it.type
                    attachmentTypes.add(AttachmentType.DOC)
                }

                if (it.voice != null) {
                    attach = it.voice.mediaString
                    type = it.type
                    attachmentTypes.add(AttachmentType.VOICE)
                }

                if (it.sticker != null) {
                    attach = "sticker"
                    type = it.type
                    attachmentTypes.add(AttachmentType.STICKER)
                }

                attachs.add(Attachments.Item(attach!!, type!!))
            }

            this.receivedAttachments = Attachments(attachs, message.forwardedMessages.isNotEmpty())
        }

        if (message.serviceAction != null) {
            this.serviceActionType = message.serviceAction.type
        }

        if (message.payload != null) this.payload = message.payload

        if (this.peerId > Chat.CHAT_PREFIX) {
            this.chatId = this.peerId - Chat.CHAT_PREFIX
            this.peerId = message.fromId

            this.messageId = message.conversationMessageId
        }

        if (this.chatId > 0) {
            this.chatIdLong = this.chatId + Chat.CHAT_PREFIX
        }
    }

    constructor(block: Message.() -> Unit) {
        block()
    }

    /**
     * @return true if message has forwarded messages
     */
    val hasForwards: Boolean get() = receivedAttachments.hasFwd || receivedForwards.isNotEmpty()

    /**
     * @return true if message has reply message
     */
    val hasReply: Boolean get() = receivedReplyMessage != null
    val replyMessage get() = receivedReplyMessage
    val forwardedMessages get() = forwardedMessagesToSend
    val attachments get() = attachmentsToSend

    /**
     * @param T Attachment type: Audio, Video, Photo, Voice, Document
     * @return List of string attachments
     */
    @PublishedApi
    internal fun  getAttachments(type: Class): List {
        val attachs = receivedAttachments.items

        if (attachs.isNotEmpty()) {
            return when (type) {
                Audio::class.java -> {
                    attachs
                        .filter { it.attachmentType == AttachmentType.AUDIO }
                        .map { it.attach }
                }

                Photo::class.java -> {
                    attachs
                        .filter { it.attachmentType == AttachmentType.PHOTO }
                        .map { it.attach }
                }

                Document::class.java -> {
                    attachs
                        .filter { it.attachmentType == AttachmentType.DOC }
                        .map { it.attach }
                }

                Voice::class.java -> {
                    attachs
                        .filter { it.attachmentType == AttachmentType.VOICE }
                        .map { it.attach }
                }

                Video::class.java -> {
                    attachs
                        .filter { it.attachmentType == AttachmentType.VIDEO }
                        .map { it.attach }
                }

                else -> emptyList()
            }
        }

        return emptyList()
    }

    /**
     * @return List of string attachments
     */
    inline fun  getAttachments(): List {
        return getAttachments(T::class.java)
    }

    val isMessageFromChat: Boolean get() = chatId > 0 || chatIdLong > 0
    val isSimpleTextMessage: Boolean get() = attachmentTypes.isEmpty()
    val isPhotoMessage: Boolean get() = attachmentTypes.contains(AttachmentType.PHOTO)
    val isVoiceMessage: Boolean get() = attachmentTypes.contains(AttachmentType.VOICE)
    val isAudioMessage: Boolean get() = attachmentTypes.contains(AttachmentType.AUDIO)
    val isVideoMessage: Boolean get() = attachmentTypes.contains(AttachmentType.VIDEO)
    val isDocMessage: Boolean get() = attachmentTypes.contains(AttachmentType.DOC)
    val isWallMessage: Boolean get() = attachmentTypes.contains(AttachmentType.WALL)
    val isStickerMessage: Boolean get() = attachmentTypes.contains(AttachmentType.STICKER)
    val isLinkMessage: Boolean get() = attachmentTypes.contains(AttachmentType.LINK)

    private fun getSenderType(peerId: Int) = when {
        peerId > 2000000000 -> SenderType.CHAT
        peerId < 0 -> SenderType.COMMUNITY
        else -> SenderType.USER
    }

    override fun toString(): String {
        return buildString {
            append("{")
            append("\"message_id\": $messageId,")
            append("\"peer_id\": $peerId,")
            append("\"timestamp\": $timestamp,")
            append("\"random_id\": $randomId,")
            append("\"text\": \"$text\",")
            append("\"items\": $receivedAttachments,")
            append("\"payload\": \"${payload.value}\"")
            append("}")
        }
    }

    enum class SenderType {
        USER,
        COMMUNITY,
        CHAT
    }

    @Serializable
    data class Attachments(
        @SerialName("items") val items: List = emptyList(),
        @SerialName("fwd") val hasFwd: Boolean = false,
        @SerialName("senderType") val from: Int? = null) {

        @Serializable
        data class Item(
            @SerialName("attach") val attach: String,
            @SerialName("attach_type") val attachmentType: AttachmentType,
            @SerialName("attach_kind") val kind: String? = null
        )

        fun toArray() = items
            .filter { it.attachmentType != AttachmentType.STICKER }
            .map { it.attachmentType.value + it.attach }
            .toTypedArray()

        fun getStickerId(): Int {
            val list = items.filter { it.attachmentType == AttachmentType.STICKER }

            return if (list.isNotEmpty()) return list[0].attach.toInt() else 0
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy