Как включить чаты в поиск 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')
Другие вопросы по тегам