Simple Telegram chat bot
Post ReplySimple Telegram chat botPosted: Sunday, November 14, 2021 [07:12:05] - 1
Lets' skip Telegram bot creation steps. Please refer to the Telegram website for that: core.telegram.org/bots This bot settings: Privacy: disabled Administrative privileges: administrator Bot mode: webhook Bot is set on the office Mac Mini with static IP and domain web address VIA Cloudflare proxy and SSL settings. Response time is within one second which is very good for a free settings and no monthly fees. |
Telegram chat bot codePosted: Sunday, November 14, 2021 [07:17:12] - 2
This code was written in two hours flat with coffee breaks, so it may (or may not) include some flaws. Use it at your own risk! #!/opt/local/bin/perl # This software is free under AL/GPL, copyright (c) 2021 CodeMacs.com # You can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. # Use it at your own risk! # Prerequisites: curl use strict; use warnings; print "Content-type: text/txt\n\n"; ## Throw text MIME my $domain_root = '/path_to_data/folder'; ## Path to the data stored my $datacr=''; my $tdata=''; ## Get Token from remote machine using passwordless access #my $tagis = `ssh user@server_IP '/bin/cat /path_to_file/token.cgi'`; ## Get Token from local file #my $tagis = `/bin/cat /path_to_file/token.cgi`; ## Embed Token into the program my $tagis='1234567890:CGF90DaKIud4lk1eOElEchi3TEBppCDddrb'; # Get JSON data and convert it to hash if($ENV{'CONTENT_LENGTH'}) {read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); $datacr=$buffer; $datacr =~ s/^\{+//; $datacr =~ s/^\s+//; $datacr =~ s/\}$//; $datacr =~ s/\015/\n/g; $datacr =~ tr/\n\n//s; $datacr =~ s/(\n)(\s{2})/\n/g; $datacr =~ s/ /SP/g; $datacr =~ s/(\:)(\{)/ \=\> $2/g; $datacr =~ s/\s+$//; $datacr =~ s#(http|https)(\,)#$1\:#gi; $datacr =~ s/\$/\\\$/g; $datacr =~ s/\"/\'/g; # Replace double quotes to a single quotes to protect hex data if($datacr =~ m/\\u\w{4}/) { $origstr=$datacr; $origstr =~ s/\'/\\\'/g; } } ## END DATA PRESENT else {print "Thank you!\n"; print "received\n"; my @initqu=(); my @initqu; # Create buttons foreach my $q (@initqu) {$questions.= "$comma\[\"$q\"\]"; my $utime=time; unless(-d "$domain_root/data") {`mkdir -p $domain_root/data`; unless(-d "$domain_root/chats") {`mkdir -p $domain_root/chats`; # Write data to a file open(MESS,">$domain_root/data/$utime.txt"); print MESS "\%messdata=($datacr);$origstr"; our %messdata=(); eval {require "$domain_root/data/$utime.txt"}; if($messdata{message}{from}{is_bot} eq 'false') { my $chatid = $messdata{message}{chat}{id}; my $messageid = $messdata{message}{message_id}; my $nameid = $messdata{message}{from}{id}; my $name = "$messdata{message}{from}{first_name} $messdata{message}{from}{last_name}"; my $posted = $messdata{message}{date}; my $message = $messdata{message}{text}; $messdata{message}{text} =~ s/\W//g; # Convert foreign language characters if($origstr && $message =~ m/\\u\w{4}/) { $message =~ s#\\u(\w{4})#chr(hex $1)#eg;} if($origstr && $messdata{message}{from}{first_name} =~ m/\\u\w{4}/) { $messdata{message}{from}{first_name} =~ s#\\u(\w{4})#chr(hex $1)#eg; $messdata{message}{from}{last_name} =~ s#\\u(\w{4})#chr(hex $1)#eg; $name =~ s#\\u(\w{4})#chr(hex $1)#eg; } if($messdata{message}{new_chat_participant}) { ## NEW USER JOINED THE CHAT ######################### # Throw a Welcome greeting to a new user my $trepl = "$messdata{message}{from}{first_name}, Welcome to $messdata{message}{chat}{title}!\n"; $trepl = "Type the word \"Help\" and send it at any point to get a quick answer."; $trepl =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg; `/opt/local/bin/curl 'https://api.telegram.org/bot$tagis/sendMessage?chat_id=$chatid\&text=$trepl'`; sleep(2); # Throw a quick access buttons $tdata='{"text":"Please feel free to ask any questions or click on a button below.","chat_id":'.$chatid.',"reply_markup":{"keyboard":['.$questions.'],"one_time_keyboard":true,"resize_keyboard":true}}'; `/opt/local/bin/curl -H 'content-type: application/json' -d '$tdata' 'https://api.telegram.org/bot$tagis/sendMessage'`; # Send Growl message to a local workstation (optional) #sendgrowl($name,$messdata{message}{chat}{title},$posted,'joined'); exit(0); ## There is no message from user - just exit } ## END NEW USER JOINED THE CHAT ################################################################## elsif($messdata{message}{left_chat_member}) { ## USER LEFT CHAT ################################# # Nothing to do here except sending a Growl message (optional) #sendgrowl($name,$messdata{message}{chat}{title},$posted,'left'); exit(0); } ## END USER LEFT CHAT ######################################################################### elsif($messdata{message}{reply_to_message}) { ## CLICK ON A BUTTON #### if($subquestion{$message}{1}) { doreplyqu($messdata{message}{from}{first_name},$messdata{message}{from}{last_name},$chatid,$message); } ## END PROPER QUESTION else { ## BAD QUESTION my $trepl = "Unfortunately I don't have an answer to your question\n\"$message\""; $trepl =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg; `/opt/local/bin/curl 'https://api.telegram.org/bot$tagis/sendMessage?chat_id=$chatid\&text=$trepl'`; exit(0); } ## END BAD QUESTION } ## END CLICK ON A BUTTON ############################################ elsif($messdata{message}{text} eq 'help') { # If "Help" requested - print quick keyboard buttons my $tdatahlp='{"text":"Please click appropriate button below","chat_id":'.$chatid.',"reply_markup":{"keyboard":['.$questions.'],"one_time_keyboard":true,"resize_keyboard":true}}'; `/opt/local/bin/curl -H 'content-type: application/json' -d '$tdatahlp' 'https://api.telegram.org/bot$tagis/sendMessage'`; exit(0); } ## END HELP REQUESTED # If actual message sent by the user - send a reply if($messdata{message}{text}) { sendreply($chatid,$messageid,$nameid,$name,$posted,$message); } ## END IF MESSAGE PRESENT } ## END NOT BOOT exit(0); ## Program finished - exit sub sendreply { my($chatid,$messageid,$nameid,$name,$posted,$message)=@_; if(-f "$domain_root/chats/$nameid.txt") {eval {require "$domain_root/chats/$nameid.txt"};} ## END CHAT WITH PERSON PRESENT if($nameid eq 'Your_user_ID') { # Used for debugging purpose - comment after deployement # # # # } ## END END SENT FROM US else { ## Throw immediate answer to the first message from the new user unless(-f "/path_to_scrap_folder/init.chat.done.$nameid") {`touch /path_to_scrap_folder/init.chat.done.$nameid`; my @initrpl = ('Just a moment..','One minute please','One moment','Be right back','Hold on please'); randomarrs ( \@initrpl ); $reply .= "\nWe will try to answer your question personally ASAP"; } ## END UNLESS ALREADY REPLIED } ## END SENT FROM OTHER PERSON if($reply) { $origchat{$posted}{reply}=$reply; $reply =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg; `/opt/local/bin/curl 'https://api.telegram.org/bot$tagis/sendMessage?chat_id=$chatid\&text=$reply'`; } # Write a chat log if needed my $ptstime=localtime($posted); $origchat{$posted}{postime}=$ptstime; $origchat{$posted}{chatid}=$chatid; $origchat{$posted}{messageid}=$messageid; $origchat{$posted}{name}=$name; $origchat{$posted}{posted}=$posted; $origchat{$posted}{message}=$message; open(TXS,">$domain_root/chats/$nameid.txt"); foreach my $ut (sort numbr keys (%origchat)) { print TXS "$cma'$ut'=>{\n"; foreach my $k (sort keys %{$origchat{$ut}}) {$origchat{$ut}{$k} =~ s/\'/\\\'/g; unless($origchat{$ut}{$k}) {next;} print TXS "$cma1'$k','$origchat{$ut}{$k}'"; } ## FOREACH KEY END print TXS "\n}"; } ## FOREACH UNIX TIME END print TXS "\n);\n"; } ## END SEND REPLY SUB sub numbr {$a <=> $b;} sub randomarrs { my $array = shift; my $i; for ($i = @$array; --$i; ) { my $j = int rand ($i+1); next if $i == $j; @$array[$i,$j] = @$array[$j,$i]; } } ## RANDOMIZE ARRAYS END sub sendgrowl { ## Send Growl message my($name,$chatname,$posted,$did) = @_; my $wrkIP='192.168.2.230'; ## Workstation IP address my $dcheck = `ping -q -c 1 -W 1 $wrkIP`; if($dcheck =~ m/1 packets received/) { my $data="$name\n\n$did Telegram chat\n\n\"$chatname\"\n\non: $posted"; $data =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg; `/opt/local/bin/curl http://$wrkIP/chat.cgi?data=$data`; } ## END GOOD PING } ## END SEND GROWL MESSAGE sub doreplyqu { # Reply to pre-set question (click on the button) my($fname,$lname,$chatid,$message)=@_; foreach my $answ (sort numbr keys %{$subquestion{$message}}) { $prtext .= "$subquestion{$message}{$answ}\n"; } ## FOREACH ANSWER END $prtext =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg; `/opt/local/bin/curl 'https://api.telegram.org/bot$tagis/sendMessage?chat_id=$chatid\&text=$prtext'`; exit(0); } ## END DO REPLY TO QUESTION sub gethashes {# Create a keyboard buttons @initqu=('Get Product information','Placing an Order','Contacting Us','Order issues'); $subquestion{'Get Product information'}{1}="Go to:\nhttps://www.example.com/"; $subquestion{'Get Product information'}{2}="Choose Category from the drop-down menu or use site search to locate the product."; $subquestion{'Get Product information'}{3}="Click on the product link to see full product description"; $subquestion{'Placing an Order'}{1}="Locate the product and click on \"Buy it Now\" button."; $subquestion{'Placing an Order'}{2}="Follow order instructions."; $subquestion{'Placing an Order'}{3}="Once order received you will receive order confirmation email."; $subquestion{'Contacting Us'}{1}="The easiest and most reliable way to get in-touch with us would be using our Contact form at:"; $subquestion{'Contacting Us'}{2}="https://www.example.com/contact/"; $subquestion{'Order issues'}{1}="Should any order issues arise, please do not hesitate to contact us."; $subquestion{'Order issues'}{2}="We will try our best to work with you for your complete satisfaction."; $subquestion{'Order issues'}{3}="We have 30-day money-back guarantee!"; } ## END SUB GET HASHES Thank you! |