1

Тема: JS: пример бота ICQ

Приветствую. Хочу поделиться примером работы с ICQ на JScript.

function callback(uin, msg)
{
	this.SendMessage(uin, "OK");
	if (msg=="close") 
	{
		this.SendMessage(uin, "bye");
		this.Close();
		WScript.Quit();
	}
}

var bot = new ICQ("9166196", "***");

bot.AddOnMsgListener(callback);
bot.Start();

while(1) WScript.Sleep(50);

Методы объекта ICQ

AddOnMsgListener(callback) - добавление обработчиков события получения сообщения.
Start() - старт клиента
SendMessage(uin, text) - отправка сообщения
Close() - закрыть клиент

Разумеется на чистом JS такое не получится (хотя ведется некоторая работа и в этом направлении по использованию WebAPI от ICQ). Поэтому придется с собой тянуть еще пару файлов: IcqBot.exe и IcqMod.dll.  IcqBot.exe представляет собой скомпилированный код AutoIt. Для начала работы  запустите файл JS.

Ссылка на закачку исправленная версия

Код скрипта


var WshShell = new ActiveXObject("WScript.Shell");

function GlobalObject(Name)
{    
    if(!Name)Name="GlobalObject";
    if (this.Window = this.FindWindow(Name))null;else
    {
        this.Window = GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}");
        this.Window.StatusText = Name;
    }
}

GlobalObject.prototype = 
{
    FindWindow : function (Name)
    {
        var  ShellWindows=(new ActiveXObject("Shell.Application")).Windows();
        for (var i=ShellWindows.Count; --i>=0;)
        if (ShellWindows.Item(i).StatusText && ShellWindows.Item(i).StatusText.indexOf(Name)!=-1) 
        return ShellWindows.Item(i);
    },
    
    GetProperty: function (Name)
    {
        return this.Window.GetProperty(Name);
    },
    
    SetProperty: function (Name, Value)
    {
        this.Window.PutProperty(Name, Value);
    }
}

function TerminateProcessByName(Name)
{

var objWMIService, colitems, e;
	objWMIService = GetObject("winmgmts:{impersonationlevel=impersonate}!\\\\.\\root\\cimv2");
	colitems = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE name = '"+Name+"'");
	e = new Enumerator(colitems);
	for (; !e.atEnd(); e.moveNext())
	e.item().Terminate();
}

function ICQ(uin, pass)
{
	this.__callbacks=[];
	this.g = new GlobalObject("ICQ");
	this.g.SetProperty("login", uin);
	this.g.SetProperty("pass", pass);
	this.g.SetProperty("quit", "0");
	this.g.SetProperty("scriptbot", this);
}

ICQ.prototype.SendMessage = function (To, Text)
{
	this.g.SetProperty("text", Text);
	this.g.SetProperty("uin", To);
}

ICQ.prototype.__OnMessageFireEvent = function (uin, msg) 
{
	for (var i=0, l=this.__callbacks.length; i<l; i++)
	this.__callbacks[i].call(this, uin, msg);
}

ICQ.prototype.AddOnMsgListener = function (callback)
{
	this.__callbacks.push(callback);
}

ICQ.prototype.Start=function ()
{
	WshShell.Run("IcqBot");
}

ICQ.prototype.Close = function () 
{
	this.g.SetProperty("quit", "1");
	this.g.SetProperty("uin", 0);
	WScript.Sleep(1000);
	var e;
	try {
		TerminateProcessByName("IcqBot.exe")
		this.g.Quit();
	} catch (e) {}
	
}

//---------------------------------------------------------------

function callback(uin, msg)
{
	this.SendMessage(uin, "OK");
	if (msg=="close") 
	{
		this.SendMessage(uin, "bye");
		this.Close();
		WScript.Quit();
	}
}

var bot = new ICQ("9166196", "***");

bot.AddOnMsgListener(callback);
bot.Start();

while(1) WScript.Sleep(50);

Вот код "сервера" на AutoIt

#NoTrayIcon 
#include <IcqMod.au3>

$oContainer = OpenContainer("ICQ")

Func OpenContainer($sName)
    Local $oShell, $oShellWindow, $oShellWindows
    $oShell = ObjCreate("Shell.Application")
    $oShellWindows = $oShell.Windows
    
    For $oShellWindow In $oShellWindows
        If StringInstr($oShellWindow.StatusText, $sName) Then
            Return $oShellWindow
        EndIf
    Next
    
    $oContainer = ObjGet("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}")
    $oContainer.StatusText = $sName
    
    Return $oContainer
EndFunc

Func PutProperty($oContainer, $sName, $vValue)
    $oContainer.PutProperty($sName, $vValue)
EndFunc

Func GetProperty($oContainer, $sName)
    Return $oContainer.GetProperty($sName)
EndFunc

$icqlogin = GetProperty($oContainer, "login")
$icqpass = GetProperty($oContainer, "pass")
$scriptbot = GetProperty($oContainer, "scriptbot")

Func Check()
   $uin = GetProperty($oContainer, "uin")
   $text = GetProperty($oContainer, "text")
   If ($uin<>0) Then 
	  ICQ_Send_Msg($uin, $text) 
      PutProperty($oContainer, "uin", "0")
   EndIf
   
   If GetProperty($oContainer, "quit")="1" Then 
	  ICQ_Close() 
	  Exit
   EndIf
EndFunc

if ICQ_Connect("login.icq.com", 5190, $icqlogin, $icqpass) = $ICQ_CONNECT_STATUS_OK	Then
	
	While DllStructGetData($ICQ_CLIENT, "status") = $ICQ_CLIENT_STATUS_CONNECTED
		Sleep(100)
		Check()
		If ICQ_Read_Msg() = 1 Then
			$RecvMsg = DllStructGetData($RecvInfo, "msg")
			$scriptbot.__OnMessageFireEvent(DllStructGetData($RecvInfo,"uin"), $RecvMsg)
		EndIf
	WEnd
Else
	MsgBox(0, "Error", "Connection error")
EndIf