0) return NULL; return $peer_id; } return $user_id; } function getById(string $message_ids, int $preview_length = 0, int $extended = 0): object { $this->requireUser(); $msgs = new MSGRepo; $ids = preg_split("%, ?%", $message_ids); $items = []; foreach($ids as $id) { $message = $msgs->get((int) $id); if(!$message) continue; else if($message->getSender()->getId() !== $this->getUser()->getId() && $message->getRecipient()->getId() !== $this->getUser()->getId()) continue; $author = $message->getSender()->getId() === $this->getUser()->getId() ? $message->getRecipient()->getId() : $message->getSender()->getId(); $rMsg = new APIMsg; $rMsg->id = $message->getId(); $rMsg->user_id = $author; $rMsg->from_id = $message->getSender()->getId(); $rMsg->date = $message->getSendTime()->timestamp(); $rMsg->read_state = 1; $rMsg->out = (int) ($message->getSender()->getId() === $this->getUser()->getId()); $rMsg->body = $message->getText(false); $rMsg->text = $message->getText(false); $rMsg->emoji = true; if($preview_length > 0) $rMsg->body = ovk_proc_strtr($rMsg->body, $preview_length); $rMsg->text = ovk_proc_strtr($rMsg->text, $preview_length); $items[] = $rMsg; } return (object) [ "count" => sizeof($items), "items" => $items, ]; } function send(int $user_id = -1, int $peer_id = -1, string $domain = "", int $chat_id = -1, string $user_ids = "", string $message = "", int $sticker_id = -1) { $this->requireUser(); if($chat_id !== -1) $this->fail(946, "Chats are not implemented"); else if($sticker_id !== -1) $this->fail(-151, "Stickers are not implemented"); else if(empty($message)) $this->fail(100, "Message text is empty or invalid"); # lol recursion if(!empty($user_ids)) { $rIds = []; $ids = preg_split("%, ?%", $user_ids); if(sizeof($ids) > 100) $this->fail(913, "Too many recipients"); foreach($ids as $id) $rIds[] = $this->send(-1, $id, "", -1, "", $message); return $rIds; } if(!empty($domain)) { $peer = (new USRRepo)->getByShortCode($domain); } else { $peer = $this->resolvePeer($user_id, $peer_id); $peer = (new USRRepo)->get($peer); } if(!$peer) $this->fail(936, "There is no peer with this id"); if($this->getUser()->getId() !== $peer->getId() && !$peer->getPrivacyPermission('messages.write', $this->getUser())) $this->fail(945, "This chat is disabled because of privacy settings"); # Finally we get to send a message! $chat = new Correspondence($this->getUser(), $peer); $msg = new Message; $msg->setContent($message); $msg = $chat->sendMessage($msg, true); if(!$msg) $this->fail(950, "Internal error"); else return $msg->getId(); } function delete(string $message_ids, int $spam = 0, int $delete_for_all = 0): object { $this->requireUser(); $msgs = new MSGRepo; $ids = preg_split("%, ?%", $message_ids); $items = []; foreach($ids as $id) { $message = $msgs->get((int) $id); if(!$message || $message->getSender()->getId() !== $this->getUser()->getId() && $message->getRecipient()->getId() !== $this->getUser()->getId()) $items[$id] = 0; $message->delete(); $items[$id] = 1; } return (object) $items; } function restore(int $message_id): int { $this->requireUser(); $msg = (new MSGRepo)->get($message_id); if(!$msg) return 0; else if($msg->getSender()->getId() !== $this->getUser()->getId()) return 0; $msg->undelete(); return 1; } function getConversations(int $offset = 0, int $count = 20, string $filter = "all", int $extended = 0, string $fields = ""): object { $this->requireUser(); $convos = (new MSGRepo)->getCorrespondencies($this->getUser(), -1, $count, $offset); $convosCount = (new MSGRepo)->getCorrespondenciesCount($this->getUser()); $list = []; $users = []; foreach($convos as $convo) { $correspondents = $convo->getCorrespondents(); if($correspondents[0]->getId() === $this->getUser()->getId()) $peer = $correspondents[1]; else $peer = $correspondents[0]; $lastMessage = $convo->getPreviewMessage(); $listConvo = new APIConvo; $listConvo->peer = [ "id" => $peer->getId(), "type" => "user", "local_id" => $peer->getId(), ]; $canWrite = $peer->getSubscriptionStatus($this->getUser()) === 3; $listConvo->can_write = [ "allowed" => $canWrite, ]; $lastMessagePreview = NULL; if(!is_null($lastMessage)) { $listConvo->last_message_id = $lastMessage->getId(); if($lastMessage->getSender()->getId() === $this->getUser()->getId()) $author = $lastMessage->getRecipient()->getId(); else $author = $lastMessage->getSender()->getId(); $lastMessagePreview = new APIMsg; $lastMessagePreview->id = $lastMessage->getId(); $lastMessagePreview->user_id = $author; $lastMessagePreview->from_id = $lastMessage->getSender()->getId(); $lastMessagePreview->date = $lastMessage->getSendTime()->timestamp(); $lastMessagePreview->read_state = 1; $lastMessagePreview->out = (int) ($lastMessage->getSender()->getId() === $this->getUser()->getId()); $lastMessagePreview->body = $lastMessage->getText(false); $lastMessagePreview->text = $lastMessage->getText(false); $lastMessagePreview->emoji = true; if($extended == 1) { $users[] = $author; } } $list[] = [ "conversation" => $listConvo, "last_message" => $lastMessagePreview, ]; } if($extended == 0){ return (object) [ "count" => $convosCount, "items" => $list, ]; } else { $users[] = $this->getUser()->getId(); $users = array_unique($users); return (object) [ "count" => $convosCount, "items" => $list, "profiles" => (!empty($users) ? (new APIUsers)->get(implode(',', $users), $fields, 0, $count+1) : []) ]; } } function getConversationsById(string $peer_ids, int $extended = 0, string $fields = "") { $this->requireUser(); $peers = explode(',', $peer_ids); $output = [ "count" => 0, "items" => [] ]; $userslist = []; foreach($peers as $peer) { if(key($peers) > 100) continue; if(is_null($user_id = $this->resolvePeer((int) $peer))) $this->fail(-151, "Chats are not implemented"); $user = (new USRRepo)->get((int) $peer); $dialogue = new Correspondence($this->getUser(), $user); $iterator = $dialogue->getMessages(Correspondence::CAP_BEHAVIOUR_START_MESSAGE_ID, 0, 1, 0, false); $msg = $iterator[0]->unwrap(); // шоб удобнее было $output['items'][] = [ "peer" => [ "id" => $user->getId(), "type" => "user", "local_id" => $user->getId() ], "last_message_id" => $msg->id, "in_read" => $msg->id, "out_read" => $msg->id, "sort_id" => [ "major_id" => 0, "minor_id" => $msg->id, // КОНЕЧНО ЖЕ ], "last_conversation_message_id" => $user->getId(), "in_read_cmid" => $user->getId(), "out_read_cmid" => $user->getId(), "is_marked_unread" => $iterator[0]->isUnread(), "important" => false, // целестора когда релиз "can_write" => [ "allowed" => ($user->getId() === $this->getUser()->getId() || $user->getPrivacyPermission('messages.write', $this->getUser()) === true) ] ]; $userslist[] = $user->getId(); } if($extended == 1) { $userslist = array_unique($userslist); $output['profiles'] = (!empty($userslist) ? (new APIUsers)->get(implode(',', $userslist), $fields) : []); } $output['count'] = sizeof($output['items']); return (object) $output; } function getHistory(int $offset = 0, int $count = 20, int $user_id = -1, int $peer_id = -1, int $start_message_id = 0, int $rev = 0, int $extended = 0): object { $this->requireUser(); if(is_null($user_id = $this->resolvePeer($user_id, $peer_id))) $this->fail(-151, "Chats are not implemented"); $peer = (new USRRepo)->get($user_id); if(!$peer) $this->fail(1, "ошибка про то что пира нет"); $results = []; $dialogue = new Correspondence($this->getUser(), $peer); $iterator = $dialogue->getMessages(Correspondence::CAP_BEHAVIOUR_START_MESSAGE_ID, $start_message_id, $count, abs($offset), $rev === 1); foreach($iterator as $message) { $msgU = $message->unwrap(); # Why? As of OpenVK 2 Public Preview Two database layer doesn't work correctly and refuses to cache entities. # UPDATE: the issue seems to be caused by debug mode and json_encode (bruh_encode). ~~Dorothy $rMsg = new APIMsg; $rMsg->id = $msgU->id; $rMsg->user_id = $msgU->sender_id === $this->getUser()->getId() ? $msgU->recipient_id : $msgU->sender_id; $rMsg->from_id = $msgU->sender_id; $rMsg->date = $msgU->created; $rMsg->read_state = 1; $rMsg->out = (int) ($msgU->sender_id === $this->getUser()->getId()); $rMsg->body = $message->getText(false); $rMsg->text = $message->getText(false); $rMsg->emoji = true; $results[] = $rMsg; } return (object) [ "count" => sizeof($results), "items" => $results, ]; } function getLongPollHistory(int $ts = -1, int $preview_length = 0, int $events_limit = 1000, int $msgs_limit = 1000): object { $this->requireUser(); $res = [ "history" => [], "messages" => [], "profiles" => [], "new_pts" => 0, ]; $manager = SignalManager::i(); $events = $manager->getHistoryFor($this->getUser()->getId(), $ts === -1 ? NULL : $ts, min($events_limit, $msgs_limit)); foreach($events as $event) { if(!($event instanceof NewMessageEvent)) continue; $message = $this->getById((string) $event->getLongPoolSummary()->message["uuid"], $preview_length, 1)->items[0]; if(!$message) continue; $res["messages"][] = $message; $res["history"][] = $event->getVKAPISummary($this->getUser()->getId()); } $res["messages"] = [ "count" => sizeof($res["messages"]), "items" => $res["messages"], ]; return (object) $res; } function getLongPollServer(int $need_pts = 1, int $lp_version = 3, ?int $group_id = NULL): array { $this->requireUser(); if($group_id > 0) $this->fail(-151, "Not implemented"); $url = "http" . (ovk_is_ssl() ? "s" : "") . "://$_SERVER[HTTP_HOST]/nim" . $this->getUser()->getId(); $key = openssl_random_pseudo_bytes(8); $key = bin2hex($key) . bin2hex($key ^ ( ~CHANDLER_ROOT_CONF["security"]["secret"] | ((string) $this->getUser()->getId()) )); $res = [ "key" => $key, "server" => $url, "ts" => time(), ]; if($need_pts === 1) $res["pts"] = -1; return $res; } }