분류 php

PHP로 텔레그램 봇 구축

컨텐츠 정보

  • 조회 152 (작성일 )

본문

Telegram은 현재 메시징 앱 시장에서 멋진 두 아이 중 하나입니다. 특히 최근 WhatsApps의 새로운 데이터 공유 정책에 화가 난 이후 사용자 수가 긍정적으로 치솟았습니다. 현재 5 억 명이 넘는 사람들이 앱을 사용하고 있습니다.


개인적으로 저는 2015 년부터 사용하고 있습니다. 2018 년부터는 일상 커뮤니케이션의 95 %에 사용했습니다. 그 동안 Telegram에 정말 멋진 Chat Bot API가 있다는 것도 알게 되었습니다! 그래서 몇 개를 만들었습니다.

  • 하나는 내 약속을 추적하고 미리 알림을 보냅니다.
  • 내 친구 채팅 그룹의 배송 목표를 추적합니다.
  • 그룹에서 누가 가장 놀렸는지 확인한 사람
  • 내 회사의 일부 메트릭을 추적하는 것 (잠재 고객 증가 등)

오늘은 어떻게 하는지 가르쳐 드리고자 합니다. 우리 모두가 자동화 된 채팅 로봇의 개인 군대가 있는 미래는 확실히 제가 살고 싶은 것이기 때문입니다!


전제 조건 


이 기사를 따르려면 두 가지만 필요합니다.


  • PHP 7.2+ 및 Composer의 작동 설치
  • Telegram 앱 및 계정

봇을 만들려면 Telegram 자체의 특별한 토큰이 필요합니다. 우리는 자동화 된 봇에서도 이것을 얻을 수 있습니다! @BotFather라고 하며 설정 프로세스를 안내합니다. 이제 그렇게 합시다!


Setup process with BotFather 


축하합니다! 첫 번째 Telegram 봇을 설정했습니다. 마지막 메시지에서 해당 토큰을 기록해 두십시오. 몇 분 안에 필요합니다. 프로필 이미지 등을 사용하여 봇을 추가로 사용자 지정할 수도 있습니다. 나는 당신에게 맡길 것입니다.


PHP 프로젝트 설정 


이제 이 프로젝트의 실제 핵심 인 채팅 봇 구현에 대해 알아볼 시간입니다. $ CURRENT_YEAR의 좋은 PHP 프로젝트와 마찬가지로 Composer 프로젝트를 설정하여 시작할 것입니다.


$ composer init 


Telegram의 HTTP API를 직접 처리 할 수 ​​있지만 Irfaq Sayed가 우리를 위해 이미 구축 한 매우 멋진 라이브러리가 있습니다. 그래서 그것도 잡자!


$ composer require irazasyed/telegram-bot-sdk 


그런 다음 디렉토리 구조를 정의 할 때입니다. Telegram 봇을 만들 때 일반적으로 다음과 같은 구조를 따릅니다.


chat-bot/ ├─ composer.json ├─ composer.lock ├─ vendor/ ├─ src/ ├─ public/ ├─ .env ├─ bootstrap.php ├─ helpers.php ├─ setup.php 


먼저 Composer에서 생성 한 일반 파일이 있습니다.


  • src /는 모든 명령과 기타 애플리케이션 별 코드를 배치하는 폴더입니다.
  • public /에는 인터넷의 무서운 현실에 노출되는 코드가 포함될 것입니다.
  • bootstrap.php는 자동 로더를 포함하고 .env 파일에서 변수를 로드하는 것과 같은 몇 가지 사항을 설정합니다. 우리는 그것을 많이 포함 할 것입니다.
  • helpers.php에는 일반적으로 다른 곳에 맞지 않는 작은 유틸리티 함수가 포함되어 있습니다.
  • 마지막으로 setup.php는 Telegram과의 연결을 설정하는 데 도움이 되는 작은 파일입니다.

이제 이전에 BotFather에서 받은 토큰을 복사하여 .env 파일에 넣을 수 있습니다.


# .env TELEGRAM_BOT_TOKEN="1234567890:YOUR_TOKEN" 


원하는 대로 이름을 지정할 수 있습니다. 내가 선택한 이름은 라이브러리의 기본값입니다.


이 설정 순서를 마무리하기 위해 남은 것은 오토로더를 설정하는 것입니다. 이를 위해 composer.json을 수정하고 다음을 추가합니다.


"autoload": { "psr-4": { "Pretzel\\": "src/" }, "files": [ "helpers.php" ] } 


다시 말하지만, 네임 스페이스는 원하는 대로 지정할 수 있습니다. 자기 중심적 일 필요는 없습니다.


변경 사항은 기본적으로 다음과 같이 요약됩니다. src /에서 Pretzel 네임 스페이스로 모든 것을 로드 하고 helpers.php 파일도 구체적으로로드하십시오.


이제 마침내 PHP 프로젝트를 시작할 준비가 되었습니다!


Telegram과의 연결 설정 


Telegram은 이벤트 기반 시스템과 함께 작동하여 새 업데이트가 도착하면 알려줍니다. 이를 위해 웹훅 핸들러를 설정해야 합니다. 현실 세계에서 이것은 누군가가 우리 봇에 메시지를 보낼 때마다 Telegram이 요청을 보내는 PHP 파일입니다. 공상!


먼저 봇의 토큰이 필요합니다. 그것이 우리가 Telegram에 우리가 누구인지 식별하는 방법입니다. 기억 하시겠지만 우리는 그것을 .env 파일에 넣었습니다. 그럼 여기서 로딩 변수를 설정해 봅시다.


$ composer require vlucas/phpdotenv 


그런 다음 bootstrap.php에 다음을 추가합니다.


// bootstrap.php <?php require __DIR__ . "/vendor/autoload.php"; $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); $dotenv->load(); 



짧고 달콤한 스니펫 덕분에 이제 env() 함수를 사용하여 .env 파일에서 값을 쉽게 가져올 수 있습니다. 이것은 기본 PHP 기능이 아니지만 Telegram Bot SDK는 이를 종속성으로 제공합니다.


다음으로 helpers.php에 작은 도우미 함수를 설정하고 싶습니다.


// helpers.php <?php function telegram(): \Telegram\Bot\Api { return new \Telegram\Bot\Api( env('TELEGRAM_BOT_TOKEN') ); } 


이것은 순전히 편의를 위한 것입니다. 이를 통해 .env 파일을 다시 쿼리 할 필요 없이 Telegram API 래퍼의 인스턴스를 가져올 수 있습니다. 이제 setup.php 파일에서 이 두 가지를 결합 할 수 있습니다.


// setup.php <?php require 'bootstrap.php'; telegram()->setWebhook(['url' => env('TELEGRAM_WEBHOOK')]); echo "Setup the Telegram webhook!"; 


이런 것들이 telegram() 도우미가 유용한 이유입니다.


당신의 말을 보유. 날카로운 눈을 가진 독자는 .env 파일에서 TELEGRAM_WEBHOOK을 얻고 있음을 알 수 있습니다. 아직 없죠? 


Telegram이 업데이트를 보낼 수 있는 일종의 URL을 전달해야 합니다. localhost에서 어떻게 할까요? 물어봐서 기뻐요. 2021 년에 PHP 개발자가 된다는 것은 멋진 경험이므로 이를 위한 완벽한 도구가 있습니다. 노출이라고 부르며 BeyondCode에서 제작했습니다.


참고 : 다른 옵션도 있습니다. ngrok과 같은 것이 잘 작동합니다. 설정이 쉽고 사용자 지정 하위 도메인을 무료로 제공하기 때문에 노출을 좋아합니다.


로컬 웹훅 설정 


로컬 환경에 대한 URL을 가져 오기 시작하려면 먼저 expose를 설치합니다.


$ composer global require beyondcode/expose 


이렇게 하면 전체적으로 노출 유틸리티가 설치되고 액세스 권한이 부여됩니다. 한동안 Composer를 사용하고 있다면 이미 그렇게 했지만 composer 전역 구성 bin-dir --absolute가 $ PATH에 있는지 확인하십시오.


다음으로 어떻게 든 PHP를 실행해야 합니다. 이와 같은 프로젝트의 경우 통합 PHP 웹 서버가 좋습니다. 따라서 프로젝트의 루트 디렉토리에서 다음을 사용하여 실행할 수 있습니다.


$ php -S localhost:8080 -t public [Mon Jan 18 11:28:18 2021] PHP 8.0.0 Development Server (http://localhost:8080) started 


그런 다음 다른 터미널 탭을 열고 다음을 실행하십시오.


$ expose share localhost:8080 --subdomain=pbbot 


하위 도메인 옵션은 원하는 대로 지정할 수 있습니다. "hunky-dory"라는 이름도 지정할 수 있습니다.


끝 부분의 결과 출력에서 ​​sharedwithexpose.com으로 끝나는 URL을 찾아야 합니다. 제 경우에는 pbbot.sharedwithexpose.com이고 이것이 필요한 URL입니다. 


더 인체 공학적으로 만들기 (선택 사항) 


한 번에 두 개의 다른 터미널 탭을 실행하는 것은 번거롭습니다. 이제 ✨magical Composer 스크립트 ✨를 사용하여 봇의 속도를 높이기 위해 하나의 명령 만 실행하면 됩니다. 쉘의 & 기능을 사용하여 두 가지를 동시에 실행할 수 있습니다. 따라서 이것을 composer.json에 추가 할 수 있습니다.


"scripts": { "dev": "php -S localhost:8080 -t public &>/dev/null & expose share localhost:8080 --subdomain=pbbot" } 


원하는 대로 하위 도메인과 포트를 조정합니다.


&> / dev / null 항목은 원래 PHP 웹 서버의 출력이 노출과 엉망이 되지 않도록 합니다. 노출은 우리에게 멋진 요청 개요를 제공하기 때문에 어쨌든 필요하지 않습니다. 이제 단일 명령을 실행할 수 있으며 봇이 활성화됩니다!


$ composer run dev 


이제 웹훅 URL을 .env 파일에 추가 할 수 있습니다.


# .env TELEGRAM_BOT_TOKEN="1234567890:YOUR_TOKEN" TELEGRAM_WEBHOOK="https://pbbot.sharedwithexpose.com/webhook.php" 


URL * 반드시 *는 HTTPS 여야 합니다. 보안과 그 모든 것.


webhook.php는 Telegram에서 들어오는 모든 요청을 처리하는 데 사용하는 파일입니다. 다음 단계에서 만들 것입니다. 먼저 간단한 setup.php 스크립트를 실행하겠습니다.


$ php setup.php Setup the Telegram webhook! 


웹훅 핸들러 설정 


그래서 우리는 Telegram에게 webhook.php에 정보를 보내 달라고 말했지만 아직 해당 파일이 없습니다. public / 폴더에 생성합니다. 웹훅 핸들러는 기본적으로 처리되지 않은 업데이트를 가져와 봇에 전달하고 결과를 Telegram에 반환하는 역할을 합니다. 다음과 같이 보입니다.


// public/webhook.php <?php require __DIR__ . '/../bootstrap.php'; telegram()->commandsHandler(true); 


이제 Telegram Bot SDK가 유용한 이유를 알 수 있을 것 같습니다. 전체 명령 시스템을 설정하기 위해 하나의 함수 만 호출해야 한다는 사실은 매우 유용하고 생산성을 높게 유지합니다!


첫 번째 명령 작성 


이제 모든 성가신 설정 작업을 완료 했으므로 첫 번째 명령을 작성할 수 있습니다. 상상할 수 있는 가장 기본적인 명령부터 시작해 보겠습니다. 봇에게 / hello라고 말하면 Hello World가 다시 우리에게 전달되기를 원합니다.


먼저 명령에 대한 새 클래스를 만들어야 합니다. src / Commands / HelloCommand.php에 넣어서 Pretzel \ Commands \ HelloCommand 클래스를 통해 액세스 할 수 있습니다. 우리가 만드는 모든 명령은 Bot SDKs 기본 클래스에서 상속해야 합니다. 또한 이름이 필요합니다. 따라서 기본 구조는 다음과 같습니다.


// src/Commands/HelloCommand.php <?php namespace Pretzel\Commands; use Telegram\Bot\Commands\Command; class HelloCommand extends Command { protected $name = 'hello'; public function handle() { // TODO: Implement command } } 


이제 handle() 함수 내에서 방금 받은 메시지에 응답하는 데 사용할 수 있는 다양한 replyWith * 유형 함수에 액세스 할 수 있습니다. 가장 쉬운 방법은 replyWithMessage를 사용하는 것입니다.


Suggestion box showing all replyWith* functions 


이 함수는 모두 배열 형태의 인수를 취합니다. 나는 그들 모두를 마음으로 말할 수도 없습니다. 고맙게도 좋은 문서가 있습니다! 함수에 전송해야 하는 내용을 찾으려면 API 메서드 문서에서 검색하면 됩니다. 더 자세한 정보는 공식 Telegram 문서를 적극 권장합니다.


각 send * 함수는 replyWith * 함수 중 하나에 해당합니다.


이 replyWith * 함수가 수행하는 중요한 것은 인수에 chat_id 매개 변수를 추가하는 것입니다. 그래서 우리는 그것을 무시할 수 있습니다. 필요한 다른 매개 변수는 텍스트입니다. 이름에서 알 수 있듯이 메시지 텍스트를 포함해야 합니다.


이제 우리 수업은 다음과 같이 보일 것입니다.


// src/Commands/HelloCommand.php <?php namespace Pretzel\Commands; use Telegram\Bot\Commands\Command; class HelloCommand extends Command { protected $name = 'hello'; public function handle() { $this->replyWithMessage([ 'text' => 'Hello World!' ]); } } 



이것은 PHP 8에서 명명 된 인수에 대한 놀라운 사용 사례가 될 것입니다!


봇에 등록 


이제 이 명령을 봇에 등록해야 하므로 실제로 사용할 수 있는 명령을 알 수 있습니다. 이를 위해 bootstrap.php 파일로 돌아가서 다음을 추가합니다.


// bootstrap.php telegram()->addCommands([ Pretzel\Commands\HelloCommand::class, ]); 


명령의 네임 스페이스는 물론 다릅니다.


이제 이 작업을 완료 했으므로 봇과 상호 작용할 수 있습니다! Telegram에서 봇과의 채팅을 열고 / hello 명령을 보내십시오. 즉시 응답해야 합니다!


Bot saying "Hello World" 


인수 작업(Working with arguments) 


물론 명령은 인수를 보낼 수 있을 때 훨씬 더 흥미롭습니다. 친구를 맞이하고 싶다고 해! 그들의 이름을 어떻게 전달합니까?


이를 위해 우리가 상속 받은 Command 클래스는 $pattern 속성을 제공합니다. 여기에서 {this}와 같은 중괄호로 명명 된 인수를 사용하거나 사용자 지정 정규식을 전달할 수 있습니다.


// src/Commands/HelloCommand.php class HelloCommand extends Command { protected $pattern = '{name}'; // Our argument is called 'name' protected $pattern = '{name}?'; // We have an optional argument called 'name' protected $pattern = '.+' // We'll take in any argument with 1 or more characters. It'll be called 'custom' // .. SNIP .. } 


따라서 봇이 사람을 받는 경우 이름으로 사람을 맞이하기를 원한다고 가정 해 보겠습니다. 그렇지 않으면 모든 사람이 가끔씩 인사를 해야 하기 때문에 우리는 세상을 인사합니다. 이를 위해 $ pattern을 {name}?으로 설정합니다.


그런 다음 handle() 함수에서 미리 제공된 $ arguments 속성을 가져올 수 있습니다.


// src/Commands/HelloCommand.php <?php class HelloCommand extends Command { protected $name = 'hello'; protected $pattern = '{name}?'; public function handle() { $arguments = collect($this->arguments); // .. SNIP .. } } 


보시다시피 인수를 가져올 때 collect 함수를 사용했습니다. 이것은 Laravel 세계의 또 다른 아름다운 것이며 Bot SDK가 가져 왔습니다. 컬렉션은 기본적으로 훨씬 더 깔끔하게 작업 할 수 있는 강력한 PHP 배열입니다.


물론 $arguments 배열을 직접 처리 할 수도 있지만 저는 이 방법을 매우 선호합니다.


이제 인수에서 이름 키를 가져 오거나 없는 경우 기본값을 반환 할 수 있습니다. 그런 다음이 인수를 문자열에 삽입하고 사용자에게 다시 보냅니다. 이렇게 생겼어요


// src/Commands/HelloCommand.php <?php class HelloCommand extends Command { protected $name = 'hello'; protected $pattern = '{name}?'; public function handle() { $arguments = collect($this->arguments); $this->replyWithMessage([ 'text' => sprintf( 'Hello %s!', $arguments->get('name', 'World') ) ]); } } 


명령을 저장 한 후 즉시 시도 할 수 있습니다! 봇으로 이동하여 / hello <YOUR_NAME>을 (를) 보내세요. 기계적으로 설계된 행복으로 인사하는 모습을 지켜보세요!


Bot greeting user by name 


Sending unprompted messages 


물론 봇은 사용자가 요청할 때만 응답하는 경우에만 사용이 제한됩니다. 운 좋게도 사전 명령 없이 메시지를 보낼 수도 있습니다. 우리가 그렇게 느끼기 때문입니다. 이를 위해서는 메시지를 보내려는 사람의 chat_id 또는 메시지를 보낼 그룹의 @username이 필요합니다.


개인 chat_id를 찾으려면 @RawDataBot에게 연락하면 첫 번째 메시지에서 알려줄 것입니다.


Raw Data Bot showing information about a private message 


@username이 없는 비공개 그룹이 있는 경우 그룹에 @RawDataBot을 추가하여 그룹의 chat_id를 찾을 수도 있습니다. 음수가 됩니다.


Raw Data Bot showing information about a group message 


그런 다음 Telegram API 개체의 sendMessage 함수를 사용할 수 있습니다. 데모로 webhook을 성공적으로 설정했다는 메시지를 setup.php에 추가해 보겠습니다.


// setup.php <?php require 'bootstrap.php'; $telegram = telegram(); $telegram->setWebhook(['url' => env('TELEGRAM_WEBHOOK')]); $telegram->sendMessage([ 'chat_id' => env('PRETZELHANDS_CHAT_ID'), 'text' => 'Successfully set up webhook' ]); 


Processing raw messages without commands 


일부 봇의 경우 Telegram이 제공하는 원시 정보를 사용하여 명령 없이 전송 된 메시지를 처리 ​​할 수 ​​있습니다. 이것은 다시 한번 상대적으로 쉽습니다. 명령 시스템을 통과 한 후 SDK는 웹훅 핸들러에서 업데이트 객체를 제공합니다. 그런 다음 이를 사용하여 무엇이든 할 수 있습니다!


// public/webhook.php <?php <?php require __DIR__ . '/../bootstrap.php'; $updates = telegram()->commandsHandler(true); // Telegram\Bot\Objects\Update Object( // [items:protected] => Array( // [update_id] => 290647531 // [message] => Array( // [message_id] => 81 // [from] => Array( // [id] => 0000000000 // [is_bot] => // [first_name] => Richard // [last_name] => Blechinger // [username] => pretzelhands // [language_code] => en // ) // // [chat] => Array( // [id] => 00000000000 // [first_name] => Richard // [last_name] => Blechinger // [username] => pretzelhands // [type] => private // ) // // [date] => 1610977759 // [text] => abc // ) // ) // ) 


이 업데이트의 모든 속성에 직접 액세스 할 수 있습니다. 따라서 $ update-> message-> text를 사용하여 관련 메시지 텍스트 등을 가져올 수 있습니다.


이것은 사용자 메시지에서 직접 날짜 및 이벤트 정보를 구문 분석하기 위해 다른 봇에서 사용한 프로세스입니다. 자연어 날짜를 구문 분석하는 것이 고통스럽다는 사실을 제외하고는 훌륭하게 작동합니다!


Deployment 


이 설정을 위한 배포는 이전에 다른 PHP 배포를 처리 한 적이 있는 사람이라면 누구나 간단해야 합니다. 그렇게 하는 것은 독자를 위한 연습 문제로 남겨 두었지만, 세 가지 요점으로 요약됩니다.

  • 서버에 파일 푸시
  • 웹 서버가 public /
  • setup.php를 사용하여 webhook URL을 yourdomain.com/webhook.php로 업데이트합니다.

마무리 생각 


이 기사는 어떤 목적으로든 자신의 Telegram 봇을 작성하기 시작하기에 충분한 개요를 제공했을 것입니다. 이제부터 가능성은 대부분 당신이 상상할 수 있는 것으로 제한됩니다.


내 메인 봇은 현재 뉴스 레터 성장, 트위터 성장을 추적하고, Notebag의 수명주기 동안 일일 수입량을 추적했습니다. 내 사이드 ​​프로젝트 생활이 어떻게 진행되고 있는지 알려주는 작은 일일 대시 보드와 같습니다. 두 번째 봇은 내가 정시에 가지고 있는 모든 약속에 표시되도록 합니다.


이 프로젝트의 코드는 GitHub에서도 사용할 수 있습니다.


https://pretzelhands.com/posts/build-a-telegram-bot-in-php