Привет! Данный топик будет посвящен написанию автоответчика для Skype, который будет принимать за вас звонки, проигрывать приветствие и записывать ответ.
Дано: Skype: 5.0.0.156, WinXPSP3, ActiveState Python 2.6.2.2.
По идеи, работать должно и под *nix, но не тестировалось. Для взаимодействия со Skype через его API будем использовать Skype4py. Скачать можно тут, а с документацией ознакомиться здесь.
Используя Skype4py, достаточно просто взаимодействовать со Skype, для нашей задачи необходимо только прописать свои обработчики различных событий. Обрабатывать события мы будем в нашем классе:
Обработчик OnCall, принимает входящие звонки, в том случае, если мы не отвечаем на звонок больше чем time2wait секунд. Заодно выводит дополнительную отладочную информацию. Вызов call.Answer взят в try..except для минимизации кода, если по честному, то там необходимо обработать различные ситуации, например, завершение вызова звонящим до поднятия трубки и другие. В WavFile хранится файл, который мы будем проигрывать всем звонящим:
В OnInputStatusChanged мы будем отлавливать завершение проигрывания нашего файла и начнем запись голоса звонящего. Все записи будут складываться в подпапку с имене��, совпадающим с ником пользователя, в папке IncomingCallsDir. Вызов call.InputDevice(Skype4Py.callIoDeviceTypeFile, None) прекращает воспроизведение нашего файла, в противном случае файл будет проигран несколько раз.
Вот собственно и все. Ниже весь код целиком:
UPD: исправил два бага в логике, автоответчик включался также при исходящих звонках и включался, в случае если трубка таки была поднята человеком.
Дано: Skype: 5.0.0.156, WinXPSP3, ActiveState Python 2.6.2.2.
По идеи, работать должно и под *nix, но не тестировалось. Для взаимодействия со Skype через его API будем использовать Skype4py. Скачать можно тут, а с документацией ознакомиться здесь.
Используя Skype4py, достаточно просто взаимодействовать со Skype, для нашей задачи необходимо только прописать свои обработчики различных событий. Обрабатывать события мы будем в нашем классе:
class AnsweringMachine: def __init__(self): self.FilesPath = os.getcwd() + '\\' #путь до нашего рабочего каталога файлов self.WavFile = self.FilesPath + 'outofoffice.wav' #файл с ответом self.IncomingCallsDir = self.FilesPath + 'incoming\\' #папка с аудиофайлами self.time2wait = 30 #время ожидания звонка self.callsanswered = dict() #словарь в котором мы будем хранить состояние принимаемых звонков.
Обработчик OnCall, принимает входящие звонки, в том случае, если мы не отвечаем на звонок больше чем time2wait секунд. Заодно выводит дополнительную отладочную информацию. Вызов call.Answer взят в try..except для минимизации кода, если по честному, то там необходимо обработать различные ситуации, например, завершение вызова звонящим до поднятия трубки и другие. В WavFile хранится файл, который мы будем проигрывать всем звонящим:
def OnCall(self, call, status): if status == Skype4Py.clsRinging and call.Type.startswith('INCOMING'): print 'Incoming call from:', call.PartnerHandle time.sleep(self.time2wait) if call.Duration == 0: try: call.Answer() except: pass self.callsanswered[call.Id] = 'Answered' else: self.callsanswered[call.Id] = 'HumanAnswered' if status == Skype4Py.clsInProgress and self.callsanswered[call.Id] == 'Answered': self.callsanswered[call.Id] = 'Playing' print ' playing ' + self.WavFile call.InputDevice(Skype4Py.callIoDeviceTypeFile, self.WavFile) if status in CallIsFinished: print 'call ',status.lower()
В OnInputStatusChanged мы будем отлавливать завершение проигрывания нашего файла и начнем запись голоса звонящего. Все записи будут складываться в подпапку с имене��, совпадающим с ником пользователя, в папке IncomingCallsDir. Вызов call.InputDevice(Skype4Py.callIoDeviceTypeFile, None) прекращает воспроизведение нашего файла, в противном случае файл будет проигран несколько раз.
def OnInputStatusChanged(self, call, status): if not status and call.InputDevice().has_key('FILE') and call.InputDevice()['FILE'] == self.WavFile and self.callsanswered[call.Id] == 'Playing': self.callsanswered[call.Id] = 'Recording' print ' play finished' if not os.path.exists(self.IncomingCallsDir + call.PartnerHandle): os.mkdir(self.IncomingCallsDir + call.PartnerHandle) OutFile = self.IncomingCallsDir + call.PartnerHandle + '\\' + time.strftime("%Y-%m-%d_%H-%M-%S") + '.wav' call.InputDevice(Skype4Py.callIoDeviceTypeFile, None) print ' recording ' + OutFile call.OutputDevice(Skype4Py.callIoDeviceTypeFile, OutFile)
Вот собственно и все. Ниже весь код целиком:
#!/usr/bin/python # -*- coding: cp1251 -*- import Skype4Py import sys, time, os CallIsFinished = set ([Skype4Py.clsFailed, Skype4Py.clsFinished, Skype4Py.clsMissed, Skype4Py.clsRefused, Skype4Py.clsBusy, Skype4Py.clsCancelled]); class AnsweringMachine: def __init__(self): self.FilesPath = os.getcwd() + '\\' #путь до нашего рабочего каталога файлов self.WavFile = self.FilesPath + 'outofoffice.wav' #файл с ответом self.IncomingCallsDir = self.FilesPath + 'incoming\\' #папка с аудиофайлами self.time2wait = 30 #время ожидания звонка self.callsanswered = dict() #словарь в котором мы будем хранить состояние принимаемых звонков. if not os.path.exists(self.IncomingCallsDir): os.mkdir(self.IncomingCallsDir) def OnCall(self, call, status): if status == Skype4Py.clsRinging and call.Type.startswith('INCOMING'): print 'Incoming call from:', call.PartnerHandle time.sleep(self.time2wait) if call.Duration == 0: try: call.Answer() except: pass self.callsanswered[call.Id] = 'Answered' else: self.callsanswered[call.Id] = 'HumanAnswered' if status == Skype4Py.clsInProgress and self.callsanswered[call.Id] == 'Answered': self.callsanswered[call.Id] = 'Playing' print ' playing ' + self.WavFile call.InputDevice(Skype4Py.callIoDeviceTypeFile, self.WavFile) if status in CallIsFinished: print 'call ',status.lower() def OnInputStatusChanged(self, call, status): if not status and call.InputDevice().has_key('FILE') and call.InputDevice()['FILE'] == self.WavFile and self.callsanswered[call.Id] == 'Playing': self.callsanswered[call.Id] = 'Recording' print ' play finished' if not os.path.exists(self.IncomingCallsDir + call.PartnerHandle): os.mkdir(self.IncomingCallsDir + call.PartnerHandle) OutFile = self.IncomingCallsDir + call.PartnerHandle + '\\' + time.strftime("%Y-%m-%d_%H-%M-%S") + '.wav' call.InputDevice(Skype4Py.callIoDeviceTypeFile, None) print ' recording ' + OutFile call.OutputDevice(Skype4Py.callIoDeviceTypeFile, OutFile) def OnAttach(status): global skype print 'Attachment status: ' + skype.Convert.AttachmentStatusToText(status) if status == Skype4Py.apiAttachAvailable: skype.Attach() def main(): global skype am = AnsweringMachine() skype = Skype4Py.Skype() skype.OnAttachmentStatus = OnAttach skype.OnCallStatus = am.OnCall skype.OnCallInputStatusChanged = am.OnInputStatusChanged if not skype.Client.IsRunning: print 'Starting Skype..' skype.Client.Start() print 'Connecting to Skype process..' skype.Attach() print 'Waiting for incoming calls' try: while True: time.sleep(1) except: pass if __name__ == '__main__': main()
UPD: исправил два бага в логике, автоответчик включался также при исходящих звонках и включался, в случае если трубка таки была поднята человеком.
