Как включить чаты в поиск Gmail IMAP из imaplib Python?
Я с радостью использую imaplib для получения идентификаторов сообщений в определенной метке:
connection.select("MyLabel")
connection.uid('SEARCH', None, 'ALL'))
но если у меня есть несколько чатов в этом ярлыке, они не возвращаются, поэтому они невидимы для IMAP. Я прочитал Доступ к папке чата в Python с помощью Imaplib, хотя это для поиска по метке Чаты, а не для поиска чатов в другой метке, и, похоже, это не работает.
Возможно, я мог бы выполнить второй поиск в "Чатах" для сообщений, помеченных как "MyLabel", но это дополнительный запрос, и он требует довольно много настроек от пользователей моего приложения.
1 ответ
Ярлыки Gmail отображаются как почтовые ящики верхнего уровня, а не наоборот. Для поиска в нескольких почтовых ящиках необходимо выполнить несколько запросов, выполнив тем самым select()
на соответствующий почтовый ящик, затем делает search
команда (или uid
в твоем случае).
Настройка учетной записи Gmail для доступа к чатам через IMAP:
Ссылка, которую вы дали: Доступ к папке чата в Python Использование Imaplib по-прежнему очень актуально, так как пользователям нужно будет разрешить IMAP доступ к своим журналам чата. Вы также можете проверить расширения imap, используемые Gmail, с описанием X-GM-RAW
а также X-GM-LABELS
,
Если вы используете Gmail для бизнеса, я не уверен, что он работает (у меня нет аккаунта для проверки), но эта ссылка: https://developers.google.com/gmail/imap_extensions может помочь вам увидеть если расширения присутствуют.
Модифицированная кодировка utf-7:
Большинство серверов imap хранят имена и метки почтовых ящиков в модифицированной версии utf-7
, Вы не можете использовать подобные ярлыки для Gmail, если вы не используете обычный us-ascii
, IMAPClient
знает, как кодировать / декодировать, используя модифицированную кодировку utf7, используемую большинством серверов IMAP. Существует открытая ошибка в imaplib, так что вы можете использовать imapclient.imap_utf7
модуль для кодирования имен почтовых ящиков и / или меток до imaplib
начинает поддерживать модифицированный utf-7
кодирование само по себе. Другая вещь, которую я нашел в Интернете: в то время как вы можете STORE
удачно помечается с определенной кодировкой, SEARCH
для них (также когда задействован xoauth), если вы не используете этот измененный utf-7
кодирование или указание кодировки. Другие проекты уже выполняют большую часть работы для gmail, например BaGoMa ( резервная копия google mail), которая поставляется с поддержкой imap-utf7. До сих пор я смог создать ярлык через интерфейс latin-1
характер и SEARCH
для этого с помощью utf-8
кодировок.
Вот как кодировать ваш ярлык:
from imapclient import imap_utf7
label = imap_utf7.encode(u'yourlabel')
см. также этот вопрос: кодировка пути к папке IMAP (IMAP UTF-7) для Python
Вы можете проверить свои этикетки с:
>>>> sock.select("[Gmail]/Chats", True)
>>>> sock.uid('FETCH', '1:*', 'X-GM-LABELS')
Это полезно, чтобы проверить, какие метки у вас есть, и для устранения проблем кодирования.
Пример:
import imaplib
import getpass
import atexit
from imapclient import imap_utf7
def find_messages(sock, label):
mailbox = imap_utf7.encode(label)
label = imap_utf7.encode(label.encode('utf-8'))
try:
# process regular mailbox
sock.select(mailbox)
except sock.error:
pass
else:
resp, data = sock.uid('SEARCH', None, '(ALL)')
assert resp == 'OK'
for uid in data[0].split():
# because we do select, this uid will be valid.
yield uid
try:
# now process chats with that label
sock.select("[Gmail]/Chats", True)
except sock.error:
# access to chats via IMAP is disabled most likely
pass
else:
# resp, data = sock.uid('SEARCH', 'X-GM-RAW', 'label:%s' % label)
sock.literal = label
resp, data = sock.uid('SEARCH', 'CHARSET', 'UTF-8', 'X-GM-LABELS')
assert resp == 'OK'
for uid in data[0].split():
# because we do select, this uid will be valid.
yield uid
def test():
email = "XXXXXXXX@gmail.com"
label = u"français" # oui oui merci beaucoup.
sock = imaplib.IMAP4_SSL("imap.gmail.com", 993)
sock.login(email, getpass.getpass())
for uid in find_messages(sock, label):
# e.g.
print sock.uid('FETCH', uid, '(BODY[HEADER])')
sock.close()
sock.logout()
проверено на моей машине!
>>> test()
Password:
('OK', [('1 (UID 14 BODY[HEADER] {398}', 'MIME-Version: 1.0\r\nReceived: by 10.XXX.XXX.XXX with HTTP; Thu, 11 Jul 2013 09:54:32 -0700 (PDT)\r\nDate: Thu, 11 Jul 2013 09:54:32 -0700\r\nDelivered-To: XXXXXXXX@gmail.com\r\nMessage-ID: <XXXXXXXX@mail.gmail.com>\r\nSubject: test email\r\nFrom: Damien <XXXXXXXX@gmail.com>\r\nTo: Damien <XXXXXXXX@gmail.com>\r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\n'), ')'])
('OK', [('1 (UID 1 BODY[HEADER] {47}', 'From: Damien XXXXXXXX <XXXXXXXX@gmail.com>\r\n\r\n'), ')'])
('OK', [('2 (UID 2 BODY[HEADER] {46}', 'From: Vincent XXXXXXXX <XXXXXXXX@gmail.com>\r\n\r\n'), ')'])
Недокументированный интерфейс:
imaplib
может использовать литералы, это особенно полезно при использовании другой кодировки. Это работает, установив IMAP4.literal
атрибут перед запуском команды.
sock.literal = label
resp, data = sock.uid('SEARCH', 'CHARSET', 'UTF-8', 'X-GM-LABELS')