κ°œλ°œκ΄€λ ¨/PHP

[PHP] ν…”λ ˆκ·Έλž¨ μ›Ήν›…(Webhook) μ‚¬μš©ν•˜μ—¬ μ‹€μ‹œκ°„ 체크 봇 λ§Œλ“€κΈ°! #4

🐻곰이🐻 2022. 11. 1.
728x90

μ•ˆλ…•ν•˜μ„Έμš” κ³°μ΄μ—μš”!

 

μ–΄μ œλŠ” μ›Ή ν›…κ³Ό 폴링에 λŒ€ν•΄μ„œ κ°œλ…μ„ μ •λ¦¬ν•˜λŠ” ν¬μŠ€νŒ…μ„ μ˜¬λ Έμ—ˆλŠ”λ°μš”!

 

μ˜€λŠ˜μ€ μ›Ή ν›… λ°©μ‹μœΌλ‘œ ν…”λ ˆκ·Έλž¨ 봇과 ν†΅μ‹ ν•˜λŠ” 법에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

 
 

μ€€λΉ„ν•΄μ•Ό ν•˜λŠ” 것

php μ„€μΉ˜κ°€ λ˜μ–΄μžˆλŠ” μ›Ήμ„œλ²„

μ›Ή ν›… 연결을 μœ„ν•œ callback url (도메인 μ—°κ²°λœ μ‚¬μ΄νŠΈκ°€ ν•„μš”) 1번과 μ—°κ²°λœ 도메인이 μ—¬μ•Ό ν•©λ‹ˆλ‹€.

 

μ €λŠ” NASκ°€ μžˆμ–΄μ„œ μ›Ήμ„œλ²„λΌλ˜μ§€ callback url을 μ‰½κ²Œ λ§Œλ“€ 수 μžˆμ—ˆλŠ”λ°μš”

 

μœ„μ˜ 쀀비물이 μ€€λΉ„κ°€ λ˜μ—ˆμœΌλ‹ˆ μ €λŠ” test_webhook.phpλΌλŠ” νŒŒμΌμ„ λ§Œλ“€μ–΄μ£Όκ² μŠ΅λ‹ˆλ‹€.

 

https://μžμ‹ μ˜ 도메인/test_webhook.php 이런 μ‹μœΌλ‘œ 접근이 되게 λ”μš”.

 

php μ†ŒμŠ€λŠ” μ•„λž˜ 접은 κΈ€λ‘œ ν‘œκΈ°ν•˜κ² μŠ΅λ‹ˆλ‹€. ν•„μš”ν•˜μ‹  뢄은 νŽΌμ³μ„œ μ°Έκ³ ν•΄μ£Όμ„Έμš” ^^

더보기
<?
	/**
	*   @comment
	*     - ν…”λ ˆκ·Έλž¨ μ›Ήν›… 방식 톡신
	*   @modified by   κ°œλ°œμ‰½κ²Œν•˜μžκ³°
	*   @modified      22.11.01
	**/

	//봇 api 토큰
	define('BOT_TOKEN', 'μžμ‹ μ˜ 봇 토큰');
	//api url
	define('API_URL', 'https://api.telegram.org/bot'.BOT_TOKEN.'/');
	//μ›Ήν›… μ£Όμ†Œ
	define('WEBHOOK_URL', API_URL.'setWebhook?url=μžμ‹ μ˜ 도메인/test_webhook.php/'.BOT_TOKEN);

	function exec_curl_request($handle) 
	{
		$response = curl_exec($handle);

		if ($response === false) {
			$errno = curl_errno($handle);
			$error = curl_error($handle);
			error_log("Curl returned error $errno: $error\n");
			curl_close($handle);
			return false;
		}

		$http_code = intval(curl_getinfo($handle, CURLINFO_HTTP_CODE));
		curl_close($handle);

		if ($http_code >= 500) 
		{
			// do not wat to DDOS server if something goes wrong
			sleep(10);
			return false;
		} 
		else if ($http_code != 200) 
		{
			$response = json_decode($response, true);
			error_log("Request has failed with error {$response['error_code']}: {$response['description']}\n");
			if ($http_code == 401) 
			{
				throw new Exception('Invalid access token provided');
			}
			return false;
		} 
		else 
		{
			$response = json_decode($response, true);
			if (isset($response['description'])) 
			{
				error_log("Request was successful: {$response['description']}\n");
			}
			$response = $response['result'];
		}
		 return $response;
	}

	function apiRequest($method, $parameters) 
	{
		if (!is_string($method)) 
		{
			error_log("Method name must be a string\n");
			return false;
		}

		if (!$parameters) 
		{
			$parameters = array();
		} 
		else if (!is_array($parameters)) 
		{
			error_log("Parameters must be an array\n");
			return false;
		}

		foreach ($parameters as $key => &$val) 
		{
			// encoding to JSON array parameters, for example reply_markup
			if (!is_numeric($val) && !is_string($val)) 
			{
				$val = json_encode($val);
			}
		}
		$url = API_URL.$method.'?'.http_build_query($parameters);

		$handle = curl_init($url);
		curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
		curl_setopt($handle, CURLOPT_TIMEOUT, 60);

		return exec_curl_request($handle);
	}

	function apiRequestJson($method, $parameters) 
	{
		if (!is_string($method)) 
		{
			error_log("Method name must be a string\n");
			return false;
		}

		if (!$parameters) 
		{
			$parameters = array();
		} 
		else if (!is_array($parameters)) 
		{
			error_log("Parameters must be an array\n");
			return false;
		}

		$parameters["method"] = $method;

		$handle = curl_init(API_URL);
		curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
		curl_setopt($handle, CURLOPT_TIMEOUT, 60);
		curl_setopt($handle, CURLOPT_POST, true);
		curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($parameters));
		curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));

		return exec_curl_request($handle);
	}

	function processMessage($message) 
	{
		// process incoming message
		if(is_array($message["message"]) == true) 
		{
			$message_id	= $message["message"]['message_id'];
			$chat_id	= $message["message"]['chat']['id'];
		}
		else if(is_array($message["channel_post"]) == true)
		{
			$message_id	= $message["channel_post"]['message_id'];
			$chat_id	= $message["channel_post"]['chat']['id'];
		}

		if(isset($message["message"]['text']) || isset($message["channel_post"]['text'])) 
		{
			// incoming text message
			if(is_array($message["message"]) == true) 
			{
				$text = $message["message"]['text'];
			}
			else if(is_array($message["channel_post"]) == true)
			{
				$text = $message["channel_post"]['text'];
			}
			if(strpos($text, "/start") === 0)
			{
				apiRequestJson("sendMessage", array('chat_id' => $chat_id, "text" => 'Hello', 'reply_markup' => array(
					'keyboard' => array(array('Hello', 'Hi')),
					'one_time_keyboard' => true,
					'resize_keyboard' => true)));
			}
			else if ($text === "Hello" || $text === "Hi")
			{
				apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'Nice to meet you'));
			}
			else 
			{
				apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'Cool'));
			}
		}
		else 
		{
			apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'No.'));
		}
	}

	if (php_sapi_name() == 'cli') 
	{
		// if run from console, set or delete webhook
		apiRequest('setWebhook', array('url' => isset($argv[1]) && $argv[1] == 'delete' ? '' : WEBHOOK_URL));
		exit;
	}

	$content = @file_get_contents("php://input");
	$update = json_decode($content, true);
	if(!$update) 
	{
		exit;
	}

	if(isset($update)) 
	{
		processMessage($update);
	}

	exit;
?>

μœ„μ²˜λŸΌ php νŒŒμΌμ„ λ§Œλ“€μ–΄μ£Όκ³  봇 토큰과 κ°€μž₯ μ€‘μš”ν•œ webhook μ„€μ •μΈλ°μš”.

 

μ›Ή ν›… μ„€μ • url은 

 

https://api.telegram.org/bot{봇토큰}/setWebhook?url={μžμ‹ μ˜λ„λ©”μΈ}/bot_webhook.php/{봇토큰} 

 

이런 μ‹μœΌλ‘œ μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

μ €μ˜ 봇 토큰은 5695678451:AAEBBcGX3ZWCQG248E2Reo1x6HKqlc-IiDM μž…λ‹ˆλ‹€.

 

λŒ€μž…μ„ ν•˜λ©΄

 

https://api.telegram.org/bot5695678451:AAEBBcGX3ZWCQG248E2Reo1x6HKqlc-IiDM/setWebhook?url={μžμ‹ μ˜λ„λ©”μΈ}/bot_webhook.php/5695678451:AAEBBcGX3ZWCQG248E2Reo1x6HKqlc-IiDM 

 

μ΄λ ‡κ²Œ λ˜κ² λ„€μš” μžμ‹ μ˜ λ„λ©”μΈμ΄λΌλŠ” κ³³μ—λŠ” μ•„κΉŒ μœ„μ—μ„œ λ§μ”€λ“œλ Έλ‹€μ‹œν”Ό php 파일과 μ—°κ²°λœ 도메인이어야 ν•©λ‹ˆλ‹€.

 

그럼 μ›Ή 훅을 μ„€μ •ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

μ •μƒμ μœΌλ‘œ μ›Ή 훅이 μ„€μ •λ˜μ—ˆλ‹€κ³  ν•©λ‹ˆλ‹€.

 

μ΄μ œλΆ€ν„° 이 봇은 저와 λŒ€ν™”λ₯Ό ν•  수 μžˆλŠ” 봇이 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

 

function processMessage($message) 
	{
		// process incoming message
		if(is_array($message["message"]) == true) 
		{
			$message_id	= $message["message"]['message_id'];
			$chat_id	= $message["message"]['chat']['id'];
		}
		else if(is_array($message["channel_post"]) == true)
		{
			$message_id	= $message["channel_post"]['message_id'];
			$chat_id	= $message["channel_post"]['chat']['id'];
		}

		if(isset($message["message"]['text']) || isset($message["channel_post"]['text'])) 
		{
			// incoming text message
			if(is_array($message["message"]) == true) 
			{
				$text = $message["message"]['text'];
			}
			else if(is_array($message["channel_post"]) == true)
			{
				$text = $message["channel_post"]['text'];
			}
			if(strpos($text, "/start") === 0)
			{
				apiRequestJson("sendMessage", array('chat_id' => $chat_id, "text" => 'Hello', 'reply_markup' => array(
					'keyboard' => array(array('Hello', 'Hi')),
					'one_time_keyboard' => true,
					'resize_keyboard' => true)));
			}
			else if ($text === "Hello" || $text === "Hi")
			{
				apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'Nice to meet you'));
			}
			else 
			{
				apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'Cool'));
			}
		}
		else 
		{
			apiRequest("sendMessage", array('chat_id' => $chat_id, "text" => 'No.'));
		}
	}

접은 μ†ŒμŠ€ μ€‘μ—μ„œ processMessageλΌλŠ” ν•¨μˆ˜κ°€ μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

 

μ—¬κΈ°μ„œ μ œκ°€ μž…λ ₯ν•  말을 λ°›μ•„μ„œ μ–΄λ–»κ²Œ 닡을 ν•΄μ€˜μ•Ό ν•˜λŠ”μ§€ μ ν˜€μžˆλŠ”λ°μš”.

 

μ €λŠ” μš°μ„  /startλΌλŠ” λͺ…λ Ήμ–΄λ₯Ό μž…λ ₯ν•˜λ©΄ 

 

봇은 hello ν•˜λ©΄μ„œ μ €μ—κ²Œ 인라인 λ²„νŠΌ 두 개λ₯Ό 주게 λ©λ‹ˆλ‹€.

 

Hello와 HiλΌλŠ” κ°’μœΌλ‘œμš” 눈으둜 직접 λ³΄μ‹œμ£ .

 

μ–΄λ•Œμš”?? ν™•μ‹€νžˆ μ‹€μ‹œκ°„μœΌλ‘œ λ°˜μ‘μ„ ν•©λ‹ˆλ‹€.

 

그럼 μ œκ°€ HelloλΌλŠ” λ²„νŠΌμ„ 클릭해 λ³Όκ²Œμš”. 그럼 봇은 Nice to meet youλΌλŠ” 값을 주도둝 μ„€μ •λ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€.

 

이런 μ‹μœΌλ‘œ λ°”λ‘œλ°”λ‘œ μ œκ°€ λ΄‡μ—κ²Œ μž…λ ₯받을 수 μžˆλŠ” 값을 μ£Όμ—ˆμ„ λ•Œ 봇은 μ €μ—κ²Œ μ„€μ •λœ κ°’μœΌλ‘œ μ‘λ‹΅ν•˜κ²Œ λ©λ‹ˆλ‹€.

 

값을 응닡을 λͺ» λ°›κ²Œ μ„€μ •ν•˜λ©΄ Coolμ΄λΌλŠ” 값을 μ €μ—κ²Œ 주게 λ©λ‹ˆλ‹€.

 

이제 여기에 심화과정을 λ”ν•˜κ²Œ λœλ‹€λ©΄ λΉ„λ‘œμ†Œ ν™œμš©μ„± λ†’κ³  멋진 봇이 νƒ„μƒν•˜κ² μ£  γ…Žγ…Ž

 

μ•„λž˜λŠ” μ œκ°€ μ‹¬μ‹¬ν•΄μ„œ λ§Œλ“€κ³  μžˆλŠ” 날씨 λ΄‡μž…λ‹ˆλ‹€.

그밖에도 λΉ„νŠΈμ½”μΈ μ‹œμ„Έ μ•Œλ¦Ό 봇도 μžˆμ–΄μš” γ…Žγ…Ž 아직 ν•œμ°Έ λ¬Όλ €μžˆμ–΄μ„œ γ…œγ…œ

μ„€μ •ν•œ κ°€κ²©λŒ€μ— λ„λ‹¬ν•˜λ©΄ 1λΆ„λ§ˆλ‹€ μ•Œλ¦Όμ΄ 계속 μ˜€κ²Œλ” λ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€.

 

μ›Ή 훅을 μ¨λ³΄μ•˜λŠ”λ°μš” 이제 μ €μ˜ 봇 토큰은 μ‚­μ œν•  μ˜ˆμ •μž…λ‹ˆλ‹€.

 

μ›λž˜ 봇 토큰은 유좜되면 μ•ˆ λ˜κΈ°μ— ν¬μŠ€νŒ…μ„ μœ„ν•΄ 잠깐 λ™μ•ˆ λ§Œλ“  κ±°λΌμ„œμš” γ…Žγ…Ž

 

이상 ν¬μŠ€νŒ…μ„ λ§ˆμΉ˜λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€ κΈ΄ κΈ€ μ½μ–΄μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€!

λ°˜μ‘ν˜•

λŒ“κΈ€