Skip to content

Commit 374dc6d

Browse files
committed
Add search_messages method
1 parent 6f638cd commit 374dc6d

3 files changed

Lines changed: 188 additions & 1 deletion

File tree

compiler/docs/compiler.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ def get_title_list(s: str) -> list:
175175
stop_poll
176176
retract_vote
177177
send_dice
178+
search_messages
178179
download_media
179180
""",
180181
chats="""

pyrogram/client/methods/messages/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
from .stop_poll import StopPoll
5353
from .vote_poll import VotePoll
5454
from .send_dice import SendDice
55+
from .search_messages import SearchMessages
5556

5657

5758
class Messages(
@@ -90,6 +91,7 @@ class Messages(
9091
EditInlineCaption,
9192
EditInlineMedia,
9293
EditInlineReplyMarkup,
93-
SendDice
94+
SendDice,
95+
SearchMessages
9496
):
9597
pass
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# Pyrogram - Telegram MTProto API Client Library for Python
2+
# Copyright (C) 2017-2020 Dan <https://github.com/delivrance>
3+
#
4+
# This file is part of Pyrogram.
5+
#
6+
# Pyrogram is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Lesser General Public License as published
8+
# by the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# Pyrogram is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Lesser General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public License
17+
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
18+
19+
from typing import Union, List, Generator
20+
21+
import pyrogram
22+
from pyrogram.client.ext import BaseClient, utils
23+
from pyrogram.api import functions, types
24+
25+
26+
class Filters:
27+
EMPTY = types.InputMessagesFilterEmpty()
28+
PHOTO = types.InputMessagesFilterPhotos()
29+
VIDEO = types.InputMessagesFilterVideo()
30+
PHOTO_VIDEO = types.InputMessagesFilterPhotoVideo()
31+
DOCUMENT = types.InputMessagesFilterDocument()
32+
URL = types.InputMessagesFilterUrl()
33+
ANIMATION = types.InputMessagesFilterGif()
34+
VOICE_NOTE = types.InputMessagesFilterVoice()
35+
AUDIO = types.InputMessagesFilterMusic()
36+
CHAT_PHOTO = types.InputMessagesFilterChatPhotos()
37+
PHONE_CALL = types.InputMessagesFilterPhoneCalls()
38+
AUDIO_VIDEO_NOTE = types.InputMessagesFilterRoundVideo()
39+
VIDEO_NOTE = types.InputMessagesFilterRoundVideo()
40+
MENTION = types.InputMessagesFilterMyMentions()
41+
LOCATION = types.InputMessagesFilterGeo()
42+
CONTACT = types.InputMessagesFilterContacts()
43+
44+
45+
POSSIBLE_VALUES = list(map(lambda x: x.lower(), filter(lambda x: not x.startswith("__"), Filters.__dict__.keys())))
46+
47+
48+
# noinspection PyShadowingBuiltins
49+
def get_chunk(
50+
client: BaseClient,
51+
chat_id: Union[int, str],
52+
query: str = "",
53+
filter: str = "empty",
54+
offset: int = 0,
55+
limit: int = 100,
56+
from_user: Union[int, str] = None
57+
) -> List["pyrogram.Message"]:
58+
try:
59+
filter = Filters.__dict__[filter.upper()]
60+
except KeyError:
61+
raise ValueError('Invalid filter "{}". Possible values are: {}'.format(
62+
filter, ", ".join('"{}"'.format(v) for v in POSSIBLE_VALUES))) from None
63+
64+
r = client.send(
65+
functions.messages.Search(
66+
peer=client.resolve_peer(chat_id),
67+
q=query,
68+
filter=filter,
69+
min_date=0,
70+
max_date=0,
71+
offset_id=0,
72+
add_offset=offset,
73+
limit=limit,
74+
min_id=0,
75+
max_id=0,
76+
from_id=(
77+
client.resolve_peer(from_user)
78+
if from_user
79+
else None
80+
),
81+
hash=0
82+
)
83+
)
84+
85+
return utils.parse_messages(client, r)
86+
87+
88+
class SearchMessages(BaseClient):
89+
# noinspection PyShadowingBuiltins
90+
def search_messages(
91+
self,
92+
chat_id: Union[int, str],
93+
query: str = "",
94+
offset: int = 0,
95+
filter: str = "empty",
96+
limit: int = 0,
97+
from_user: Union[int, str] = None
98+
) -> Generator["pyrogram.Message", None, None]:
99+
"""Search for text and media messages inside a specific chat.
100+
101+
Parameters:
102+
chat_id (``int`` | ``str``):
103+
Unique identifier (int) or username (str) of the target chat.
104+
For your personal cloud (Saved Messages) you can simply use "me" or "self".
105+
For a contact that exists in your Telegram address book you can use his phone number (str).
106+
107+
query (``str``, *optional*):
108+
Text query string.
109+
Required for text-only messages, optional for media messages (see the ``filter`` argument).
110+
When passed while searching for media messages, the query will be applied to captions.
111+
Defaults to "" (empty string).
112+
113+
offset (``int``, *optional*):
114+
Sequential number of the first message to be returned.
115+
Defaults to 0.
116+
117+
filter (``str``, *optional*):
118+
Pass a filter in order to search for specific kind of messages only:
119+
120+
- ``"empty"``: Search for all kind of messages (default).
121+
- ``"photo"``: Search for photos.
122+
- ``"video"``: Search for video.
123+
- ``"photo_video"``: Search for either photo or video.
124+
- ``"document"``: Search for documents (generic files).
125+
- ``"url"``: Search for messages containing URLs (web links).
126+
- ``"animation"``: Search for animations (GIFs).
127+
- ``"voice_note"``: Search for voice notes.
128+
- ``"audio"``: Search for audio files (music).
129+
- ``"chat_photo"``: Search for chat photos.
130+
- ``"phone_call"``: Search for phone calls.
131+
- ``"audio_video_note"``: Search for either audio or video notes.
132+
- ``"video_note"``: Search for video notes.
133+
- ``"mention"``: Search for messages containing mentions to yourself.
134+
- ``"location"``: Search for location messages.
135+
- ``"contact"``: Search for contact messages.
136+
137+
limit (``int``, *optional*):
138+
Limits the number of messages to be retrieved.
139+
By default, no limit is applied and all messages are returned.
140+
141+
from_user (``int`` | ``str``):
142+
Unique identifier (int) or username (str) of the target user you want to search for messages from.
143+
144+
Returns:
145+
``Generator``: A generator yielding :obj:`Message` objects.
146+
147+
Example:
148+
.. code-block:: python
149+
150+
# Search for text messages in @pyrogramchat. Get the last 333 results
151+
for message in app.search_messages("pyrogramchat", query="dan", limit=333):
152+
print(message.text)
153+
154+
# Search for photos sent by @haskell in @pyrogramchat
155+
for message in app.search_messages("pyrogramchat", "", filter="photo" limit=333, from_user="haskell"):
156+
print(message.text)
157+
"""
158+
current = 0
159+
total = abs(limit) or (1 << 31) - 1
160+
limit = min(100, total)
161+
162+
while True:
163+
messages = get_chunk(
164+
client=self,
165+
chat_id=chat_id,
166+
query=query,
167+
filter=filter,
168+
offset=offset,
169+
limit=limit,
170+
from_user=from_user
171+
)
172+
173+
if not messages:
174+
return
175+
176+
offset += 100
177+
178+
for message in messages:
179+
yield message
180+
181+
current += 1
182+
183+
if current >= total:
184+
return

0 commit comments

Comments
 (0)