AutoHotkey Community

It is currently May 26th, 2012, 9:59 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: October 14th, 2008, 6:40 pm 
Offline

Joined: August 9th, 2007, 10:18 am
Posts: 11
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 8th, 2009, 11:49 pm 
Great! Thanks!!!


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: February 10th, 2009, 7:33 pm 
Offline

Joined: August 9th, 2007, 10:18 am
Posts: 11
Welcome! 1st comment at all. Glad to hear its helpful for you.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: June 26th, 2009, 6:06 pm 
Offline

Joined: June 20th, 2009, 10:03 pm
Posts: 13
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!


Report this post
Top
 Profile  
Reply with quote  
PostPosted: July 23rd, 2009, 10:48 pm 
Offline

Joined: November 26th, 2008, 4:16 pm
Posts: 32
@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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 26th, 2009, 7:16 pm 
Offline

Joined: May 24th, 2006, 7:08 pm
Posts: 66
Location: New Mumbai, India
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 27th, 2009, 12:59 am 
Offline

Joined: November 26th, 2008, 4:16 pm
Posts: 32
@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


Report this post
Top
 Profile  
Reply with quote  
PostPosted: August 3rd, 2009, 8:49 pm 
Offline

Joined: June 20th, 2009, 10:03 pm
Posts: 13
@GeeNeeYes

I asked the same question in a different thread (http://www.autohotkey.com/forum/viewtop ... ight=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!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 31st, 2009, 6:57 am 
Offline

Joined: February 23rd, 2008, 6:52 pm
Posts: 30
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 4th, 2009, 4:32 pm 
Offline

Joined: February 23rd, 2008, 6:52 pm
Posts: 30
I am preferring call duration output to StatusBar:
Code:
;tooltip, %TextReceived%
;sleep, 999
;Tooltip ;clear tooltip
SB_SetText(TextReceived)


Report this post
Top
 Profile  
Reply with quote  
PostPosted: November 30th, 2009, 8:34 am 
Offline

Joined: November 30th, 2009, 8:22 am
Posts: 1
Location: Italy
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 22nd, 2011, 12:41 am 
A blank string was received or there was an error?
Win7 64 AHK 64 Latest Skype.........


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 22nd, 2011, 12:52 am 
OH IC this is Skype API Console hmmm what command is possible here?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: April 12th, 2011, 9:33 pm 
Offline

Joined: June 20th, 2009, 10:03 pm
Posts: 13
@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!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 4th, 2012, 5:25 pm 
Offline

Joined: February 27th, 2012, 9:31 pm
Posts: 10
Location: Sweden
jpjpjp wrote:
@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!


Hi.. Nice !!

But why this ?? Tryed out anything but cant get anything happend, eaven trying the simple CALL.

Running Windows 7, 64 bit. How do i invoke the option 32 or 64 bit in Ahk. Think I'm running 64-bit now.

Anyone ho can explane this to me ??

Sorry for my por Englich, But I'm an Swedich Viking !!
Brg to Y all HotKey'ers
/FROGMAN


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: kenn and 14 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group