GitHubじゃ!Pythonじゃ!

GitHubからPython関係の優良リポジトリを探したかったのじゃー、でも英語は出来ないから日本語で読むのじゃー、英語社会世知辛いのじゃー

eternnoir

pyTelegramBotAPI – Python Telegram bot api

投稿日:

Python Telegram bot api。

pyTelegramBotAPI

Telegram Bot API用のシンプルで拡張可能なPython実装。

入門。

このAPIは、Python 2.6、Python 2.7、Python 3.4、Pypy、およびPypy 3でテストされています。ライブラリをインストールする方法は2つあります。

  • pip(Pythonパッケージマネージャー)を使用したインストール*:
$ pip install pyTelegramBotAPI
  • ソースからのインストール(gitが必要):
$ git clone https://github.com/eternnoir/pyTelegramBotAPI.git
$ cd pyTelegramBotAPI
$ python setup.py install

通常、最初のオプションを使用することをお勧めします。

* APIはプロダクションの準備ができていますが、まだ開発中で定期的な更新がありますので、 pip install pytelegrambotapi --upgrade呼び出して定期的に更新することを忘れないでください

あなたの最初のボットを書く

前提条件

@BotFatherを使用してAPIトークンを取得したことが前提です。 このトークンをTOKENと呼びます。 さらに、Pythonプログラミング言語、さらに重要なTelegram Bot APIに関する基本知識があります

単純なエコーボット

TeleBotクラス(_ init _.pyで定義)は、すべてのAPI呼び出しを1つのクラスにカプセル化します。 それは、 send_xyzsend_messagesend_documentなど)や着信メッセージを受信するためのいくつかの方法などの機能を提供します。

echo_bot.pyというファイルを作成します。 次に、ファイルを開き、TeleBotクラスのインスタンスを作成します。

import telebot

bot = telebot.TeleBot("TOKEN")

注:実際には、独自のAPIトークンでTOKENを置き換えてください。

その宣言の後、いわゆるメッセージハンドラを登録する必要があります。 メッセージハンドラは、メッセージが通過しなければならないフィルタを定義します。 メッセージがフィルタを通過すると、装飾された関数が呼び出され、着信メッセージが引数として渡されます。

incoming /start/helpコマンドを扱うメッセージハンドラを定義しましょう。

@bot.message_handler(commands=['start', 'help'])
def send_welcome(message):
	bot.reply_to(message, "Howdy, how are you doing?")

メッセージハンドラによって装飾された関数は、任意の名前を持つことができますが、パラメータ(メッセージ)は1つだけでなければなりません

別のハンドラを追加しましょう:

@bot.message_handler(func=lambda m: True)
def echo_all(message):
	bot.reply_to(message, message.text)

これは、すべての着信テキストメッセージを送信者に返信します。 ラムダ関数を使用してメッセージをテストします。 ラムダがTrueを返す場合、メッセージは装飾された関数によって処理されます。 すべてのメッセージをこの関数で処理したいので、単にTrueを返すだけです。

注:すべてのハンドラは、宣言された順序でテストされます

静的メッセージを “/ start”と “/ help”コマンドに返信し、残りの送信メッセージをエコーする基本的なボットを用意しました。 ボットを起動するには、以下をソースファイルに追加してください:

bot.polling()

さて、それだけです! 私たちのソースファイルは次のようになります:

import telebot

bot = telebot.TeleBot("TOKEN")

@bot.message_handler(commands=['start', 'help'])
def send_welcome(message):
	bot.reply_to(message, "Howdy, how are you doing?")

@bot.message_handler(func=lambda message: True)
def echo_all(message):
	bot.reply_to(message, message.text)

bot.polling()

ボットを起動するには、ターミナルを開き、 python echo_bot.pyと入力してボットを実行してください! コマンド( ‘/ start’と ‘/ help’)と任意のテキストメッセージを送信してテストします。

一般的なAPIドキュメント

タイプ

すべての型はtypes.pyで定義されています。 それらはすべて、 テレグラムAPIのタイプの定義に完全に一致しています 。ただし、 from_userが変更されたMessageのfrom_userフィールドはfrom_userfromはPython予約トークンです)。 したがって、 message_idなどの属性には、 message.message_id直接アクセスできます。 message.chatは、 UserまたはGroupChatインスタンスのいずれかになります( message.chatのユーザーとGroupChatを区別する方法を参照してください)。

Messageオブジェクトには、メッセージのタイプを定義するcontent_type属性もあります。 content_typeは、 textaudiodocumentphotostickervideovideo video_notevoicelocationcontactnew_chat_membersleft_chat_membernew_chat_titlenew_chat_photonew_chat_photodelete_chat_photogroup_chat_createdsupergroup_chat_createdchannel_chat_createdmigrate_to_chat_idmigrate_from_chat_idpinned_message

一つの関数でいくつかの型を使うことができます。 例:

content_types=["text", "sticker", "pinned_message", "photo", "audio"]

メソッド

すべてのAPIメソッドは、TeleBotクラスにあります。 共通のPython命名規則に従って名前が変更されています。 たとえば、 getMeget_mesendMessagegetMeが変更されsend_message

APIの一般的な使用

次に、APIの一般的な使用例を示します。

メッセージハンドラ

メッセージハンドラは、TeleBotインスタンスのmessage_handlerデコレータで装飾された関数です。 メッセージハンドラは、1つまたは複数のフィルタで構成されます。 各フィルタは、メッセージハンドラがそのメッセージを処理する資格を得るために、特定のメッセージに対して真に多くを返します。 メッセージハンドラは次の方法で宣言されます(提供されたbotはTeleBotのインスタンスです)。

@bot.message_handler(filters)
def function_name(message):
	bot.reply_to(message, "This is a message handler")

function_nameは制限に束縛されません。 すべての関数名はメッセージハンドラで許可されます。 関数は最大で1つの引数を受け入れなければなりません。これは関数が処理しなければならないメッセージです。 filtersはキーワード引数のリストです。 フィルタは次のように宣言されます: name=argument 1つのハンドラが複数のフィルタを持つ場合があります。 TeleBotは次のフィルタをサポートしています。

議論 調子
content_types 文字列のリスト(デフォルト['text'] message.content_typeが文字列のリストにある場合はTrueです。
正規表現 文字列としての正規表現 re.search(regexp_arg)Trueを返し、 message.content_type == 'text'Pythonの正規表現を参照してください)
コマンド 文字列のリスト message.content_type == 'text'場合はTruemessage.content_type == 'text'は文字列のリストにあるコマンドで始まります。
機能 関数(ラムダまたは関数参照) ラムダ関数リファレンスがTrue返す場合はTrue

フィルタとメッセージハンドラの使用例を次に示します。

import telebot
bot = telebot.TeleBot("TOKEN")

# Handles all text messages that contains the commands '/start' or '/help'.
@bot.message_handler(commands=['start', 'help'])
def handle_start_help(message):
	pass

# Handles all sent documents and audio files
@bot.message_handler(content_types=['document', 'audio'])
def handle_docs_audio(message):
	pass

# Handles all text messages that match the regular expression
@bot.message_handler(regexp="SOME_REGEXP")
def handle_message(message):
	pass

#Handles all messages for which the lambda returns True
@bot.message_handler(func=lambda message: message.document.mime_type == 'text/plain', content_types=['document'])
def handle_text_doc(message):
	pass

#Which could also be defined as:
def test_message(message):
	return message.document.mime_type == 'text/plain'

@bot.message_handler(func=test_message, content_types=['document'])
def handle_text_doc(message)
	pass

# Handlers can be stacked to create a function which will be called if either message_handler is eligible
# This handler will be called if the message starts with '/hello' OR is some emoji
@bot.message_handler(commands=['hello'])
@bot.message_handler(func=lambda msg: msg.text.encode("utf-8") == SOME_FANCY_EMOJI)
def send_something(message):
    pass

重要:すべてのハンドラは宣言された順序でテストされます

編集されたメッセージハンドラ

メッセージハンドラと同じ

channel_post_handler

メッセージハンドラと同じ

edited_channel_post_handler

メッセージハンドラと同じ

コールバッククエリハンドラ

bot2.0のアップデート。 更新オブジェクトでcallback_queryを取得できます。 テレホンでは、 callback_query_handlerを処理するためにcallback_query_handlerを使用します。

@bot.callback_query_handler(func=lambda call: True)
def  test_callback(call):
    logger.info(call)

テレボット

import telebot

TOKEN = '<token_string>'
tb = telebot.TeleBot(TOKEN)	#create a new Telegram Bot object

# Upon calling this function, TeleBot starts polling the Telegram servers for new messages.
# - none_stop: True/False (default False) - Don't stop polling when receiving an error from the Telegram servers
# - interval: True/False (default False) - The interval between polling requests
#           Note: Editing this parameter harms the bot's response time
# - timeout: integer (default 20) - Timeout in seconds for long polling.
tb.polling(none_stop=False, interval=0, timeout=20)

# getMe
user = tb.get_me()

# setWebhook
tb.set_webhook(url="http://example.com", certificate=open('mycert.pem'))
# unset webhook
tb.remove_webhook()

# getUpdates
updates = tb.get_updates()
updates = tb.get_updates(1234,100,20) #get_Updates(offset, limit, timeout):

# sendMessage
tb.send_message(chatid, text)

# forwardMessage
tb.forward_message(to_chat_id, from_chat_id, message_id)

# All send_xyz functions which can take a file as an argument, can also take a file_id instead of a file.
# sendPhoto
photo = open('/tmp/photo.png', 'rb')
tb.send_photo(chat_id, photo)
tb.send_photo(chat_id, "FILEID")

# sendAudio
audio = open('/tmp/audio.mp3', 'rb')
tb.send_audio(chat_id, audio)
tb.send_audio(chat_id, "FILEID")

## sendAudio with duration, performer and title.
tb.send_audio(CHAT_ID, file_data, 1, 'eternnoir', 'pyTelegram')

# sendVoice
voice = open('/tmp/voice.ogg', 'rb')
tb.send_voice(chat_id, voice)
tb.send_voice(chat_id, "FILEID")

# sendDocument
doc = open('/tmp/file.txt', 'rb')
tb.send_document(chat_id, doc)
tb.send_document(chat_id, "FILEID")

# sendSticker
sti = open('/tmp/sti.webp', 'rb')
tb.send_sticker(chat_id, sti)
tb.send_sticker(chat_id, "FILEID")

# sendVideo
video = open('/tmp/video.mp4', 'rb')
tb.send_video(chat_id, video)
tb.send_video(chat_id, "FILEID")

# sendVideoNote
videonote = open('/tmp/videonote.mp4', 'rb')
tb.send_video_note(chat_id, videonote)
tb.send_video_note(chat_id, "FILEID")

# sendLocation
tb.send_location(chat_id, lat, lon)

# sendChatAction
# action_string can be one of the following strings: 'typing', 'upload_photo', 'record_video', 'upload_video',
# 'record_audio', 'upload_audio', 'upload_document' or 'find_location'.
tb.send_chat_action(chat_id, action_string)

# getFile
# Downloading a file is straightforward
# Returns a File object
import requests
file_info = tb.get_file(file_id)

file = requests.get('https://api.telegram.org/file/bot{0}/{1}'.format(API_TOKEN, file_info.file_path))

返信マークアップ

send_xyzすべてのsend_xyz関数は、オプションのreply_markup引数をreply_markupます。 この引数は、 ReplyKeyboardRemove定義されているForceReplyForceReply 、またはForceReplyインスタンスでなければなりません。

from telebot import types

# Using the ReplyKeyboardMarkup class
# It's constructor can take the following optional arguments:
# - resize_keyboard: True/False (default False)
# - one_time_keyboard: True/False (default False)
# - selective: True/False (default False)
# - row_width: integer (default 3)
# row_width is used in combination with the add() function.
# It defines how many buttons are fit on each row before continuing on the next row.
markup = types.ReplyKeyboardMarkup(row_width=2)
itembtn1 = types.KeyboardButton('a')
itembtn2 = types.KeyboardButton('v')
itembtn3 = types.KeyboardButton('d')
markup.add(itembtn1, itembtn2, itembtn3)
tb.send_message(chat_id, "Choose one letter:", reply_markup=markup)

# or add KeyboardButton one row at a time:
markup = types.ReplyKeyboardMarkup()
itembtna = types.KeyboardButton('a')
itembtnv = types.KeyboardButton('v')
itembtnc = types.KeyboardButton('c')
itembtnd = types.KeyboardButton('d')
itembtne = types.KeyboardButton('e')
markup.row(itembtna, itembtnv)
markup.row(itembtnc, itembtnd, itembtne)
tb.send_message(chat_id, "Choose one letter:", reply_markup=markup)

最後の例では、この結果が得られます。

# ReplyKeyboardRemove: hides a previously sent ReplyKeyboardMarkup
# Takes an optional selective argument (True/False, default False)
markup = types.ReplyKeyboardRemove(selective=False)
tb.send_message(chat_id, message, reply_markup=markup)
# ForceReply: forces a user to reply to a message
# Takes an optional selective argument (True/False, default False)
markup = types.ForceReply(selective=False)
tb.send_message(chat_id, "Send me another word:", reply_markup=markup)

ForceReply:

インラインモード

インラインモードの詳細。

インラインハンドラー

これで、inline_handlerを使用して、テレホンでinline_queryを取得できます。

@bot.inline_handler(lambda query: query.query == 'text')
def query_text(inline_query):
    # Query message is text

selected_inline_handler

テレフォンでselected_inline_resultを取得するには、selected_inline_handlerを使用してください。 @Botfatherの/ setinlinefeedbackコマンドを追加するのを忘れてはいけません。

詳細: 収集フィードバック

@bot.chosen_inline_handler(func=lambda chosen_inline_result: True)
def test_chosen(chosen_inline_result):
    # Process all chosen_inline_result.

answer_inline_query

@bot.inline_handler(lambda query: query.query == 'text')
def query_text(inline_query):
    try:
        r = types.InlineQueryResultArticle('1', 'Result', types.InputTextMessageContent('Result message.'))
        r2 = types.InlineQueryResultArticle('2', 'Result2', types.InputTextMessageContent('Result message2.'))
        bot.answer_inline_query(inline_query.id, [r, r2])
    except Exception as e:
        print(e)

エンティティの操作:

このオブジェクトは、テキストメッセージ内の1つの特殊なエンティティを表します。 たとえば、ハッシュタグ、ユーザー名、URLなど属性:

  • type
  • url
  • offset
  • length
  • user

次に例を示します message.entities[num].<attribute>
ここで、 numは、応答/メッセージ内に複数のエンティティが存在する場合、エンティティ番号またはエンティティの応答の順序です。
message.entitiesはエンティティオブジェクトのリストを返します。
message.entities[0].typeは、最初のエンティティのタイプを指定します。
詳細はBot Apiを参照してください

APIの高度な使用

メッセージの非同期配信

すべてのget_me関数とget_me関数を非同期に実行するTeleBotの実装が存在します。 これにより、ボットの速度を大幅に向上させることができますが、慎重に使用すると望ましくない副作用があります。 この動作を有効にするには、TeleBotの代わりにAsyncTeleBotのインスタンスを作成します。

tb = telebot.AsyncTeleBot("TOKEN")

今、テレグラムAPIを呼び出すすべての関数は別のスレッドで実行されます。 AsyncTaskインスタンスを返すように関数が変更されています(util.pyで定義されています)。 AsyncTeleBotを使用すると、以下を実行できます。

import telebot

tb = telebot.AsyncTeleBot("TOKEN")
task = tb.get_me() # Execute an API call
# Do some other operations...
a = 0
for a in range(100):
	a += 10

result = task.wait() # Get the result of the execution

注:wait()を呼び出さずにsend_xyz関数をお互いに実行すると、メッセージの配送順序が間違っている可能性があります。

大きなテキストメッセージを送信する

場合によっては、5000文字を超えるメッセージを送信する必要があります。 テレグラムAPIは、1つのリクエストで多くの文字を処理できないため、メッセージを複数に分割する必要があります。 APIを使用してその操作を行う方法は次のとおりです。

from telebot import util
large_text = open("large_text.txt", "rb").read()

# Split the text each 3000 characters.
# split_string returns a list with the splitted text.
splitted_text = util.split_string(large_text, 3000)
for text in splitted_text:
	tb.send_message(chat_id, text)

TeleBotが使用するスレッドの量の制御

TeleBotコンストラクタには、次のオプション引数があります。

  • threaded:True / False(デフォルトはTrue)。 TeleBotがポーリングスレッド上でメッセージハンドラを実行するかどうかを示すフラグ。

リスナーメカニズム

メッセージハンドラの代替として、TeleBotにリスナとして機能を登録することもできます。 例:

def handle_messages(messages):
	for message in messages:
		# Do something with the message
		bot.reply_to(message, 'Hi')

bot.set_update_listener(handle_messages)
bot.polling()

ウェブフックの使用

webhooksテレグラムを使用する場合は、1つのコールごとに1つのUpdateを送信します。処理するには、受信時にprocess_new_messages([update.message])を呼び出す必要があります。

examples / webhook_examplesディレクトリにwebhooksを使用したがいくつかあります。

ロギング

Telebotモジュールロガーを使用して、Telebotに関するデバッグ情報を記録できます。 telebot.loggerを使用して、TeleBotモジュールのロガーを取得します。 カスタムロギングハンドラをロガーに追加することは可能です。 詳細については、 Pythonロギングモジュールのページ参照してください。

import logging

logger = telebot.logger
telebot.logger.setLevel(logging.DEBUG) # Outputs debug messages to console.

プロキシ

プロキシをリクエストに使用できます。 apihelper.proxyオブジェクトは、呼び出しrequestsプロキシ引数によって使用されます。

from telebot import apihelper

apihelper.proxy = {'http', 'http://10.10.1.10:3128'}

socket5プロキシを使用する場合は、依存関係pip install requests[socks]必要があります。

proxies = {
    'http': 'socks5://user:pass@host:port',
    'https': 'socks5://user:pass@host:port'
}

よくある質問

Bot 2.0

4月9,2016電報は新しいメソッドをリリースしました。最新のバージョンに更新したい場合は、ボットのコードをボット2.0のメソッドインタフェースに切り替えたことを確認してください。

pyTelegramBotAPIのbot2.0サポートの詳細

私はどのようにUserとGroupChatをmessage.chatで区別できますか?

Telegram Bot APIは、message.chatの新しいタイプのチャットをサポートしています。

  • Chatオブジェクトのtype属性を確認します。
if message.chat.type == “private”:
	# private chat message

if message.chat.type == “group”:
	# group chat message

if message.chat.type == “supergroup”:
	# supergroup chat message

if message.chat.type == “channel”:
	# channel message

テレグラムチャットグループ

助けを得ます。 話し合います。 チャット。

より多くの例

このAPIを使用するボット

  • SiteAlertボットソース )by ilteoood – ウェブサイトを監視し、変更を通知します
  • aRandomStrangerによるTelegramLoggingBot
  • GabrielRFによってKindle Botに送信する – Kindleファイルまたはファイルへのリンクに送信する。
  • GabrielRFによるLMGTFY_botsource )の電報 – 私にあなたのためにGoogleをさせてください。
  • GabrielRFによるUrlProBotソース )のテレグラム – URL短縮機能とURL拡張機能。
  • GrooghaによるTelegram Proxy Bot – ある種の “プロキシ”の役割を果たすテレグラム用の単純なBITM(bot-in-the-middle)。
  • mrgigabyteによるプロキシボットの電報Credits for the original version of this bot goes to Grooshaに行き , simply added certain features which I thought were needed
  • TronikartによるRadRetroRobot – Multifunctional TelegramのBot RadRetroRobot。
  • League of Legendsボットソース )by i32ropie
  • ネオレンジャーによるネオボット
  • ピタシによるTagAlertBot
  • comedoresUrlbotsource )by alejandrocq – Universidad de Granadaダイニングホールのメニューをチェックするための電報ボット。
  • picpingbot – Boogie Muffinによる楽しい匿名の写真交換。
  • TheZigZagProject – テレグラムのための ‘All In One’ボット! WebShark025によって
  • proxybot – テレグラムのためのシンプルなプロキシボット。 p-hashで
  • DonantesMalagaBot – DonantesMalagaBotは、マラガ献血者に、今日、または入院日に寄付できる場所についての情報を容易にします。 また、最後の寄付の日付も記録され、寄付者がいつ再寄付できるかを知るのに役立ちます。 – by vfranch
  • Dmytryi StriletskyiのDuttyBot – キエフのある大学のタイムテーブル。
  • dailypepebot by Jaime – あなたは無作為なペペ画像を取得し、あなたにIDを渡すと、番号でこの画像を呼び出すことができます。
  • 毎日00:00にqwerteeの毎日のTシャツを送るチャンネルを管理するJaime -BotのDailyQwertee
  • ワットブリッジ by rmed – WhatsAppとの電文の送受信
  • flibusta_botによってKurbezz
  • EmaProject by halkliff – Ema – イースタン・メディア・アシスタントは、使い易さの点から考えました。 ここでのコーディングは、高速で強力なものと同じくらい簡単です。
  • jcolladospによるfilmratingbotsource ) – IMDbとメタクラートから映画評価を取得するPython APIを使用した電報ボット
  • you2mp3botリンク ) – このボットは、YouTubeのビデオをMp3に変換できます。 必要なのは、URLビデオを送信することだけです。
  • areajugonesbotリンク ) – areajugonesbotは、ビデオゲームのブログAreajugonesをTelegramに公開したニュースを送ります。
  • GabrielRFのSend2Kindlebotソース ) – Kindleサービスに送信します。
  • GabrielRF -BotのRastreioBotソース )は、ブラジルのメールサービスでパッケージを追跡するために使用されました。
  • filex_botリンク
  • SPBU学生のためのタイムテーブル付EeOneDown – BotのSpbu4UBotリンク )。
  • 0xvKによるSmartySBotリンク ) – Zhytomyr Ivan Franko州立大学生のためのテレグラムタイムテーブルボット。
  • yandex_music_bot – 無料でYandex.Musicストリーミングサービスからトラック/アルバム/公開プレイリストをダウンロードします。
  • LearnItリンク ) – 他の言語の語彙を覚えるのを助けるために作成された電報ボット。

あなたのボットをここに掲載したいですか? テレグラムメッセージを@eternnoirまたは@pevdhに送ります。







-eternnoir
-, , , ,

執筆者: