Cкайп, D-Bus и Go

Мелкософт уже давно грозят прикрыть АПИ в skype для сторонних программ. Но видать,там что-то такое накуралешено, что они уже сами не разберутся. Поэтому апи пока работает и добраться до него можно. Но не факт что будет работать в следующих версиях. Если что, то у меня убунту 12.04 и версия скайпа 4.2.0.11

D-Bus

D-Bus - это система для взаимодействия программ. Одно приложение может выполнять запросы к другому.

В Go есть несколько либ для работы с D-Bus. Самая нормальная это github.com/norisatir/go-dbus. В принципе, кроме этой либы нам больше ничего не нужно, можем подключаться к скайпу:

package skype

import (
    "log"
    "github.com/norisatir/go-dbus"
)

var conn *dbus.Connection

func SkypeConnect() {
    var (
        err error
        conn *dbus.Connection
        method *dbus.Method
        out []interface{}
    )
    if conn, err = dbus.Connect(dbus.SessionBus); err != nil {
        log.Fatal("Connection error:", err)
    }

    //...
}

Замечательно. Теперь нужно аутентифицироваться и разрешить наше приложение в настройках скайпа

if err = conn.Authenticate(); err != nil {
    log.Fatal("Authentication error:", err)
}

Теперь можем получить экземпляр API и начать работу непосредственно с скайповским D-Bus протоколом. Из самого API нам нужен метод Invoke

obj := conn.Object("com.Skype.API", "/com/Skype")

method, err = obj.Interface("com.Skype.API").Method("Invoke")
if err != nil {
    log.Fatal(err)
}

Используем API выполняя запросы через D-Bus. При выполнении первого вызова в скайпе появится окошко, которое попросит разрешить стороннему приложению подключиться к скайпу.

out, err = conn.Call(method, "NAME Go") // устанавливаем имя приложения
fmt.Println(out)
out, err = conn.Call(method, "PROTOCOL 8") // это версия которая будет использоваться
                                           // при обращении к API
fmt.Println(out)
out, err = conn.Call(method, "GET SKYPEVERSION")
fmt.Println(out)
out, err = conn.Call(method, "SEARCH RECENTCHATS") // выведет список последних чатов
fmt.Println(out)
out, err = conn.Call(method, "CHAT CREATE myfriend") // создаем новый чат с skype-пользователем
fmt.Println(out)
// отправляем сообщение в определенный чат
out, err = conn.Call(method, "CHATMESSAGE #artemkovardin/$myfriend;8cbc8f1ec76c5a61 message")

Собственно, все. Если интересно разбираться дальше, то вы хрен найдете вменяемую документацию. Я нашел только это

Код к статье лежит на github

updatedupdated2021-03-062021-03-06