Vreen is a simple and convenient library for working with vk.api

    I present to you a new Qt library for working with vk api, which can be useful to you when creating any desktop and mobile applications that interact with vk. The project was born from the vkontakte plugin for qutIM and grew into a separate independent library, which everyone can now use.

    Short review

    Vreen is a wrapper over vk.com api, written in C ++ 11 / Qt, designed to quickly and easily create mobile and desktop applications, as well as embed interaction with vk.com api in existing applications. The library supports several authorization methods and allows you to add your own if necessary. Also in vreen there is a full binding to qml, which allows you to create applications without writing a single line in C ++. To reduce the number of required dependencies, all authorization methods are moved to separate static libraries.

    Key features:

    1. Support for all types of dialogs including group chats.
    2. Support for viewing news feeds, walls.
    3. Work with comments, including additions, likes and reposts.
    4. Support for working with attachments.
    5. Support for roster including tracking the status of interlocutors.
    6. Support for audio recordings.
    7. The ability to directly work with the API from qml in the style familiar to many XHTTPRequest.
    8. Extensibility.
    9. Free LGPL license, allowing you to use the library with proprietary applications.

    The basics:

    Base classes for working with the API:
    • Connection - a class based on QNetworkAccessManager that performs authorization and directly implements API requests.
    • Reply - the class monitors the execution of the request.
    • Longpoll - a class that polls the server for events.
    • Roster is a friend list management class.
    • Client is a base class that stitches everything together.

    Making API requests:
    Simple request:
        QVariantMap args;
        args.insert("uids", join(ids));
        args.insert("fields", fields.join(","));
        auto reply = d->client->request("users.get", args);
        reply->connect(reply, SIGNAL(resultReady(const QVariant&)),
                       this, SLOT(_q_friends_received(const QVariant&)));

    The resultReady signal is thrown when the request is completed and contains the response from the server converted to QVariant json into the response or nothing in case of an error, the error code in this case is contained in reply-> error ()
    In addition, you can hide the result processing from the recipient by adding a reply function is a result handler, in this case the result can be obtained by calling the reply-> result () method, the result will be returned as a QVariant, so it will need to be further converted using QVariant :: fromValue.
         QVariantMap args;
        //TODO add chat messages support and contact check
        args.insert("uid", message.toId());
        args.insert("message", message.body());
        args.insert("title", message.subject());
    	return request ("messages.send", args, [](const QVariant &response) -> QVariant { return response.toInt(); });

    In order to clearly indicate the type of the returned value, you can apply the following template magic:
         typedef ReplyBase SendMessageReply;
         QVariantMap args;
        //TODO add chat messages support and contact check
        args.insert("uid", message.toId());
        args.insert("message", message.body());
        args.insert("title", message.subject());
    	return request ("messages.send", args, [](const QVariant &response) -> QVariant { return response.toInt(); });

    As a result, in the SendMessageReply :: result () slot, it will return int instead of QVariant.
    	auto reply = static_cast(sender());
    	int mid = reply->result();

    In general, all interaction with the API is simple and transparent.

    Receiving and assembly

    Vreen uses submodules and therefore the best way to get the source is.
    $ git clone git://github.com/gorthauer/vreen.git
    $ cd vreen
    $ git submodule update --init

    To build, you need cmake 2.8, Qt 4.7.4, and any compiler with basic support for C ++ 11 (gcc 4.4+, clang 3.0+, msvc2010 +).
    The assembly itself is quite trivial:
    $ mkdir build
    $ cd build
    $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr
    $ make
    $ make install (sudo)

    If you have questions regarding the build of a release or release version, it is best to simply refer to the cmake documentation. As an experimental option, assembly using qbs is supported. It is possible to build a library using qmake ', but this method is not officially supported.

    Use in a C ++ project


    To connect to other projects in Vreen, pkg-config is used, therefore, to connect vreen with the standard authorization method through a browser, just add lines to the pro file.
    CONFIG += link_pkgconfig
    PKGCONFIG += vreen \

    For systems that do not support pkgconfig, you can either manually add LIBS and INCLUDEPATH or write the find script for cmake or qbs.
    Those interested can help me write a prf file for Qt.


    Let's take as an example a small console application that will pull out all the phone numbers from the friends list.

    To get started, simply initialize the client, indicating the connection method, the application identifier, and also ask him to create a window with permission for access from the application to the api.
        auto auth = new Vreen::OAuthConnection(3220807, this);  //в качестве clientId используйте собственный 
        auth->setConnectionOption(Vreen::Connection::ShowAuthDialog, true); //заставляет клиент самостоятельно создавать окошко авторизации.
        auth->setConnectionOption(Vreen::Connection::KeepAuthData, true); //заставляет хранить токен между сессиями
        connect(this, SIGNAL(onlineStateChanged(bool)), SLOT(onOnlineChanged(bool))); 
        connect(roster(), SIGNAL(syncFinished(bool)), SLOT(onSynced(bool)));

    After the client successfully connects to the api, the onOnlineChanged slot will be called in which we will request a list of friends from the roster. When prompted, you can select the fields that you want to receive. There are several macros with the most common field options VK_COMMON_FIELDS, VK_EXTENDED_FIELDS and VK_ALL_FIELDS for all known fields.
    A description of the fields and obtained properties can be read here u.
    In this case, we are interested in only three fields and there is no need to strain the server with heavier requests.
            roster()->sync(QStringList() << QLatin1String("first_name")
                           << QLatin1String("last_name")
                           << QLatin1String("contacts")); 

    After successfully completing roster synchronization, we simply display the result:
            qDebug() << tr("-- %1 contacts recieved").arg(roster()->buddies().count());
            foreach (auto buddy, roster()->buddies()) {
                QString homeNumber = buddy->property("_q_home_phone").toString();
                QString mobileNumber = buddy->property("_q_mobile_phone").toString();
                qDebug() << tr("name: %1, home: %2, mobile: %3").arg(buddy->name())
                            .arg(homeNumber.isEmpty() ? tr("unknown") : homeNumber)
                            .arg(mobileNumber.isEmpty() ? tr("unknown") : mobileNumber);

    All properties that are not yet implemented properly for contacts will have the prefix _q_, while the rest can be obtained through getters or through the names specified in Q_PROPERTY.

    As a second example, try using the qml api and get a list of friends.
    Import Vreen support into qml:
    import com.vk.api 1.0

    And create a client:
        Client {
            id: client
            connection: conn //используем в качестве подключения и авторизации известный по C++ примеру метод
        OAuthConnection {
            id: conn
            Component.onCompleted: { //Не забудем установить для него те же самые свойства, что и в случае с photoview'ером
                setConnectionOption(Connection.ShowAuthDialog, true); 
                setConnectionOption(Connection.KeepAuthData, true);
            clientId: 3220807
            displayType: OAuthConnection.Popup //из всех окошек авторизации это оказалось наиболее удобным

    We will connect simply through client.connectToHost, in the confirmation window that appears, you will be able to enter your login and password, so you can not create separate fields for input, but restrict yourself to an extremely concise prompt.

    To display a list of dialogs, you can use the ready-made model from com.vk.api 1.0:
        DialogsModel {
            id: dialogsModel
            client: client

    To get a list of recent dialogs, simply after connecting, request a list:
        Connections {
            target: client
            onOnlineChanged: {
                if (client.online) {
                    dialogsModel.getDialogs(0, //смещение относительно последнего элемента  
                                    15, //число элементов
                                    160 //максимальная длина сообщения

    The model properties available for the delegate can be seen in the code for its implementation:
        roles[SubjectRole] = "subject"; 
        roles[BodyRole] = "body";
        roles[FromRole] = "from";
        roles[ToRole] = "to";
        roles[ReadStateRole] = "unread"; 
        roles[DirectionRole] = "incoming";  
        roles[DateRole] = "date";
        roles[IdRole] = "mid";
        roles[AttachmentRole] = "attachments";
        roles[ChatIdRole] = "chatId";

    Using these fields, you can get a completely neat-looking list of dialogs:

    Similarly, create a photo album:

    And I want to note that in the case of creating a photo album, we work through qml directly with vk.api
        function getAll(ownerId, count, offset) {
            if (!offset)
                offset = 0;
            if (!count)
                count = 200;
            var args = {
                "owner_id"  : ownerId,
                "offset"    : offset,
                "count"     : count,
                "extended"  : 0
            var reply = client.request("photos.getAll", args)
            reply.resultReady.connect(function(response) {
                var count = response.shift()
                for (var index in response) {
                    var photo = response[index]

    It turns out very briefly and concisely.


    The current version of vreen is 0.9.5, that is, in fact, this is almost a release, which means that for the most part the API will not change and binary compatibility between versions will be supported, which means that you can safely join the use and testing in real conditions.
    At the moment, support for the API is still very incomplete, but the writing of wrappers over it is as simple as possible, so that I will be glad to all the patches with the implementation of various features.
    For other questions I’m ready to answer in PM or in jabber, which can be found in the profile.
    Fork me with github .

    Also popular now: