# tutorial_2.cpp

## C++ Tutorial Step 2: Conversations and Properties

The primary class that governs communication in Skype is the Conversation. In this example we will:

- Take a Skype Name and password as command-line arguments
- Retrieve a list of Conversation objects
- Retrieve the display name (P_DISPLAYNAME) property of each Conversation
- Retrieve multiple properties of the Conversation with the GetProps method

### Code Walkthrough

Firstly, lets see how to get a Conversation object. The most common use case would probably be to find a Conversation by names of people in that conversation. For this, you can use the Skype::GetConversationByParticipants method. There are other methods of retrieving Conversation objects by other criteria but for now, lets focus on this one.

This method takes a string list of contact identities as an argument and finds the first Conversation object that has all these people in it.

Once we have the Conversation object, we will want to access some of its properties. For this we can use GetProp (returns an SEString), or in case of multiple properties - GetProps methods. GetProp and GetProps methods are common to all the main wrapper classes and are inherited from the base class SEObject. In addition, each class also has a strongly typed accessor methods for all its properties in form of Class::GetProp<Propname>.

Using the strongly typed accessor, we would end up with something like this:

    Conversation::Ref conv;
    SEStringList partnerNames;
    partnerNames.append("partnernamehere"); // <- you may want to change this argument

    if (skype->GetConversationByParticipants(partnerNames, conv, false, false))
    {
      SEString displayName;
      conv->GetPropDisplayname(displayName);
      printf("Conversation disaplayname: %s\n", (const char*)displayName);
    }
    else
    {
      printf("No conversation on this account with this participant.\n");
    };

Secondly, lets see how to obtain a list of Conversation objects. The easiest way to do this is with the Skype::GetConversationList method. This method takes the following two arguments:

- A pre-defined conversation list filter
- A list of conversation object references (for the objects that are returned)

The filter is a Conversation::LIST_TYPE enumerator, with following values:

- ALL_CONVERSATIONS - entire conversation list
- INBOX_CONVERSATIONS - only the last 6 months' conversations are stored in inbox
- BOOKMARKED_CONVERSATIONS - is_bookmarked is set
- LIVE_CONVERSATIONS - local_livestatus is anything except NONE

To retrieve a list of conversations currently in Inbox, we use the following:

    Conversation::Refs inbox;
    skype->GetConversationList(inbox, Conversation::INBOX_CONVERSATIONS);

Once we have the list, we can iterate over it to examine each of the retrieved references. Note that the retrieved list is 0-based.

Looping over a conversation list and retrieving Conversation::P_DISPLAYNAME property would end up looking like this:

    Conversation::Ref conv;
    Conversation::Refs inbox;
    skype->GetConversationList(inbox, Conversation::INBOX_CONVERSATIONS);
    for (int i = 0; i < inbox.size(); i++)
    {
      conv = inbox[i];
      SEString displayName;
      conv->GetPropDisplayname(displayName);
      printf("%2d. %s\n", i+1, (const char*)displayName);
    };

Retrieving multiple properties at once is similar. Instead of asking for each property explicitly, GetProps takes a list of property IDs and returns a dictionary of ID-value pairs.

The property ID list is of class SEIntList and the key-value pairs are of class SEIntDict. The usage looks like this:

    skype->GetConversationList(inbox, Conversation::INBOX_CONVERSATIONS);
    printf("Conversations in Inbox : %d\n", inbox.size());

    SEIntList propIds;
    SEIntDict propValues;
    propIds.append(Conversation::P_TYPE);
    propIds.append(Conversation::P_DISPLAYNAME);

    SEString convType;
    SEString displayName;
    for (int i = 0; i < inbox.size(); i++)
    {
      propValues  = inbox[i]->GetProps(propIds);
      convType    = propValues.find(Conversation::P_TYPE);
      displayName = propValues.find(Conversation::P_DISPLAYNAME);
      printf("Type: %s  Name: %s \n", (const char*)convType, (const char*)displayName);
    };

In the example above, you might find the use of propValues.find(propID) for each retrieved property aesthetically unpleasing. If so, can also access the return values directly, as array elements, like this:

    convType = propValues[0];
    displayName = propValues[1];

## Full code of this example

    /****************************************************************************

    Getting Started With SkypeKit. Tutorial Application, Step 2.

    In this example we will:
     1. Take a skypename and password as command-line arguments
     2. Retrieve a list of Conversation objects
     3. Retrieve the display name (P_DISPLAYNAME) property of each Conversation
     4. Retrieve multiple properties of the Conversation with the GetProps method
    **/

    #include "skype-embedded_2.h"
    #include "keypair.h"
    #include "tutorial_common.h"

    using namespace Sid;

    //----------------------------------------------------------------------------
    // Interface section

    class MySkype : public Skype
    {
    public:
      // Note that to reduce clutter in this and all the further tutorials,
      // MyAccount classcomes from tutorial_common.h
      Account* newAccount(int oid) {return new MyAccount(oid, this);}
    };

    //----------------------------------------------------------------------------
    // Main

    MySkype* skype = 0;

    int main(int argc, char * argv[])
    {
      printf("*****************************************************************\n");
      printf(" SkypeKit Tutorial, Step 2. - Conversation list and properties\n");
      printf("*****************************************************************\n");

      if (argc < 3)
      {
        printf("usage: tutorial_2 <skypename> <password>\n");
        return 0;
      };

      SEString myAccountName  = argv[1];
      SEString myAccountPsw   = argv[2];

      printf("creating skype ..\n");
      skype = new MySkype();

      printf("starting Skype and submitting application token..\n");
      getKeyPair ();
      skype->init(keyBuf, inetAddr, portNum, "streamlog.txt");
      skype->start();

      printf("getting account ..\n");
      MyAccount::Ref account;

      if (skype->GetAccount(myAccountName, account))
      {
        printf("Logging in..\n");
        account->LoginWithPassword(myAccountPsw, false, true);

        account->BlockWhileLoggingIn();

        if (account->loggedIn)
        {
          Conversation::Ref conv;

          printf("Example 1: one Conversation (using GetConversationByParticipants)\n");
          SEStringList partnerNames;
          partnerNames.append("partnernamehere"); // <- you may want to change this argument

          // Note that setting the 1st boolean argument true will cause this method
          // to automatically create Conversation object, even if there is actually
          // no such contact as given in partnerNames.
          if (skype->GetConversationByParticipants(partnerNames, conv, true, false))
          {
            SEString displayName;
            conv->GetPropDisplayname(displayName);
            printf("Conversation disaplayname: %s\n", (const char*)displayName);
          }
          else
          {
            printf("No conversation on this account with this participant.\n");
          };

          printf("Press ENTER to continue..\n");
          getchar();

          printf("Example 2: List of Conversations (using GetConversationList)\n");
          Conversation::Refs inbox;
          skype->GetConversationList(inbox, Conversation::INBOX_CONVERSATIONS);
          printf("Conversations in Inbox : %d\n", inbox.size());

          for (uint i = 0; i < inbox.size(); i++)
          {
            conv = inbox[i];
            SEString displayName;
            conv->GetPropDisplayname(displayName);
            printf("%2d. %s\n", i+1, (const char*)displayName);
          };

          printf("Press ENTER to continue..\n");
          getchar();

          printf("Example 3: List of Conversations and multiple properties at once (using GetProps)\n");
          skype->GetConversationList(inbox, Conversation::INBOX_CONVERSATIONS);
          printf("Conversations in Inbox : %d\n", inbox.size());

          SEIntList propIds;
          SEIntDict propValues;
          propIds.append(Conversation::P_TYPE);
          propIds.append(Conversation::P_DISPLAYNAME);

          SEString convType;
          SEString displayName;
          for (uint i = 0; i < inbox.size(); i++)
          {
            // GetProps will return a list with both P_TYPE and P_DISPLAYNAME for the object.
            // Weakness here is that the while values are returned as SEStrings, enum values
            // are not converted to their human-readable equivalents. convType for example
            // will be either "1" or "2", rather than "DIALOG" or "CONFERENCE".
            propValues  = inbox[i]->GetProps(propIds);
            convType    = propValues.find(Conversation::P_TYPE);
            displayName = propValues.find(Conversation::P_DISPLAYNAME);
            printf("Type: %s  Name: %s \n", (const char*)convType, (const char*)displayName);
          };

          printf("Press ENTER to log out..\n");
          getchar();

          printf("Logging out..\n");
          account->Logout(false);
          account->BlockWhileLoggingOut();
        }
      }
      else
      {
          printf("Account does not exist\n");
      };

      printf("Cleaning up.\n");
      skype->stop();
      delete skype;
      printf("Done.\n");
      return 0;
    };

All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

(c) Skype Technologies S.A. Confidential/Proprietary

Last updated: Fri Mar 16 2012