Как скачать вложение из электронного письма, отправленного на почтовый адрес группы Google - PullRequest
0 голосов
/ 11 декабря 2018

Допустим, моя электронная почта a@company.com находится в группе Google с адресом электронной почты group@company.com.У нас есть сервисная учетная запись ag Suite, в которой разрешено делегирование домена Служб Google.У нас есть электронные письма, отправленные с b@companyb.com на электронный адрес нашей группы group@company.com, с темой Report from company b и приложением отчета к электронному письму.

Проблема в том, что API gmail может перечислять все сообщения, но не может перечислять вложения в каждом письме.

Есть ли способ сделать это?

Вот мой код:

    // here when I create the client, I use my email address `a@company.com`
    using(var client = CreateClient())
    {
        UsersResource.MessagesResource.ListRequest request = client.Users.Messages.List("me");

        request.Q = "from:b@compayb.com AND subject:Report from company b AND has:attachment"

        // List messages.
        var messageIds = request.Execute().Messages?.Select(m => m.Id) ?? new List<string>();

        foreach(var mId in messageIds)
        {
            // https://developers.google.com/gmail/api/v1/reference/users/messages/attachments/get
            Message message = client.Users.Messages.Get("me", messageId).Execute();
            IList<MessagePart> parts = message.Payload.Parts;
            foreach (MessagePart part in parts)
            {
                if (!String.IsNullOrEmpty(part.Filename))
                {
                    String attId = part.Body.AttachmentId;
                    MessagePartBody attachPart = client.Users.Messages.Attachments.Get("me", messageId, attId).Execute();

                    // Converting from RFC 4648 base64 to base64url encoding
                    // see http://en.wikipedia.org/wiki/Base64#Implementations_and_history
                    String attachData = attachPart.Data.Replace('-', '+');
                    attachData = attachData.Replace('_', '/');

                    byte[] data = Convert.FromBase64String(attachData);
                    var file = new FileInfo(part.Filename);
                    File.WriteAllBytes(file.FullName, data);
                }
            }
        }
    }

Если я отправлю письмо вручную на тот же адрес (таким образом, получатель будет me), код загрузит вложение.

Буду признателен, если вы поможете.

1 Ответ

0 голосов
/ 12 декабря 2018

Я обнаружил, что вложения есть у ребенка MessagePart.Поэтому я написал рекурсивный метод для циклического прохождения всех частей для получения всех вложений.

    // List<FileInfo> Files = new List<FileInfo>();
    // client is created outside this method
    private void GetAttachmentsFromParts(IList<MessagePart> parts, string messageId)
    {
        if (parts == null) return;

        foreach (MessagePart part in parts)
        {
            if (!String.IsNullOrEmpty(part.Filename))
            {
                String attId = part.Body?.AttachmentId ?? null;
                if(String.IsNullOrWhiteSpace(attId)) continue;

                MessagePartBody attachPart = GmailServiceClient.Users.Messages.Attachments.Get("me", messageId, attId).Execute();

                // Converting from RFC 4648 base64 to base64url encoding
                // see http://en.wikipedia.org/wiki/Base64#Implementations_and_history
                String attachData = attachPart.Data.Replace('-', '+');
                attachData = attachData.Replace('_', '/');

                byte[] data = Convert.FromBase64String(attachData);
                var file = new FileInfo(part.Filename);
                Files.Add(file);
                File.WriteAllBytes(file.FullName, data);
            }

            if((part.Parts?.Count ?? 0) > 0)
                GetAttachmentsFromParts(part.Parts, messageId);
        }
    }

Все вложения будут сохранены в List<FileInfo> Files

...