Download MetaTrader 5

Using Skype to Send Messages from an Expert Advisor

27 September 2007, 08:58
Alexey Koshevoy
10
2 795

Introduction

Skype is a telecommunications program that, along with normal chats, allows people to phone via Internet. One of the most important advantages of Skype as compared to other programs of the kind is a gateway to real mobile network operators. Respectively, one can call a real mobile phone, send SMSes, and so on. There is also a Skype version for mobile phones. One can save money on SMSes since sending regular messages within the program is absolutely free. Basically, a mobile phone must work under an operating system. Well, it is possible now to be fully mobile if necessary. And it is this opportunity that many people use nowadays.


Who and Why May Need This?

Trader cannot always sit in front of trading terminal and watch how the trading is performed, neither he/she must do this. However, it would be great to be able to get signals sometimes that would inform the trader about Expert Advisor's actions or about the market state at certain moments. Why not to get this information in his or her mobile phone?


What Kind of Information Would It Be Useful to Get?

Information that can be got using messages in a mobile phone can be divided into two groups:

  1. current data that do not influence anything and are practically the same as those in the log file;
  2. useful info that will be helpful for the trader exactly when it incomes.

Let's consider examples of current data:

  • Order states. When an order was opened, in what direction, what stops were assigned for it, etc., when it was closed, for what reason, at a loss or at a profit, etc.
  • Various market states. For example, when an indicator meets a certain level or a trend changes its direction.

Useful information:

  • Error report. All programmers are people, and sometimes some unpleasant situations occur when the Expert Advisor works improperly. It would be not bad to know about the conditions, in which errors occur and whether that results in a fatal halting. This will work, of course, if the Expert Advisor's logic allows one to detect errors.
  • Expert Advisor's operating state. For instance, the EA is set up in such a way as to send a message about its operating state every hour while you are on a business trip. And it happens so that the expected message has not income at the hour stated. Everything could happen: from disconnection from the Internet to power cuts. If the terminal works at your home, it would make sense to ask a colleague or the spouse to find out about the reason and restore settings, instead of waiting during a week in the dark.

This division is, of course, of a relative nature, and the list of possible events extends further than this article. Every trader will decide for him or herself what content the message should have. The main thing is to realize that this function is very helpful.


How Does This Work in Skype?

  • SMSes. The service is, of course, to be paid for. Everything looks like usually: dial the subscriber's number, type the message, and press "Send".
  • Regular messages. This is absolutely free. Just select a user, type a message and press "Send".


How to Do This from an Expert Advisor?

I found two ways how to do this, and both need using of DLLs:

  1. We should prepare a macrofile in advance, i.e. at launching of that file control over keyboard and mouse will be intercepted. Thus, using the sequence of actions, we should activate Skype, find the SMS- sending item in the menu, then dial the subscriber's number in the window that appears, and paste from clipboard the text message initially typed in the Expert Advisor. You can train and polish up the operations beforehand. Thus, we have prepared a file that is an associated document and can be launched as a normal application. By the way, there are very many applications that record and replay macrofiles, so we won't consider specific programs in this article.

    Then we have to develop a DLL that will operate as follows. Its first operation will be placing the text from the Expert Advisor into clipboard. The second operation is launching the predefined macrofile. If everything is set up well and all windows and buttons appear in their proper places, there should not occur any problems, the message will be sent.

    However, this way is a bit frightening. Intuition suggests me that, if brains start to invent something like that, one has to either find a more pleasing solution or renounce the idea as a whole. A new idea flashed into my mind: Can Skype have an API? Well, I found API and ActiveX interface on their website. Great! Let's consider another way to work with Skype from an Expert Advisor.

  2. It is mostly the same. The subscriber's number and the text to be sent will be passed from the EA to the DLL, which sends the message through the Skype COM object.


How to Realize the Second Way

Let us start with DLL. The main part of all works will be preparing DLL for interaction with the Expert Advisor. First, we write a library that would work when called from several Expert Advisors. Unfortunately, it will be insufficient just to write a function and call it. We are using ActiveX, so it is desirable to create a special separated thread for it and do all work in it. The standard paralleling tool for Mutex functions will not help. There will be crashes that cannot be detected. So we will realize the sequence of calls through the custom messaging system.


DLL Source Code

#include "stdafx.h"
 
#pragma once
// Allow use of features specific to Windows XP or later. 
#ifndef WINVER
// Change this to the appropriate value to target other versions of Windows.
#define WINVER 0x0501      
#endif
// Exclude rarely-used stuff from Windows headers 
#define WIN32_LEAN_AND_MEAN
 
// Include Skype4COM.dll, preliminarily downloaded 
// from the Skype developers website – http://developers.skype.com/
#import "Skype4COM.dll" rename("CreateEvent","CreatePluginEvent"), 
                        rename("SendMessage","SendChatMessage")
 
 
#define MT4_EXPFUNC __declspec(dllexport)
 
// Declare message codes for our functions.
#define WM_PROC_SENDSKYPESMS WM_USER + 01
#define WM_PROC_SENDSKYPEMESSAGE WM_USER + 02
 
// Variables for the thread to be used for 
// sending messages
HANDLE hUserThread;
DWORD ThreadId;
 
// Structures to store parameters of functions
// SendSkypeSMS
struct fcpSendSkypeSMS
  {
    int ExitCode;
    char * UserNum;
    char * Message;
  };
 
// SendSkypeMessage
struct fcpSendSkypeMessage
  {
    int ExitCode;
    char * UserName;
    char * Message;
  };
//+------------------------------------------------------------------+
//| Thread function                                                  |
//+------------------------------------------------------------------+
DWORD WINAPI ThreadProc(LPVOID lpParameter)
  {
    MSG msg;
    HANDLE hEvent;
  
    while(true)
      {
        if(PostThreadMessage(GetCurrentThreadId(), WM_USER, 0, 0))
            break;
      };
    // Initialize COM
    CoInitialize(NULL);
    while(GetMessage(&msg, 0, 0, 0))
      {
        if(msg.message == WM_QUIT)
          {
            break;
          }
        // Message processor WM_PROC_SENDSKYPESMS
        else 
            if(msg.message == WM_PROC_SENDSKYPESMS)
              {
                fcpSendSkypeSMS* fcp = (fcpSendSkypeSMS*)msg.wParam;
                hEvent = (HANDLE)msg.lParam;
                try
                  {
                    // Initialize Skype 
                    SKYPE4COMLib::ISkypePtr pSkype(__uuidof(SKYPE4COMLib::Skype));
                    // Connect to Skype. 6 is the protocol version
                    HRESULT hr=pSkype->Attach(6,VARIANT_TRUE);
                    // If everything is ok, start sending the message
                    if(!FAILED(hr))
                      {    
                        try
                          {
                            fcp->ExitCode = 1;
                            // Try to send an SMS
                            pSkype->SendSms(fcp->UserNum,fcp->Message,"");
                          }
                        catch(...)
                          {
                            fcp->ExitCode=-1;
                          }
                      }
                    // Deinitialize Skype
                    pSkype = NULL;
                  }
                catch(...)
                  {
                    //Error is processed here
                  }
                // Set the event
                SetEvent(hEvent);
              }
            // Message processor WM_PROC_SENDSKYPEMESSAGE
            else 
                if(msg.message == WM_PROC_SENDSKYPEMESSAGE)
                  {
                    fcpSendSkypeMessage* fcp = 
                                   (fcpSendSkypeMessage*)msg.wParam;
                    hEvent = (HANDLE)msg.lParam;
        
                    try
                      {
                        // Initialize Skype 
                        SKYPE4COMLib::ISkypePtr pSkype(__uuidof
                                              (SKYPE4COMLib::Skype));
                        // Connect to Skype. 6 is the protocol version
                        HRESULT hr=pSkype->Attach(6,VARIANT_TRUE);
                        // If everything is ok, start sending the message
                        if(!FAILED(hr))
                          {
                            try
                              {
                                fcp->ExitCode = 1;
                                // Try to send the message
                                pSkype->SendChatMessage(fcp->UserName,
                                                        fcp->Message);
                              }
                            catch(...)
                              {
                                fcp->ExitCode=-1;
                                MessageBeep(0);
                              }
                          }
                        // Deinitialize Skype
                        pSkype = NULL;
                      }
                    catch(...)
                      {
                        //Error is processed here
                      }
  
                    // Set the event
                    SetEvent(hEvent);
                  }
              };
            // Deinitialize COM
            CoUninitialize();
            return 0;
          }
 
//DLL Initialization
//+------------------------------------------------------------------+
//| DLL entry                                                        |
//+------------------------------------------------------------------+
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call,
                      LPVOID lpReserved)
  {
    if(ul_reason_for_call == DLL_PROCESS_ATTACH)
      {
        // Create a thread and attach the processor procedure address to it
        hUserThread = CreateThread(NULL, NULL, ThreadProc, NULL, 0, &ThreadId);
        if(!hUserThread)
          {
            // Error processing if the thread is not created
          };
      } 
    else 
        if(ul_reason_for_call == DLL_PROCESS_DETACH)
          {
            // Delete the thread when exiting the library
            CloseHandle(hUserThread);
          }
    return(TRUE);
  }
 
MT4_EXPFUNC bool __stdcall SendSkypeSMS(int &ExCode,char* sUserNum, 
                                        char* sMessage)
  {
    //Declare the structure of function parameters
    fcpSendSkypeSMS* fcp;
    //Declare an event
    HANDLE hEvent;
    //The result of function operation by default is false
    bool Result = false;
 
    // Allocate a password for the structure and initialize it
    fcp = new fcpSendSkypeSMS();
    memset(fcp, 0, sizeof(fcpSendSkypeSMS));
 
    // Fill out the structure
    //By default, the code of the function working end is an error.
    fcp->ExitCode = -1;
    fcp->UserNum = sUserNum;
    fcp->Message = sMessage;
 
    // Create an event
    hEvent = CreateEvent(NULL,FALSE,FALSE, NULL);
    // Call event WM_PROC_SENDSKYPESMS, pass  the data structure address 
    // to processing procedure 
    PostThreadMessage(ThreadId, WM_PROC_SENDSKYPESMS, (WPARAM)fcp,
                      (LPARAM)hEvent);
    if(WAIT_OBJECT_0 == WaitForSingleObject(hEvent,INFINITE))
      {
        
        Result = true;
      } 
    else
      {
        // If there was an error at message processing, the function will 
        // return false
        return(Result);
      };
    // Assign the function processing code to the variable
    ExCode = fcp->ExitCode;
    if(ExCode == -1) 
        Result = false;
    // Free memory and variables and exit
    delete fcp;
    CloseHandle(hEvent);
    return(Result);
  }
 
MT4_EXPFUNC bool __stdcall SendSkypeMessage(int &ExCode,char* sUserName, 
                                            char* sMessage)
  {
    //Declare the structure of function parameters
 fcpSendSkypeMessage* fcp;
    //Declare an event
    HANDLE hEvent;
    //The result of function operation by default is false
    bool Result = false;
 
    // Allocate memory for the structure and initialize it
    fcp = new fcpSendSkypeMessage();
    memset(fcp, 0, sizeof(fcpSendSkypeMessage));
 
    // Fill out the structure
    //By default, the code of the function working end is an error.
    fcp->ExitCode = -1;
    fcp->UserName = sUserName;
    fcp->Message = sMessage;
 
    // Create an event
    hEvent = CreateEvent(NULL, FALSE,FALSE, NULL);
    // Call the event WM_PROC_SENDSKYPESMS, pass the data structure address 
    // to processing procedure
    PostThreadMessage(ThreadId, WM_PROC_SENDSKYPEMESSAGE, (WPARAM)fcp,
                      (LPARAM)hEvent);
    if(WAIT_OBJECT_0 == WaitForSingleObject(hEvent, INFINITE))
      {
        Result = true;
      } 
    else
      {
        // If there was an error at message processing, the function will 
        // return false
        return(Result);
      };
    // Assign the function processing code to the variable
    ExCode = fcp->ExitCode;
    if(ExCode == -1) 
        Result = false;
    // Free memory and variables and exit
    delete fcp;
    CloseHandle(hEvent);
    return(Result);
  }


File DEF

LIBRARY SkypeLib
 
EXPORTS SendSkypeSMS
        SendSkypeMessage


Expert Advisor to Be Tested

//+------------------------------------------------------------------+
//|                                              SkypeTestExpert.mq4 |
//|                               Copyright © 2007, Alexey Koshevoy. |
//+------------------------------------------------------------------+
// Import functions
#import "SkypeLib.dll"
   bool SendSkypeSMS(int &ExCode[], string Num,string Message);
   bool SendSkypeMessage(int &ExCode[], string User, string Message);
#import
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int init()
  {
   int ExCode[1];
   Alert("Send message...");
   Alert(SendSkypeMessage(ExCode, "skype.account.name", "Skype message test"));
   if(ExCode[0] == -1)
       Alert("Error sending the message");
   else 
       Alert("Message sent");
   Alert("Send SMS...");
   Alert(SendSkypeSMS(ExCode, "+1234567890", "Skype sms test"));
   if(ExCode[0] == -1)
       Alert("Error sending the SMS");
   else
       Alert("SMS sent");
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   return(0);
  }
//+------------------------------------------------------------------+

The Ea is very simple, its main aim is to send an SMS and a regular message through the DLL we have coded. It acts within the initialization function, so it can also be tested at weekends.


Skype Installation

The application can be downloaded at http://www.skype.com/. It is recommended to install the latest version of the program, since the preceding versions don't support COM interface, they only have an API. However, the API doesn't support sending SMSes.

Well, Skype has already been installed. Now we have to download the COM library. It can be found at https://developer.skype.com/, in Downloads. Check the amount on the account to be used for sending SMSes. If there is not enough money, you can add some through Internet. It will not allow to send SMSes without money on the account, but regular messages can be sent without any problems.

For the terminal to access to Skype API, it must be registered. You can check whether it is permitted to work with the API using the menu of Tools->Options->Privacy->Manage other programs access to Skype. It must look approximately like this:

The terminal will be registered at the first attempt to use the library. It cannot be done manually. So, when the library is being installed for the first time, it is necessary to wait until a message is sent in order to have confirmed the permission to use Skype API. Skype will show the following dialog box:

After confirmation, the system will start working in the automated mode.


Installation of SkypeLib

Для In order to install the library named SkypeLib.dll, it is necessary to copy it to the experts/libraries folder in the terminal directory. The library named Skype4COM.dll must also be copied to this folder. Now we have to set up the terminal to be able to work with the DLL. For this, check field "Allow DLL imports" in the "Safety" section when attaching an EA as shown below:

Now we can use the library.


Some Important Details

Having some experience in testing and implementation, I noticed some "subtleties". For example, you have to consider that, if you have enough money on your account and send an SMS to a non-existing number, no error will be reported, the function will work successfully, whereas the message status will be set for “sending...”. This is why it is important to set up function inputs very clearly. It is also very important the you use Skype version 3. 0 (or later versions).

It happens (however, rather rarely) that COM object is not initialized and no messages will be sent. This can only be helped with reinstallation of Skype. The external interface is relatively new, not without bugs, so such unpleasant things may happen. It has happened twice within my knowledge. Let's hope that the later versions will work stabler.

It must also be noted that some additional libraries may be needed for SkypeLib. dll to operate. The problem is especially acute after the first service pack for Visual Studio 2005 has been released. The best way to solve this problem is to create a setup file. All necessary libraries will be included in it automatically. File Skype4COM. dll can be included in it, too.


Files Attached to the Article

  • SkypeLib.dll - The library was compiled in Visual C++ 6.0. It does not need any additional files but Skype4COM.dll.
  • SkypeLib.zip - The library source code.
  • SkypeExample.mq4 - An Expert Advisor for the library to be tested.


Highs and Lows

The following disadvantages can be observed when using Skype SMSes:

  • SMSes cost some money
  • One cannot send a message to oneself, it is necessary to have another Skype account to get messages.
  • Your phone must support the mobile version of Skype. If a computer is used to receive messages, this disadvantage stands no longer.

This method has the following advantages:

  • Signals in the real-time mode
  • Function that cannot be replaced by anything at the moment. This is not even an advantage, it's just a fact.


Conclusions

We have learned how to send SMSes and regular messages via Skype. In such a way, we have got an interface, which is perhaps not the most convenient, but surely indispensable, to inform us about current events in the terminal. What comes next? Well, for example, Skype allows both sending and RECEIVING messages...

Attached files |
SkypeExample.mq4 (0.71 KB)
SkypeLib.dll (56 KB)
SkypeLib.zip (2.36 KB)
Last comments | Go to discussion (10)
Jinsong Zhang
Jinsong Zhang | 7 Jun 2009 at 03:40
That's well.
Do Hung
Do Hung | 22 Apr 2012 at 01:26

Sorry to review old topic.

It works well for me with SMS and message

I would like to make a CALL from Skype Nick to Skype Nick or from Skype Nick to Mobile.

Could you please help me the code?

Thank you very much.

Do Hung
Do Hung | 18 Oct 2014 at 08:55

Hello,

 

I try this SendSkypeMessage(ExCode, "maxpro.vn", "Test message");

It sent only a letter "T" to user "m". It seems that EA takes only the first letter of a string.

Anyone knows about this problem? Thanks! 

JF_Mennedy
JF_Mennedy | 26 Feb 2016 at 13:17
These Code modifications will transfer the whole string to the dll:
bool SendSkypeMessage(int &ExCode[], uchar &user_name[] ,uchar &message[]); void subSendSkype() {    int ExCode[1];    string DBusername = "username";    string DBmessage = "testmessage";    uchar user_name[];    uchar message[];    StringToCharArray(DBusername,user_name);    StringToCharArray(DBmessage,message);          Alert("Sende Skype Message...");    Alert(SendSkypeMessage(ExCode,user_name,message));    if (ExCode[0]==-1)       Alert("Skypemessage nicht erfolgreich");    else       Alert("Skypemessage erfolgreich");    //return(0); }

Georgiy Liashchenko
Georgiy Liashchenko | 7 Mar 2016 at 00:38
Works great! With the latest skype version you dont need to dowload any extra files, just ea and dll from the author. But you need to transform string to char array 100%. But what is disappointing is that it only sends text messages and fails for sms :(( maybe any thoughts?
Step on New Rails: Custom Indicators in MQL5 Step on New Rails: Custom Indicators in MQL5

I will not list all of the new possibilities and features of the new terminal and language. They are numerous, and some novelties are worth the discussion in a separate article. Also there is no code here, written with object-oriented programming, it is a too serous topic to be simply mentioned in a context as additional advantages for developers. In this article we will consider the indicators, their structure, drawing, types and their programming details, as compared to MQL4. I hope that this article will be useful both for beginners and experienced developers, maybe some of them will find something new.

Here Comes the New MetaTrader 5 and MQL5 Here Comes the New MetaTrader 5 and MQL5

This is just a brief review of MetaTrader 5. I can't describe all the system's new features for such a short time period - the testing started on 2009.09.09. This is a symbolical date, and I am sure it will be a lucky number. A few days have passed since I got the beta version of the MetaTrader 5 terminal and MQL5. I haven't managed to try all its features, but I am already impressed.

Using text files for storing input parameters of Expert Advisors, indicators and scripts Using text files for storing input parameters of Expert Advisors, indicators and scripts

The article describes the application of text files for storing dynamic objects, arrays and other variables used as properties of Expert Advisors, indicators and scripts. The files serve as a convenient addition to the functionality of standard tools offered by MQL languages.

How to create an indicator of non-standard charts for MetaTrader Market How to create an indicator of non-standard charts for MetaTrader Market

Through offline charts, programming in MQL4, and reasonable willingness, you can get a variety of chart types: "Point & Figure", "Renko", "Kagi", "Range bars", equivolume charts, etc. In this article, we will show how this can be achieved without using DLL, and therefore such "two-for-one" indicators can be published and purchased from the Market.