OK、これは私の大きな問題であり、実際の例を作成するのに 1 時間以上費やしたので、誰かが私の問題に十分に共感して、助けやフィードバックを提供してくれることを願っています。php 5.4 を実行している centos システムへの bash アクセスを提供する準備ができているので、コードを自分でテストできます。結果を自分で確認できるように、電報グループ「テスト チャット」に招待することもできます。寄付を受け入れる場合は、$$$$$$ を寄付する準備ができています。価格を指定してください。
シナリオは次のとおりです。IRC と Telegram に接続する通信ボットを実行しています。#public
アイデアは、人々がチャット チャネル ( on irc.glx-alliance.com:6668
) と Telegram グループに !uptime と入力するtest chat
と、ボットがオンラインになってからの時間を教えてくれるというものです。この例は機能しています。IRC と TG の両方が、!uptime
コマンドによる要求に応じて稼働時間の統計を返します。ここまでは順調ですね。
ここに問題!uptime
があります。IRC クライアントに入力すると、0.02 秒という超高速の応答時間が得られます。優秀な。それはうまくいきます。ただし、Telegram 統合の場合、!uptime
応答に最大 30 秒かかる場合があります。その理由は以下。
いくつかの詳細: Telegram 応答のイニシエータは、ループのチェックが非常に遅いということではなく、IRC が IRC 接続にデータを送信したということです。次に、電報コードの実行を促します。チャット チャネルに入力するだけでこれを簡単に再現でき、すぐに Telegram テスト チャット チャネルが稼働時間の応答を受け取ります。
これが私の作業例です。6668
これを機能させるには、ファイアウォールでポートを開き、telegram-cli
インストールして、telegram-cli-php がインストールされたディレクトリから実行する必要があります。https://github.com/zyberspace/php-telegram-cli-clientを参照してください。composer require zyberspace/telegram-cli-client
プロジェクト ディレクトリを入力し、ディレクトリ内に vendor.php への呼び出しを含むtelegramIntegrations.php
ファイルを作成するだけです。includes
( require('vendor/autoload.php');
)。私の電話番号は +447935499706 です。テレグラムに追加してください。あなたをtest chat
グループに招待します。
これがコードです。コードゴルフをプレイしない限り、これ以上ファイルサイズを小さくすることはできません。コード自体の後に重要なビットについて説明します。
<?php
set_time_limit(0);
ini_set('display_errors', 'on');
global $configure;
$configure = array(
'server' => 'irc.glx-alliance.com',
'port' => 6668,
'nick' => 'ExampleBot',
'name' => 'Example Bot'
);
include_once('../includes/telegramIntegration.php');
class IRCBot{
// TCP connection holder.
public $socket;
// Message holder.
public $msg = array();
/*
* Constucter.
* Opens the server connection, and logs in the bot.
*
* @param array.
*/
function __construct($configure){
echo '-----------Socket opening...----------------------------------' ."\r\n";
$this->socket = fsockopen($configure['server'], $configure['port']);
$this->login($configure);
$this->timestamp = time();
$this->main();
}
/*
* Logs bot in to server
*
* @param array.
*/
function login ($configure){
$this->send_data('USER', $configure['nick'] . ' rogues-alliance.com ' . $configure['nick'] . ' :' . $configure['name']);
$this->send_data('NICK', $configure['nick']);
}
/*
* Startup commands
*/
function startup () {
echo 'Startup initiated...' . PHP_EOL;
echo 'Startup finished' . PHP_EOL;
}
/*
* Bot Command
*/
function intel () {
return $this->intel;
}
/*
* Main function, used to grab all data.
*/
function main(){
while (true):
/* Fetch Data From Telegram Socket */
$this->telegram = new \Zyberspace\Telegram\Cli\Client('unix:///tmp/tg.sck');
/* Fetch Data From IRC Socket */
$data = fgets($this->socket, 1024);
flush();
$data = preg_replace('/\s{2,}/ ', ' ', $data) . PHP_EOL;
$this->ex = explode(' ', $data);
/* Ping Pong */
if($this->ex[0] == 'PING'):
$this->send_data('PONG', $this->ex[1]);
endif;
/* Internal While Loops */
if (!$this->firstRun) {
$this->firstRun = true;
// do some stuff
}
if ($this->inited){ // have we had the server motd etc
}
/* Format Text */
$command = str_replace(array(chr(10), chr(13)), '', $this->ex[3]);
if (strtoupper($this->ex[1]) == $this->ex[1]):
$request = $this->ex[1];
endif;
/* Handle Text from IRC $data */
switch ($request):
case 'PRIVMSG':
/* Setup Variables */
$host = $this->ex[0];
$username = substr($host, 1, strpos($host, '!')-1);
$target = $this->ex[2];
// list of commands the bot responds to
switch ($command){
case ':!uptime':
$this->sendMessage($this->uptime());
break;
break;
case ':!help':
$this->sendMessage('Available commands: !uptime', $this->ex[2]);
break;
}
break;
case '372':
case '375':
case '265':
case '255':
case '254':
case '003':
case '002':
echo $text;
break;
case '376':
/* Startup Commands */
$this->startup();
break;
case 'QUIT':
break;
default:
endswitch;
/* Handle Text From Telegram $telegram */
if (!$channels)
$channels = array(
'test chat'
);
foreach ($channels as $channel):
if (!$this->_tgData[$channel]):
$this->_tgData[$channel] = $this->telegram->getHistory($channel, 1);
$this->_tgData[$channel] = substr($this->_tgData[$channel], strpos($this->_tgData[$channel], ']')+3);
endif;
// fetch data
$this->_history[$channel] = $this->telegram->getHistory($channel, 1, 0);
$this->_history[$channel] = substr($this->_history[$channel], strpos($this->_history[$channel], ']')+3);
flush();
$b=0;
$output = array();
while (str_replace('>>>' , '', str_replace('»»»', '', str_replace('«««', '', str_replace('<<<', '', $this->_tgData[$channel])))) != str_replace('>>>' , '', str_replace('»»»', '', str_replace('«««', '', str_replace('<<<', '', $this->_history[$channel]))))):
// fetch data
$this->_history[$channel] = $this->telegram->getHistory($channel, 1, $b);
$this->_history[$channel] = substr($this->_history[$channel], strpos($this->_history[$channel], ']')+3);
flush();
if (preg_match("/(.+) [«><»]{3} (![\w\d]+) (.+)/", $this->_history[$channel], $matches)):
$username = substr(str_replace($channel, '', $matches[1]), 1);
$command = $matches[2];
$tokens = explode(' ', $matches[3]);
switch($command):
case '!uptime':
echo 'got here';
$this->telegram->msg($channel, $this->uptime());
endswitch;
endif;
$b++;
endwhile;
endforeach;
endwhile;
}
function sendMessage ($message, $to = false){
$this->send_data("PRIVMSG", (!$to?$this->ex[2]:$to) . " :" . $message);
}
/*
* Sends data to the server.
*/
function send_data($cmd, $msg = null){
if($msg == null){
fputs($this->socket, $cmd . "\n");
} else {
fputs($this->socket, $cmd.' '.$msg."\n");
}
}
function uptime () {
echo '------time-----';
$days = round((time() - $this->timestamp)/60/60/24);
$hours = round((time() - $this->timestamp)/60/60%24);
$minutes = round((time() - $this->timestamp)/60%60);
echo $this->timestamp;
echo '---time----';
return "I have been online for $days days, $hours hours and $minutes minutes";
}
}
$bot = new IRCBot($configure);
?>
したがって、コードの重要な部分は次のとおりです。
while (true): /*code*/ endwhile;
/* Fetch Data From Telegram Socket */
$this->telegram = new \Zyberspace\Telegram\Cli\Client('unix:///tmp/tg.sck');
/* Fetch Data From IRC Socket */
$data = fgets($this->socket, 1024);
flush();
データは IRC ソケットとテレグラム ソケットからフェッチされますが、この時点で IRC ソケットはデータを受信しているため、テレグラムはデータを受信するために追加の呼び出しを行う必要があります。下記参照。
$this->_tgData[$channel] = $this->telegram->getHistory($channel, 1);
$this->_tgData[$channel] = substr($this->_tgData[$channel], strpos($this->_tgData[$channel], ']')+3);
テレグラムはここでデータを取得します。
それで、私が考えることができるすべてをカバーしています。「この質問を友達に見せる」機能を使用するので、コードが多すぎるという投稿はやめてください。該当箇所は説明済みですので、ご安心ください。また、試してみると、コードをこれ以上短くすることはできませんでした。これは完全な例であり、テストするための環境を提供する準備ができています。この環境は、あなたまたはあなたが選択した慈善団体に寄付します.
また、注意してください: 誰かがタグ telegram-cli と telegram-cli-php を作成できますか? どちらもコミュニティにとって非常に有用なプロジェクトです。