# Code mẫu đọc thư hotmail

# 1. Đọc hòm thư qua IMAP

import email
import imaplib

import requests
from email.header import decode_header

IMAP_HOST = 'outlook.office365.com'
IMAP_PORT = 993


def decode_mime_words(s):
    decoded_words = decode_header(s)
    return ''.join([
        word.decode(encoding or 'utf-8') if isinstance(word, bytes) else word
        for word, encoding in decoded_words
    ])


class Hotmail:
    def __init__(self, mail: str, password: str, client_id: str, refresh_token: str):
        self.mail = mail
        self.password = password
        self.client_id = client_id
        self.refresh_token = refresh_token
        self.access_token = None

    def get_access_token(self):
        data = {
            'client_id': self.client_id,
            'grant_type': 'refresh_token',
            'refresh_token': self.refresh_token,
        }
        res = requests.post('https://login.live.com/oauth20_token.srf', data=data)
        print(res.text)
        print(res.json()['access_token'])
        self.access_token = res.json()['access_token']

    def generate_auth_str(self):
        # Generate OAuth2 authentication string using the access token
        auth_string = f'user={self.mail}\1auth=Bearer {self.access_token}\1\1'
        return auth_string

    def get_messages(self):
        client = imaplib.IMAP4_SSL(IMAP_HOST, IMAP_PORT)
        auth_string = self.generate_auth_str()
        encoded_auth_string = auth_string.encode()
        client.authenticate('XOAUTH2', lambda x: encoded_auth_string)
        folders = ['INBOX', 'JUNK']  # DELETED, DRAFTS, INBOX, JUNK, NOTES, OUTBOX, SENT
        for folder in folders:
            client.select(folder)
            status, messages = client.search(None, 'ALL')
            email_ids = messages[0].split()
            for num in email_ids:
                _, msg_data = client.fetch(num, '(RFC822)')
                self.extract_email(msg_data)

        client.logout()

    def extract_email(self, msg_data):
        for response_part in msg_data:
            if isinstance(response_part, tuple):
                msg = email.message_from_bytes(response_part[1])
                subject, encoding = decode_header(msg["Subject"])[0]
                if isinstance(subject, bytes):
                    subject = subject.decode(encoding if encoding else 'utf-8')
                from_ = msg.get("From")
                date = msg.get("Date")
                text = ''
                html = ''
                if msg.is_multipart():
                    for part in msg.walk():
                        content_type = part.get_content_type()
                        content_disposition = str(part.get("Content-Disposition"))
                        if content_type == "text/plain" and "attachment" not in content_disposition:
                            text = part.get_payload(decode=True).decode('utf-8', errors='replace')
                        elif content_type == "text/html":
                            html = part.get_payload(decode=True).decode('utf-8', errors='replace')
                else:
                    content_type = msg.get_content_type()
                    payload = msg.get_payload(decode=True)
                    if content_type == "text/plain":
                        text = payload.decode('utf-8', errors='replace')
                    elif content_type == "text/html":
                        html = payload.decode('utf-8', errors='replace')

                print(f'Tiêu đề: {subject}')
                print(f'Người gửi: {from_}')
                print(f'Nội dung text: {text}')
                print(f'Nội dung html: {html}')
                print(f'Ngày gửi: {date}')
                print("=" * 100)


# MUA HOTMAIL SLL TẠI https://muamail.store
hotmail_str = 'mail|pass|client_id|token'
_mail, _password, _client_id, _token = hotmail_str.split('|')
hotmail = Hotmail(_mail, _password, _client_id, _token)
hotmail.get_access_token()
hotmail.get_messages()
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using MailKit.Net.Imap;
using MailKit;
using MimeKit;
using Newtonsoft.Json;
using MailKit.Search;
using MailKit.Security;


// MUA HOTMAIL / OUTLOOK SLL TẠI https://muamail.store
public class Hotmail
{
    private readonly string _mail;
    private readonly string _password;
    private readonly string _clientId;
    private readonly string _refreshToken;
    private string _accessToken;

    private const string IMAPHost = "outlook.office365.com";
    private const int IMAPPort = 993;

    public Hotmail(string mail, string password, string clientId, string refreshToken)
    {
        this._mail = mail;
        this._password = password;
        this._clientId = clientId;
        this._refreshToken = refreshToken;
    }

    public async Task GetAccessTokenAsync()
    {
        var data = new Dictionary<string, string>
        {
            { "client_id", _clientId },
            { "grant_type", "refresh_token" },
            { "refresh_token", _refreshToken }
        };

        using (var client = new HttpClient())
        {
            var response = await client.PostAsync("https://login.live.com/oauth20_token.srf", new FormUrlEncodedContent(data));
            response.EnsureSuccessStatusCode();
            var jsonResponse = await response.Content.ReadAsStringAsync();
            dynamic result = JsonConvert.DeserializeObject(jsonResponse);
            _accessToken = result.access_token;
            Console.WriteLine($"Access Token: {_accessToken}");
        }
    }

    private string GenerateAuthString()
    {
        // Generate OAuth2 authentication string using the access token
        return $"user={_mail}\u0001auth=Bearer {_accessToken}\u0001\u0001";
    }

    public async Task GetMessagesAsync()
    {
        using (var client = new ImapClient())
        {
            await client.ConnectAsync(IMAPHost, IMAPPort, true);
            var authString = GenerateAuthString();
            await client.AuthenticateAsync(new SaslMechanismOAuth2(_mail, _accessToken));

            var folders = new[] { "INBOX", "JUNK" };
            foreach (var folder in folders)
            {
                await client.Inbox.OpenAsync(FolderAccess.ReadOnly);
                var results = await client.Inbox.SearchAsync(SearchQuery.All);

                foreach (var uid in results)
                {
                    var message = await client.Inbox.GetMessageAsync(uid);
                    ExtractEmail(message);
                }
            }

            await client.DisconnectAsync(true);
        }
    }

    private void ExtractEmail(MimeMessage message)
    {
        string subject = message.Subject ?? "No Subject";
        string from = message.From.ToString();
        string date = message.Date.ToString();
        string textBody = message.TextBody ?? "";
        string htmlBody = message.HtmlBody ?? "";

        Console.WriteLine($"Tiêu đề: {subject}");
        Console.WriteLine($"Người gửi: {from}");
        Console.WriteLine($"Nội dung text: {textBody}");
        Console.WriteLine($"Nội dung html: {htmlBody}");
        Console.WriteLine($"Ngày gửi: {date}");
        Console.WriteLine(new string('=', 100));
        Console.ReadLine();
    }
}

public class Program
{
    public static async Task Main(string[] args)
    {
        string hotmailStr = "mail|pass|client_id|token";
        var parts = hotmailStr.Split('|');
        var mail = parts[0];
        var password = parts[1];
        var clientId = parts[2];
        var token = parts[3];

        var hotmail = new Hotmail(mail, password, clientId, token);
        await hotmail.GetAccessTokenAsync();
        await hotmail.GetMessagesAsync();
    }
}

# 2. Đọc hòm thư qua POP3

import base64
import poplib
from email import parser

import requests
from email.header import decode_header

POP3_URL = 'outlook.office365.com'
PORT3_PORT = 995  # POP3 SSL


def decode_mime_words(s):
    decoded_words = decode_header(s)
    return ''.join([
        word.decode(encoding or 'utf-8') if isinstance(word, bytes) else word
        for word, encoding in decoded_words
    ])


class Hotmail:
    def __init__(self, mail: str, password: str, client_id: str, refresh_token: str):
        self.mail = mail
        self.password = password
        self.client_id = client_id
        self.refresh_token = refresh_token
        self.access_token = None

    def get_access_token(self):
        data = {
            'client_id': self.client_id,
            'grant_type': 'refresh_token',
            'refresh_token': self.refresh_token
        }
        res = requests.post('https://login.live.com/oauth20_token.srf', data=data)
        print(res.text)
        self.access_token = res.json()['access_token']

    def generate_auth_str(self):
        # Generate OAuth2 authentication string using the access token
        auth_string = f"user={self.mail}\1auth=Bearer {self.access_token}\1\1"
        return auth_string

    def get_messages(self):
        server = poplib.POP3_SSL(POP3_URL, PORT3_PORT)
        # OAuth2
        auth_string = self.generate_auth_str()
        encoded_auth_string = base64.b64encode(auth_string.encode("utf-8")).decode("utf-8")
        server._shortcmd(f'AUTH XOAUTH2')
        server._shortcmd(f'{encoded_auth_string}')

        messages = len(server.list()[1])
        print(f"Tìm thấy {messages} hòm thư.")

        # Retrieve email content
        for index in range(messages):
            response, lines, octets = server.retr(index + 1)
            msg_content = b"\n".join(lines).decode("utf-8", errors='replace')
            msg = parser.Parser().parsestr(msg_content)
            subject = ""
            from_ = ""
            text = ""
            html = ""
            date = ""
            if 'Subject' in msg:
                subject = decode_mime_words(msg['Subject'])
            if 'From' in msg:
                from_ = decode_mime_words(msg['From'])
            if 'Date' in msg:
                date = decode_mime_words(msg['Date'])

            if msg.is_multipart():
                for part in msg.walk():
                    content_type = part.get_content_type()
                    content_disposition = str(part.get("Content-Disposition"))
                    if content_type == "text/plain" and "attachment" not in content_disposition:
                        charset = part.get_content_charset() or 'utf-8'
                        text += part.get_payload(decode=True).decode(charset, errors='replace')
                    elif content_type == "text/html" and "attachment" not in content_disposition:
                        charset = part.get_content_charset() or 'utf-8'
                        html += part.get_payload(decode=True).decode(charset, errors='replace')
            else:
                content_type = msg.get_content_type()
                if content_type == "text/plain":
                    charset = msg.get_content_charset() or 'utf-8'
                    text = msg.get_payload(decode=True).decode(charset, errors='replace')
                elif content_type == "text/html":
                    charset = msg.get_content_charset() or 'utf-8'
                    html = msg.get_payload(decode=True).decode(charset, errors='replace')

            print(f"Email thứ: {index + 1}:")
            print(f'Tiêu đề: {subject}')
            print(f'Người gửi: {from_}')
            print(f'Nội dung text: {text}')
            print(f'Nội dung html: {html}')
            print(f'Ngày gửi: {date}')
            print("=" * 100)


# MUA HOTMAIL SLL TẠI https://muamail.store
hotmail_str = 'mail|pass|client_id|token'
_mail, _password, _client_id, _token = hotmail_str.split('|')
hotmail = Hotmail(_mail, _password, _client_id, _token)
hotmail.get_access_token()
hotmail.get_messages()
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using MailKit.Security;
using MimeKit;
using Newtonsoft.Json.Linq;

// MUA HOTMAIL / OUTLOOK SLL TẠI https://muamail.store
namespace EmailFetcher
{
    public class Hotmail
    {
        private const string Pop3Url = "outlook.office365.com";
        private const int Pop3Port = 995;

        private readonly string _mail;
        private readonly string _password;
        private readonly string _clientId;
        private readonly string _refreshToken;
        private string _accessToken;

        private static readonly HttpClient HttpClient = new HttpClient();

        public Hotmail(string mail, string password, string clientId, string refreshToken)
        {
            _mail = mail ?? throw new ArgumentNullException(nameof(mail));
            _password = password;
            _clientId = clientId ?? throw new ArgumentNullException(nameof(clientId));
            _refreshToken = refreshToken ?? throw new ArgumentNullException(nameof(refreshToken));
        }

        public async Task GetAccessTokenAsync()
        {
            var requestContent = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("client_id", _clientId),
                new KeyValuePair<string, string>("grant_type", "refresh_token"),
                new KeyValuePair<string, string>("refresh_token", _refreshToken),
            });

            var response = await HttpClient.PostAsync("https://login.live.com/oauth20_token.srf", requestContent);
            response.EnsureSuccessStatusCode();

            var responseString = await response.Content.ReadAsStringAsync();
            var json = JObject.Parse(responseString);
            _accessToken = json.Value<string>("access_token") ?? throw new InvalidOperationException("Không tìm thấy access_token trong response.");
        }

        private string GenerateAuthString()
        {
            if (string.IsNullOrEmpty(_accessToken))
                throw new InvalidOperationException("Access token is not available. Call GetAccessTokenAsync() first.");

            var authString = $"user={_mail}\u0001auth=Bearer {_accessToken}\u0001\u0001";
            return Convert.ToBase64String(Encoding.UTF8.GetBytes(authString));
        }

        public async Task GetMessagesAsync()
        {
            if (string.IsNullOrEmpty(_accessToken))
                throw new InvalidOperationException("Access token is not available. Call GetAccessTokenAsync() first.");

            var client = new MailKit.Net.Pop3.Pop3Client();

            await client.ConnectAsync(Pop3Url, Pop3Port, SecureSocketOptions.SslOnConnect);

            var authString = GenerateAuthString();
            await client.AuthenticateAsync(new SaslMechanismOAuth2(_mail, _accessToken));


            int messageCount = client.Count;
            Console.WriteLine($"Tìm thấy {messageCount} hòm thư.");

            for (int i = 0; i < messageCount; i++)
            {
                var message = await client.GetMessageAsync(i);
                ExtractMessage(i + 1, message);
            }

            await client.DisconnectAsync(true);
        }

        /// <summary>
        /// Trích xuất thông tin của một hòm thư.
        /// </summary>
        /// <param name="index"></param>
        /// <param name="message"></param>
        private void ExtractMessage(int index, MimeMessage message)
        {
            var subject = message.Subject ?? string.Empty;
            var from = message.From.ToString() ?? string.Empty;
            var date = message.Date.ToString("dd/MM/yyyy HH:mm:ss");
            var text = string.Empty;
            var html = string.Empty;

            if (message.TextBody != null)
            {
                text = message.TextBody;
            }

            if (message.HtmlBody != null)
            {
                html = message.HtmlBody;
            }

            Console.WriteLine($"Email thứ: {index}:");
            Console.WriteLine($"Tiêu đề: {subject}");
            Console.WriteLine($"Người gửi: {from}");
            Console.WriteLine($"Ngày gửi: {date}");
            Console.WriteLine($"Nội dung text: {text}");
            Console.WriteLine($"Nội dung html: {html}");
            Console.WriteLine(new string('=', 100));
        }

    }

    class Program
    {
        static async Task Main(string[] args)
        {
            string email = "[email protected]";
            string password = "your-password";
            string clientId = "your-clientid";
            string refreshToken = "your-refreshtoken";

            var hotmail = new Hotmail(email, password, clientId, refreshToken);

            try
            {
                await hotmail.GetAccessTokenAsync();
                await hotmail.GetMessagesAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Đã xảy ra lỗi: {ex.Message}");
            }
            Console.ReadLine();
        }
    }
}