# tutorial_9.cpp

## C++ Tutorial Step 9: Detecting Incoming Contact Authorization Requests

In Skype, when other users add you as a contact, you receive an authorization request, which you can accept or deny. In this example, we will write a program that listens for "add contact" requests.

The program will take two arguments:

- your skypename
- your password

To run the compiled program:

    $ cd examples/cpp/tutorials/step9
    $ ./tutorial_9 skypename password

### Code Walkthrough

Skype keeps all contacts with pending authorization requests in a hardwired contact list. The easiest way to catch incoming requests is to detect changes in that list. To do so, we will override the OnChange method of the ContactGroup class and filter out events with P_TYPE property equal to CONTACTS_WAITING_MY_AUTHORIZATION.

First, we make our own class for the contact list object and retrieve the hardwired group into it, like this:

    class MyContactGroup : public ContactGroup
    {
    public:
      typedef DRef<MyContactGroup, ContactGroup> Ref;
      typedef DRefs<MyContactGroup, ContactGroup> Refs;
      MyContactGroup(unsigned int oid, SERootObject* root) : ContactGroup(oid, root) {};
      void OnChange(const ContactRef& contact);
    };

    void MyContactGroup::OnChange(const ContactRef& contact)
    {
      ContactGroup::TYPE Type;
      GetPropType(Type);
      if (Type == ContactGroup::CONTACTS_WAITING_MY_AUTHORIZATION)
      {
        SEString AuthRequestText;
        contact->GetPropReceivedAuthrequest(AuthRequestText);

        if (!AuthRequestText.isEmpty())
        {
          SEString ContactSkypeName;
          contact->GetPropSkypename(ContactSkypeName);
          printf("Auth. request from: %s - %s\n",
            (const char*)ContactSkypeName,
            (const char*)AuthRequestText);
          if (contact->SetBuddyStatus(Contact::AUTHORIZED_BY_ME))
          {
            printf("%s is now authorized\n", (const char*)ContactSkypeName);
          }
          else
          {
            printf("Authorization failed.\n");
          };
        };
      };
    };

In case you want to automatically decline instead of accepting the incoming request you can use Contact::BLOCKED_BY_ME instead of Contact::AUTHORIZED_BY_ME..

In our main body, after successful login:

    MyContactGroup::Ref waitingList;
    skype->GetHardwiredContactGroup(
      ContactGroup::CONTACTS_WAITING_MY_AUTHORIZATION ,
      waitingList);
    waitingList.fetch();

After this, we just wait for a key press. To test the program, log into Skype using another skypename and "Add Contact" with the skypename you used on the command line. Make sure you have not previously authorized this contact. (If you had, use a standard Skype client to remove the contact from the contact list.)

## Full code of this example

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

    Getting Started With SkypeKit. Tutorial Application, Step 9.

    This program will take two command-linearguments:
     1. skypename
     2. password

     It will wait for incoming contact authorization request from remote party
     and display a notification message on screen.

    **/

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

    using namespace Sid;

    SEString myAccountName;
    SEString myAccountPsw;

    class MyContactGroup : public ContactGroup
    {
    public:
      typedef DRef<MyContactGroup, ContactGroup> Ref;
      typedef DRefs<MyContactGroup, ContactGroup> Refs;
      MyContactGroup(unsigned int oid, SERootObject* root) : ContactGroup(oid, root) {};
      void OnChange(const ContactRef& contact);
    };

    void MyContactGroup::OnChange(const ContactRef& contact)
    {
      // This method will fire for all contact groups. As we are only interersted in
      // one particular group - CONTACTS_WAITING_MY_AUTHORIZATION we will need to check
      // the P_TYPE property.
      ContactGroup::TYPE Type;
      GetPropType(Type);
      if (Type == ContactGroup::CONTACTS_WAITING_MY_AUTHORIZATION)
      {
        SEString AuthRequestText;
        contact->GetPropReceivedAuthrequest(AuthRequestText);

        if (!AuthRequestText.isEmpty())
        {
          SEString ContactSkypeName;
          contact->GetPropSkypename(ContactSkypeName);
          printf("Auth. request from: %s - %s\n", (const char*)ContactSkypeName, (const char*)AuthRequestText);
          // Possible values: NONE, AUTHORIZED_BY_ME, BLOCKED_BY_ME
          if (contact->SetBuddyStatus(Contact::AUTHORIZED_BY_ME))
          {
            printf("%s is now authorized\n", (const char*)ContactSkypeName);
          }
          else
          {
            printf("Authorization failed.\n");
          };
        };
      };
    };

    class MySkype : public Skype
    {
    public:
      MySkype() : Skype() {};
      Account*      newAccount(int oid) { return new MyAccount(oid, this); }
      ContactGroup* newContactGroup(int oid) { return new MyContactGroup(oid, this); }
    };

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

    MySkype* skype = 0;

    int main(int argc, char * argv[])
    {
      printf("*****************************************************************\n");
      printf(" Getting Started With SkypeKit. Tutorial, Step 9.\n");
      printf("*****************************************************************\n");

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

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

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

      // Starting the skype thread and submitting the Application Token.
      getKeyPair ();
      skype->init(keyBuf, inetAddr, portNum, "streamlog.txt");
      skype->start();

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

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

        // Here we will get ourselves a MyContactGroup object, so that we will get
        // OnChange events when an incoming auth. request occurs.
        MyContactGroup::Ref waitingList;
        skype->GetHardwiredContactGroup(ContactGroup::CONTACTS_WAITING_MY_AUTHORIZATION , waitingList);
        waitingList.fetch();

        // The rest of the interesting stuff will take place in MyContactGroup::OnChange
        printf("Waiting for incoming auth. requests..\n");
        printf("Press ENTER to quit.\n");
        getchar();

        printf("Logging out..\n");
        account->Logout(false);

        account->BlockWhileLoggingOut();
        printf("Logout complete.\n");
      }
      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