AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

A working Skype API client

 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Buddy



Joined: 09 Aug 2007
Posts: 11

PostPosted: Tue Oct 14, 2008 5:40 pm    Post subject: A working Skype API client Reply with quote

This is a working Skype API client, similar to the C++ example provided on the Skype ApiDoc page. Thought i share, maybe some people are interested.

Code:


;---------------------------------------------------------------------------
; Define constants
;---------------------------------------------------------------------------
ApplWin := "Skype API"
SKYPECONTROLAPI_ATTACH_SUCCESS               = 0
SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION = 1
SKYPECONTROLAPI_ATTACH_REFUSED               = 2
SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE         = 3
SKYPECONTROLAPI_ATTACH_API_AVAILABLE         = 0x8001
WM_COPYDATA = 0x4a
WM_KEYDOWN  = 0x100
stackIndex = 0


;---------------------------------------------------------------------------
; Define GUI
;---------------------------------------------------------------------------
Gui +Resize +LabelGui +MinSize
Gui, Font, S8 CDefault, Verdana
Gui, Add, Edit, x0 y0 w320 h222 cBlue vSkypeText hwndhSkypeText Left Multi -WantReturn -Wrap
Gui, Add, StatusBar

;---------------------------------------------------------------------------
; Register Skype messages
;---------------------------------------------------------------------------
SkypeControlAPIDiscover := DllCall( "RegisterWindowMessage", Str,"SkypeControlAPIDiscover" )
SkypeControlAPIAttach := DllCall( "RegisterWindowMessage", Str,"SkypeControlAPIAttach" )

;---------------------------------------------------------------------------
; Show GUI
;---------------------------------------------------------------------------
Gui, Show, x300 y300 h245 w320, %ApplWin%

    ;---------------------------------------------------------------------------
    ; Obtain id of (this) client window
    ;---------------------------------------------------------------------------
    WinGet, hGui, ID, %ApplWin%

    ;---------------------------------------------------------------------------
    ; Register functions for incoming messages
    ;---------------------------------------------------------------------------
    OnMessage(SkypeControlAPIAttach, "SkypeAttach")
    OnMessage(WM_COPYDATA, "SkypeReceive")
    OnMessage(WM_KEYDOWN, "KeyDown")


    SendMessage, SkypeControlAPIDiscover, hGui,,, ahk_id 0xFFFF 
Return


;---------------------------------------------------------------------------
; Writes text to the Skype API by sending WM_COPYDATA message
;---------------------------------------------------------------------------
writeApi(textToWrite) {

    global

    ;---------------------------------------------------------------------------
    ; Escape if Skype API is not available
    ;---------------------------------------------------------------------------
    If !hSKYPE_API
        Return

    ;---------------------------------------------------------------------------
    ; Fill the CopyDataStruct structure to be sent by WM_COPYDATA
    ;---------------------------------------------------------------------------
    DetectHiddenWindows On
    SetTitleMatchMode 2

    VarSetCapacity(CopyDataStruct, 12, 0)  ; Set up the structure's memory area.
    NumPut(StrLen(textToWrite) + 1, CopyDataStruct, 4)  ; OS requires that this be done.
    NumPut(&textToWrite, CopyDataStruct, 8)  ; Set lpData to point to the string itself.

    ;---------------------------------------------------------------------------
    ; Issue WM_COPYDATA message to Skype API
    ;---------------------------------------------------------------------------
    SendMessage, WM_COPYDATA, hGui, &CopyDataStruct,, ahk_id %hSKYPE_API%
}


;---------------------------------------------------------------------------
; This function is invoked upon incoming SkypeControlAPIAttach message
;---------------------------------------------------------------------------
SkypeAttach(wParam, lParam, msg, hwnd) {

    global

    ;---------------------------------------------------------------------------
    ; The Skype API handle is returned with WPARAM, if successfully attached
    ;---------------------------------------------------------------------------
    If (lParam = SKYPECONTROLAPI_ATTACH_SUCCESS)
        hSKYPE_API := wParam
}


;---------------------------------------------------------------------------
; This function is invoked upon incoming WM_COPYDATA message
; It is the sample on the bottom of the OnMessage() help page
;---------------------------------------------------------------------------
SkypeReceive(wParam, lParam) {

    global hSkypeText

    ;---------------------------------------------------------------------------
    ; This is the address of CopyDataStruct's lpData member
    ;---------------------------------------------------------------------------
    lpDataAddress := lParam + 8  ; .
    lpData := 0

    ;---------------------------------------------------------------------------
    ; For each byte in the lpData integer
    ;---------------------------------------------------------------------------
    Loop 4  ; For each byte in the lpData integer
    {
        ;---------------------------------------------------------------------------
        ; Build the integer from its bytes
        ;---------------------------------------------------------------------------
        lpData := lpData | (*lpDataAddress << 8 * (A_Index - 1))
        ;---------------------------------------------------------------------------
        ; Move on to the next byte
        ;---------------------------------------------------------------------------
        lpDataAddress += 1
    }

    ;---------------------------------------------------------------------------
    ; lpData contains the address of the string to be copied
    ; (must be a zero-terminated string)
    ;---------------------------------------------------------------------------
    DataLength := DllCall("lstrlen", UInt, lpData)
    If DataLength <= 0
        Control, EditPaste, A blank string was received or there was an error`r`n,, ahk_id %hSkypeText%
    Else
    {
        VarSetCapacity(textReceived, DataLength)
        DllCall("lstrcpy", "str", textReceived, "uint", lpData)  ; Copy the string out of the structure.
        Control, EditPaste, %textReceived%`r`n,, ahk_id %hSkypeText%
        Send ^{End}
    }

    Return true
}


;---------------------------------------------------------------------------
; This function is invoked upon incoming WM_KEYDOWN message
;---------------------------------------------------------------------------
KeyDown(wParam, lParam, msg, hwnd) {

    global hSkypeText, cmdStack, stackIndex

    ;---------------------------------------------------------------------------
    ; Process edit control events only
    ;---------------------------------------------------------------------------
    If (hwnd = hSkypeText)
    {
        ;---------------------------------------------------------------------------
        ; On ENTER key go and send command to Skype API
        ;---------------------------------------------------------------------------
        If (wParam = 13)  ;Enter
            Gosub SkypeSend

        ;---------------------------------------------------------------------------
        ; On UP key step backward and paste command from stack to current line
        ;---------------------------------------------------------------------------
        Else If (wParam = 38)  ;Up
        {
            StringSplit, cmd, cmdStack, `n
            command := cmd%stackIndex%
            Send +{Home}
            Control, EditPaste, %command%,, ahk_id %hSkypeText%
            Send ^{End}
            stackIndex -= 1
            If (stackIndex = 0)
                stackIndex := cmd0-1
        }

        ;---------------------------------------------------------------------------
        ; On DOWN key step forward and paste command from stack to current line
        ;---------------------------------------------------------------------------
        Else If (wParam = 40)  ;Down
        {
            StringSplit, cmd, cmdStack, `n
            command := cmd%stackIndex%
            Send +{Home}
            Control, EditPaste, %command%,, ahk_id %hSkypeText%
            Send ^{End}
            stackIndex += 1
            If (stackIndex > cmd0-1)
                stackIndex := 1
        }
    }
}


;---------------------------------------------------------------------------
; Send entered line command from GUI to the Skype API
;---------------------------------------------------------------------------
SkypeSend:

    ;---------------------------------------------------------------------------
    ; Extract last line (the command just entered) from the edit control
    ;---------------------------------------------------------------------------
    GuiControlGet, SkypeText
    StringSplit, cmd, SkypeText, `n
    command := cmd%cmd0%

    ;---------------------------------------------------------------------------
    ; Return if no command entered
    ;---------------------------------------------------------------------------
    If !command
        Return
   
    ;---------------------------------------------------------------------------
    ; Append command to stack
    ;---------------------------------------------------------------------------
    cmdStack := cmdStack . command . "`n"
    StringSplit, cmd, cmdStack, `n
    stackIndex := cmd0-1

    ;---------------------------------------------------------------------------
    ; Add CRLF
    ;---------------------------------------------------------------------------
    Control, EditPaste, `r`n,, ahk_id %hSkypeText%

    ;---------------------------------------------------------------------------
    ; Send command to Skype API and re-focus edit control for the next input
    ;---------------------------------------------------------------------------
    writeApi(command)
    ControlFocus,, ahk_id %hSkypeText%
Return


;---------------------------------------------------------------------------
; Re-scales imbedded edit control when resizing the main window
;---------------------------------------------------------------------------
GuiSize:

    ControlGetPos, px, py, pw, ph,, ahk_id %hSkypeText%
    ControlMove,, px, py, A_GuiWidth, A_GuiHeight-23, ahk_id %hSkypeText%
Return


;---------------------------------------------------------------------------
; Exit
;---------------------------------------------------------------------------
GuiClose:
    ExitApp
Return
Back to top
View user's profile Send private message
BuggyGas
Guest





PostPosted: Sun Feb 08, 2009 10:49 pm    Post subject: Reply with quote

Great! Thanks!!!
Back to top
Buddy



Joined: 09 Aug 2007
Posts: 11

PostPosted: Tue Feb 10, 2009 6:33 pm    Post subject: Reply with quote

Welcome! 1st comment at all. Glad to hear its helpful for you.
Back to top
View user's profile Send private message
jpjpjp



Joined: 20 Jun 2009
Posts: 13

PostPosted: Fri Jun 26, 2009 5:06 pm    Post subject: Client breaks input to other applications? Reply with quote

I started playing this today and I found that when a skype call is active and the client is getting regular status messages that I can't switch the focus to another application without the cursor constantly jumping down to the bottom of the page.

The net effect of this is that once I've initiated a call (either directly through Skype or through the Skype API GUI client) I can never send another command through the the GUI client since I can't type fast enough before a new async message comes into the GUI client itself, and I can't type the message in a different app to cut and paste it, because the cursor in that app keeps jumping to the bottom.

I can really see the power of this client and will probably run it in a GUI-less mode eventually, but it is helpful to have this GUI client to try to understand the subtleties of the protocol.

Has anyone else had this problem?

Thanks!
Back to top
View user's profile Send private message
bqw371



Joined: 26 Nov 2008
Posts: 32

PostPosted: Thu Jul 23, 2009 9:48 pm    Post subject: display skype call number and call duration as tooltip Reply with quote

@jpjpjp

Yes, I have the same issues.
Here's my workaround for the noted problems.
Copy the clip of code below and replace the section in your original .ahk file.

This will display the Skype Call # and Call Duration as a tooltip instead of sending to the editbox. This allows additional commands to be entered into the Skype API GUI without the duration time continually scrolling in the editbox. Now you can focus to another application without issues as well.

Code:

   ;---------------------------------------------------------------------------
    ; lpData contains the address of the string to be copied
    ; (must be a zero-terminated string)
    ;---------------------------------------------------------------------------
    DataLength := DllCall("lstrlen", UInt, lpData)
    If DataLength <= 0
        Control, EditPaste, A blank string was received or there was an error`r`n,, ahk_id %hSkypeText%
    Else
    {
        VarSetCapacity(textReceived, DataLength)
        DllCall("lstrcpy", "str", textReceived, "uint", lpData)  ; Copy the string out of the structure.
       
        if textReceived contains DURATION
        if textReceived not contains BODY
        {
            tooltip, %TextReceived%
            sleep, 999
            Tooltip ;clear tooltip

}     if textReceived not contains DURATION
        {
        Control, EditPaste, %textReceived%`r`n,, ahk_id %hSkypeText%
        ;msgbox, %textReceived%
        controlsend, EditPaste, ^{End},, ahk_id %hSkypeText%
        }
   
    Return true
}


@buddy

Thank you for this ahk Skype API wrapper.
Back to top
View user's profile Send private message
geeneeyes



Joined: 24 May 2006
Posts: 66
Location: New Mumbai, India

PostPosted: Sun Jul 26, 2009 6:16 pm    Post subject: Reply with quote

what does this script do?
i know skype but how does one use this script with skype?
no buttons no nothing.. atleast provide some info.. F1!!
_________________
irc://irc.freenode.net/ahk
Opera: SpeedDial, Email, Extensions, Widgets, Unite, UserJS, Notes, Contacts, IRC, BitTorrent, Download Manager, Tab Stacking, Thumbnails, Sessions, VoiceControl, Mouse Gestures, Content/Flash Blocker, Opera Link, Turbo mode
Back to top
View user's profile Send private message Visit poster's website Yahoo Messenger
bqw371



Joined: 26 Nov 2008
Posts: 32

PostPosted: Sun Jul 26, 2009 11:59 pm    Post subject: Reply with quote

@GeeNeeYes

Open skype, run the script, type the below command into the ahk GUI & press enter.

call echo123

echo123 being the username of the SKYPE / Sound Test Service.

Learn more here:
https://developer.skype.com/Docs/ApiDoc/Making_and_managing_voice_calls
Back to top
View user's profile Send private message
jpjpjp



Joined: 20 Jun 2009
Posts: 13

PostPosted: Mon Aug 03, 2009 7:49 pm    Post subject: What does the Skype API do? Reply with quote

@GeeNeeYes

I asked the same question in a different thread (http://www.autohotkey.com/forum/viewtopic.php?t=42247&highlight=skype). What I was hoping to use this script for was to find a way to send DTMF (ie: TouchTone) input to calls from the clipboard.

Once I got the hang of it I found that I could highlight a phone number combination and then with a couple of keystrokes have skype dial phone numbers with or without extensions.

Rather than post all the code that parses the highlighted text and tries to make sense out of which are numbers and which aren't, here's an example when I always wanted to call the same number

Code:

; Dial the conference bridge, with JP's conf login
+#j::
  SkypeDTMF := "12345678#*4482#"
  SkypeMessage := "#ahk call +1555-555-1234"
  writeAPI(SkypeMessage)
return


Sending the message "#ahk call +1555-555-1234" tells the Skype Client to dial the phone number "+1555-555-1234". Populating the variable SkypeDTMF tells it to send DTMF after the outbound call is made.

In order to get the SkypeClient to send the DTMF at the correct time I modified the method that handles messages to the Skype Client as follows:

Code:

    ;---------------------------------------------------------------------------
    ; lpData contains the address of the string to be copied
    ; (must be a zero-terminated string)
    ;---------------------------------------------------------------------------
    DataLength := DllCall("lstrlen", UInt, lpData)
    If DataLength <= 0
        msgbox blank received
    Else
    {
        VarSetCapacity(textReceived, DataLength)
        DllCall("lstrcpy", "str", textReceived, "uint", lpData)  ; Copy the string out of the structure.
        ;msgbox % textReceived
        If InStr(textReceived, "RINGING") {
            SkypeCallID := StringMod(textReceived, "Only", "0123456789")
            SkypeDTMFSent := "false"
        } Else If (InStr(textReceived, "EARLYMEDIA") || InStr(textReceived, "INPROGRESS")) {
              If ((SkypeDTMF != "") && (SkypeDTMFSent = "false")) {
                msgbox Will send DTMF Tones %SkypeDTMF% to Skype Call ID: %SkypeCallID%
                SendSkypeDTMF()
                SkypeDTMFSent := "true"
              }
        } Else If (InStr(textReceived, SkypeCallID) && InStr(textReceived, "DTMF")) {
            SendSkypeDTMF()
        } Else If (InStr(textReceived, SkypeCallID) && InStr(textReceived, "FINISHED")) {
            SkypeCallID := ""
        ;} Else {
            ;msgbox % SkypeCallID
        } ; else ignore the message
    }


The key bit here is that after I get the RINGING message I can grab the call ID. At that point I also post a message box stating which DTMF keys I will send. I ended up doing this since it allows the user to wait until the called party asks for those digits before sending them. You might also notice that I also call the SendDTMF method anytime I get a DTMF message in the client.

Finally, I simply created the method SendSkypeDTMF here:

Code:

;---------------------------------------------------------------------------
; This function is invoked by SkypeRecieve to send a DTMF tone if there are
; any in the queue waiting to be sent
;---------------------------------------------------------------------------
SendSkypeDTMF() {
    global SkypeDTMF
    global SkypeCallID
    if ((SkypeDTMF != "") && (SkypeCallID != "")){
        StringLeft, DTMF, SkypeDTMF, 1
        StringTrimLeft SkypeDTMF, SkypeDTMF, 1
        if (DTMF == ",") {
           ; pause half a second for a comma
            StringLeft, DTMF, SkypeDTMF, 1
            StringTrimLeft SkypeDTMF, SkypeDTMF, 1
            Sleep, 500
        }
        SkypeMessage := "alter call " . SkypeCallID . " DTMF " . DTMF
        writeAPI(SkypeMessage)
        Sleep, 300
    }
}



This basically just sends a message to Skype telling it to "alter" the call that matches our ID (in the variable SkypeCallID) by sending it a DTMF tone. After this message is sent I sleep for 300 msecs.

I played around with different times to sleep between sending DTMF messages. If I didn't sleep at all, the called party often did not intepret the DTMF correctly. (I've noticed the same thing when I just cut and paste a string of digits into the "keyboard" on the Skype client.

Finally, I added in some stuff to pause for an extra 500 msecs if there is a comma in the DTMF string.

Anyhow, this has saved me a ton of time since I do 5-10 conference calls every day.

@buddy

Thanks!
Back to top
View user's profile Send private message
drmartell



Joined: 23 Feb 2008
Posts: 27

PostPosted: Sat Oct 31, 2009 5:57 am    Post subject: Reply with quote

Does anyone have a version of the API that works. The ones I am finding in these threads all give errors within AHK as written.

UPDATE: My bad, I had an outdated installation of AHK, upgrading has solved the errors.
Back to top
View user's profile Send private message
drmartell



Joined: 23 Feb 2008
Posts: 27

PostPosted: Wed Nov 04, 2009 3:32 pm    Post subject: Reply with quote

I am preferring call duration output to StatusBar:
Code:
;tooltip, %TextReceived%
;sleep, 999
;Tooltip ;clear tooltip
SB_SetText(TextReceived)
Back to top
View user's profile Send private message
Silverhawke



Joined: 30 Nov 2009
Posts: 1
Location: Italy

PostPosted: Mon Nov 30, 2009 7:34 am    Post subject: How change Skype user comment Reply with quote

Hello, I'm a player and Skype fanatic often disturbing.
I have the G15 keyboard applet Gskype, i can answer from the keyboard. Now i want to change the comment of the user to " 'I'm playing," and after the game session to change back the comment.
Save the comment in a file and read it again is not a problem but i do not know how to read and rewrite the comment in skype. Can you help? All help is appreciated. thanks.

Edit:
I found the solution:
Code:

Skypename=xxx
ControlSetText, TMoodRichEdit.UnicodeClass1, spiele gerade, Skype™ - %Skypename%
Sleep 7000
ControlSetText, TMoodRichEdit.UnicodeClass1, wieder online, Skype™ - %Skypename%

Thanks
Back to top
View user's profile Send private message
ColdFlo
Guest





PostPosted: Fri Jan 21, 2011 11:41 pm    Post subject: Reply with quote

A blank string was received or there was an error?
Win7 64 AHK 64 Latest Skype.........
Back to top
ColdFlo
Guest





PostPosted: Fri Jan 21, 2011 11:52 pm    Post subject: Reply with quote

OH IC this is Skype API Console hmmm what command is possible here?
Back to top
jpjpjp



Joined: 20 Jun 2009
Posts: 13

PostPosted: Tue Apr 12, 2011 8:33 pm    Post subject: Reply with quote

@ColdFlo

I ran into the same problems when I went to Windows 7. I played for about a day with no luck in trying to deal with the 64 bit version of lparam with no luck.

Loaded 32 bit verison of AHK and the script worked again nicely.

I've got both versions installed and simply invoke my Skype script explicitly with the 32 bit version.

Hope this helps...sorry I missed your original post!
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group