Некоторое время назад случилось так, что пользоваться скайпом стало практически невозможно — спам-боты стучались один за другим. Неприятным фактом стало то, что в клиенте нет (до сих пор, впрочем) никакой предусмотренной функции антиспама, вроде контрольного вопроса или ещё чего-нибудь.
Нет — будет. На сайте обнаружился какой-никакой, а ассортимент wrapper'ов к API. Выбор пал на Python, ибо ничего масштабного не требовалось, а «import antigravity» только радовало. В процессе отладки скрипта было замечено несколько косяков в API. Оные были заботливо подпёрты костылями. Итак:
¬ следует автозаменить на табуляцию, так вот глупо и неудобно определяется вложенность...
Затем сие сохраняется в файл с расширением .pyw и крутится в фоне.
P.S. К счастью, волна спама давно поутихла, но вдруг кому-то пригодится.
Нет — будет. На сайте обнаружился какой-никакой, а ассортимент wrapper'ов к API. Выбор пал на Python, ибо ничего масштабного не требовалось, а «import antigravity» только радовало. В процессе отладки скрипта было замечено несколько косяков в API. Оные были заботливо подпёрты костылями. Итак:
import Skype4Py
from time import sleep
skype = Skype4Py.Skype()
TRYING = 1
TEXT = {
¬'QUESTION':"Hello. It's antispam bot. Answer, 2+2=? One figure, please. You have %i trying." % (TRYING),
¬'ANSWER':"4",
¬'WIN':"Right. I'll write you soon.",
¬'AGAIN':"Try one more time.",
¬'FAIL':"Autoignoring.",
¬'INSTANT_BAN':"Autoignoring due to banned word in the authorization request or in the name."
}
BANNED = {
¬'WORDS':("http", "www"),
¬'NAMES':("")
}
HIDE_MESSAGES_AFTER_WRONG_ANSWER = True # True may cause loss of the new answers
REFRESH_DELAY = 30 # in seconds
GET_NAME_DELAY = 1.5
queue = {}
def answer_received(msg, status):
¬username = msg._GetSender()._GetHandle()
¬if username in queue.keys():
¬¬if status==Skype4Py.cmsReceived:
¬¬¬if msg._GetBody()!=TEXT['ANSWER']:
¬¬¬¬if HIDE_MESSAGES_AFTER_WRONG_ANSWER:
¬¬¬¬¬skype.UnregisterEventHandler('MessageStatus', answer_received)
¬¬¬¬¬for eachMsg in msg._GetChat()._GetRecentMessages():
¬¬¬¬¬¬try:
¬¬¬¬¬¬¬eachMsg.MarkAsSeen()
¬¬¬¬¬¬except:
¬¬¬¬¬¬¬continue
¬¬¬¬¬skype.RegisterEventHandler('MessageStatus', answer_received)
¬¬¬¬queue[username] = queue[username]-1
¬¬¬¬if queue[username]:
¬¬¬¬¬skype.SendMessage(username, TEXT['AGAIN'])
¬¬¬¬¬return
¬¬¬¬else:
¬¬¬¬¬del queue[username]
¬¬¬¬¬skype.SendMessage(username, TEXT['FAIL'])
¬¬¬¬¬msg._GetSender()._SetIsBlocked(True)
¬¬¬else:
¬¬¬¬del queue[username]
¬¬¬¬skype.SendMessage(username, TEXT['WIN'])
¬¬¬if len(queue)==0:
¬¬¬¬skype.UnregisterEventHandler('MessageStatus', answer_received)
def hasBanned(txtstr, target):
¬for word in BANNED[target]:
¬¬if word in txtstr:
¬¬¬return True
¬return False
def auth_received(from_user):
¬newUsers = skype._GetUsersWaitingAuthorization()
¬if not newUsers:
¬¬for key in queue.keys():
¬¬¬del queue[key]
¬¬return
¬for user in newUsers:
¬¬username = user._GetHandle()
¬¬if not (username in queue.keys()):
¬¬¬if TRYING < 1:
¬¬¬¬skype.SendMessage(username, TEXT['FAIL'])
¬¬¬¬user._SetIsBlocked(True)
¬¬¬¬continue
¬¬¬if hasBanned(user._GetReceivedAuthRequest(), 'WORDS'):
¬¬¬¬skype.SendMessage(username, TEXT['INSTANT_BAN'])
¬¬¬¬user._SetIsBlocked(True)
¬¬¬¬continue
¬¬¬skype.RegisterEventHandler('MessageStatus', answer_received)
¬¬¬skype.SendMessage(username, TEXT['QUESTION'])
¬¬¬queue[username] = TRYING
¬¬¬sleep(GET_NAME_DELAY)
¬¬¬if hasBanned(user._GetFullName(), 'NAMES'): # Skype's bug: full name is available only after message sending
¬¬¬¬del queue[username]
¬¬¬¬skype.SendMessage(username, TEXT['INSTANT_BAN'])
¬¬¬¬user._SetIsBlocked(True)
¬¬¬¬if len(queue)==0:
¬¬¬¬¬skype.UnregisterEventHandler('MessageStatus', answer_received)
¬¬¬¬continue
skype.RegisterEventHandler('UserAuthorizationRequestReceived', auth_received)
# В принципе следующий цикл не обязателен, но тогда при перезапуске скайпа придётся перезапускать и скрипт. И именно в такой последовательности.
while True:
¬skype.Attach()
¬auth_received(None)
¬sleep(REFRESH_DELAY)
¬ следует автозаменить на табуляцию, так вот глупо и неудобно определяется вложенность...
Затем сие сохраняется в файл с расширением .pyw и крутится в фоне.
P.S. К счастью, волна спама давно поутихла, но вдруг кому-то пригодится.