IMAP / SMTP — thật
provider: imap_smtp. Test connection thật sự mở kết nối IMAP
(ImapFlow) và liệt kê folder thật. Đây là con đường chính để nhận
email vào Helpdesk (inbound_provider: imap).


IMAP / SMTP — thật
provider: imap_smtp. Test connection thật sự mở kết nối IMAP
(ImapFlow) và liệt kê folder thật. Đây là con đường chính để nhận
email vào Helpdesk (inbound_provider: imap).
Forward / Twilio WhatsApp — lưu cấu hình
forward chỉ lưu 1 địa chỉ forward; twilio_whatsapp lưu Account SID
OAuth — Gmail / Outlook / Custom
provider: gmail | outlook | custom_oauth. Hai chế độ: một chạm
(server đã có sẵn app Microsoft/Google chung do quản trị hệ thống cấu
hình — admin chỉ nhập tên rồi bấm 1 nút) hoặc app riêng (bring your
own app — admin tự nhập client ID/secret + endpoint, dùng khi provider
chưa được cấu hình sẵn hoặc chọn Custom OAuth). Mailbox được poll qua
IMAP XOAUTH2 và gửi qua SMTP XOAUTH2 — dùng chung pipeline
inbound/outbound. Thêm bao nhiêu connection cũng được.
Đây là đường đi mặc định và được khuyến nghị khi hệ thống đã bật sẵn app OAuth chung: admin không cần biết gì về Azure/Google, không nhập client ID/secret, không nhập mật khẩu mailbox — chỉ đặt tên connection và bấm một nút.
Trước khi admin dùng được nút một chạm, quản trị hệ thống (operator) phải đăng ký một app Microsoft Entra (và/hoặc một app Google) dùng chung cho toàn bộ Helpdesk — làm một lần, không phải mỗi mailbox một app.
Vào Entra admin center → App registrations → New registration, đặt tên bất kỳ (vd Helpdesk Mail).
Supported account types: chọn “Accounts in any organizational directory … and personal Microsoft accounts” (khớp mặc định HELPDESK_MICROSOFT_TENANT=common), hoặc “Accounts in this organizational directory only” nếu chỉ dùng nội bộ một tổ chức.
Redirect URI — loại Web — dán đúng: https://<webapp-host>/api/helpdesk/oauth/callback (prod), hoặc http://localhost:3100/api/helpdesk/oauth/callback (dev local).
API permissions → thêm quyền delegated: openid, email, profile, offline_access (Microsoft Graph) và IMAP.AccessAsUser.All, SMTP.Send (Office 365 Exchange Online). Nếu tổ chức yêu cầu, bấm Grant admin consent.
Certificates & secrets → tạo client secret mới (hạn tối đa 24 tháng) → copy giá trị ngay (chỉ hiện một lần) → ghi lại ngày hết hạn. Secret hết hạn sẽ làm toàn bộ mailbox đang dùng app này ngừng gửi/nhận cùng lúc — cần tạo secret mới và cập nhật env rồi khởi động lại backend.
Set trong backend/.env: HELPDESK_MICROSOFT_CLIENT_ID, HELPDESK_MICROSOFT_CLIENT_SECRET, HELPDESK_MICROSOFT_TENANT (mặc định common), HELPDESK_OAUTH_REDIRECT_URI — rồi khởi động lại backend. Chi tiết từng trường + scope string đầy đủ: OAuth: đăng nhập & phân bố data.
Bật SMTP AUTH trên từng mailbox sẽ kết nối (Exchange Online tắt mặc định): Set-CASMailbox -Identity <mbx> -SmtpClientAuthenticationDisabled $false. Đây là nguyên nhân phổ biến nhất của “nhận được mail nhưng không gửi được”.
Settings → Connections (hoặc bắt đầu trực tiếp từ New inbox) → Connect channel → chọn Email → chọn provider card Microsoft Outlook / 365 (hoặc Gmail).
Bước Connect chỉ hiện một ô — Connection name (đã điền sẵn tên gợi ý) — và một nút Connect with Microsoft. Không có ô client ID, secret hay tenant.
Bấm nút → chuyển sang trang đăng nhập Microsoft. Nếu tổ chức bật MFA/SSO, đăng nhập như bình thường → màn hình liệt kê quyền được yêu cầu (đọc/gửi email, thông tin cơ bản) → bấm Accept.
Trình duyệt tự quay lại đúng wizard đang mở (không văng ra Settings) — dừng ở bước Folder hoặc Finish, connection vừa tạo đã được chọn sẵn. Chọn folder cần theo dõi (nếu có) → bấm Create inbox.
Nếu bấm Cancel/Deny ở màn hình Microsoft, trình duyệt vẫn quay lại wizard ở bước Connect, hiện thông báo lỗi ngay tại chỗ (không phải màn hình trắng) — bấm nút để thử lại.
Ngay cả khi nút một chạm đã sẵn sàng, vẫn có link “Dùng app OAuth riêng” ngay dưới nút để mở form nhập tay — dùng khi muốn mailbox này backing bởi một app Azure/Google khác với app chung của hệ thống. Nếu không thấy nút một chạm mà chỉ thấy form nhập client ID/secret, nghĩa là quản trị hệ thống chưa cấu hình provider đó — xem phần “Dành cho quản trị viên hệ thống” ở trên, hoặc dùng tạm mục Dùng app OAuth riêng bên dưới.
needs_reauth)Nếu user thu hồi quyền ở phía Microsoft/Google, hoặc client secret bị xoay vòng mà chưa cập nhật env, connection sẽ chuyển sang trạng thái cần kết nối lại (needs_reauth) — cron ngừng nhận/gửi cho tới khi xử lý. Không cần tạo inbox lại:
| Lỗi | Nguyên nhân | Cách xử lý |
|---|---|---|
AADSTS50194 khi đăng nhập Microsoft |
App Azure đăng ký single-tenant nhưng hệ thống đang dùng tenant common |
Đổi HELPDESK_MICROSOFT_TENANT khớp loại tài khoản đã chọn khi tạo app, hoặc đổi app sang multi-tenant |
AADSTS50011 (redirect URI mismatch) |
Redirect URI dán trên Azure không khớp HELPDESK_OAUTH_REDIRECT_URI |
So lại chính xác từng ký tự (http/https, có/không dấu / cuối) |
Gửi reply lỗi 535 5.7.3 Authentication unsuccessful |
SMTP AUTH đang tắt trên mailbox/tenant | Chạy Set-CASMailbox -Identity <mbx> -SmtpClientAuthenticationDisabled $false; hoặc thiếu quyền SMTP.Send chưa được consent |
Connection hiện “Cần kết nối lại” (needs_reauth) |
Quyền bị thu hồi, hoặc secret đã xoay vòng | Bấm Kết nối lại ở Settings → Connections hoặc trong slideover sửa |
Dùng mục này khi provider chưa được cấu hình sẵn ở mục một chạm phía trên (nút một chạm không hiện, chỉ thấy form), hoặc khi cố tình muốn một mailbox dùng một app Azure/Google khác với app chung của hệ thống, hoặc cho Custom OAuth (provider OAuth2 + IMAP tuỳ ý). Đây là cách thêm một hộp thư (Gmail, Outlook/365, hay bất kỳ provider OAuth2 + IMAP nào) làm nguồn inbound mà không lưu mật khẩu — dùng OAuth chính chủ của provider. Client ID/secret + endpoint lưu trên chính connection (mã hoá at rest), không phải biến môi trường — nên một admin có thể thêm nhiều mailbox, mỗi cái backing bởi một OAuth app khác nhau.
Thiết lập OAuth app (ví dụ Google — một lần cho mỗi app):
Vào Google Cloud Console → tạo/chọn project → APIs & Services → OAuth consent screen: thêm scope https://mail.google.com/, thêm tài khoản Gmail cần kết nối vào Test users (nếu app chưa verify).
Credentials → Create credentials → OAuth client ID → loại Web application. Ở Authorized redirect URIs, dán đúng URI mà wizard hiển thị:
http://localhost:3100/api/helpdesk/oauth/callbackhttps://<webapp-host>/api/helpdesk/oauth/callbackBật IMAP trong hộp Gmail (Gmail → Settings → Forwarding and POP/IMAP → Enable IMAP).
(Tuỳ chọn, chỉ khi prod) đặt redirect URI chuẩn cho backend — mặc định dev đã đúng:
HELPDESK_OAUTH_REDIRECT_URI=https://<webapp-host>/api/helpdesk/oauth/callbackKhông cần set client ID/secret ở env nữa — chúng nhập trong wizard.
Kết nối (agent/admin):
Wizard New inbox → Connect a new channel → chọn Gmail, Outlook, hoặc Custom OAuth (IMAP) → nếu provider đó đã cấu hình một chạm, bấm link “Dùng app OAuth riêng” để mở form nhập tay này.
Form OAuth hiện ra với redirect URI cần whitelist (copy vào app ở bước trên) + các field: tên connection, địa chỉ mailbox, Client ID, Client secret. Gmail/Outlook đã điền sẵn authorize/token URL + scope + IMAP/SMTP host; Custom thì mở Edit endpoints / scopes để nhập tay. Riêng Outlook có thêm ô Tenant (xem note dưới).
Bấm Connect & authorize → chuyển sang trang đồng ý của provider → đồng ý quyền → trình duyệt quay lại đúng wizard đang mở, dừng ở bước Folder/Finish với connection vừa tạo đã connected và được chọn sẵn (giống luồng một chạm ở trên — không còn văng ra Settings nữa).
Chọn folder (nếu có) → Create inbox để hoàn tất trên connection vừa kết nối.
Không có nút “Tạo connection” độc lập — connection luôn được tạo trong lúc tạo inbox đầu tiên dùng nó.
Vào Settings → Connections → bấm Connect channel (hoặc bắt đầu trực tiếp từ New inbox).
Chọn Channel (Email/WhatsApp) → chọn Provider. Với Email, chọn IMAP/SMTP.
Nhập thông tin IMAP (incoming): Host, Port, Username, Password, SSL/TLS. Nhập SMTP (outgoing): có thể tick “Use the same credentials as IMAP” để dùng chung tài khoản, hoặc nhập riêng Host/Port/Username/Password/STARTTLS.
Bấm Test connection. Bước này chỉ kiểm tra IMAP thật (kết nối + liệt kê folder) — SMTP không được test ở bước này, chỉ được lưu kèm theo. Test thành công mới cho phép Continue.
Tiếp tục các bước tạo inbox (routing/folder, đặt tên) — xem chi tiết ở Tạo inbox & định tuyến. Khi bấm Create inbox ở bước cuối, connection và mật khẩu IMAP/SMTP vừa nhập được lưu (mã hoá) cùng lúc.
Settings → Connections → bấm biểu tượng bút chì trên connection cần sửa.
Với provider IMAP/SMTP, slideover hiện 2 khối Incoming (IMAP) và Outgoing (SMTP). Trường Password luôn để trống khi mở (không hiện lại mật khẩu cũ) kèm ghi chú “Leave blank to keep the current password.”
Có thể bấm Test IMAP ngay trong màn hình sửa để kiểm tra thông tin vừa gõ.
Bấm Save để lưu.
Mask khi đọc
Các trường nhạy cảm (imap_password, smtp_password, oauth_token,
oauth_refresh_token, twilio_auth_token, webhook_secret) luôn trả
về *** nếu đã có giá trị, hoặc null nếu chưa từng đặt — không bao
giờ lộ giá trị thật qua API.
Mã hoá khi ghi
Trước khi ghi xuống DB, các trường trên được mã hoá AES-256-GCM bằng khoá suy ra từ secret của ODP. Chỉ backend Helpdesk giải mã được (lúc IMAP connect / gửi SMTP).
SMTP thực sự chỉ được test tại tab Outbound của từng inbox (không phải ở màn hình Connection), vì mỗi inbox có thể dùng SMTP dùng chung (Shared — theo connection) hoặc SMTP riêng (Custom). Nút Test SMTP chỉ hiện khi chọn mode Custom. Xem chi tiết mục outbound override ở Tạo inbox & định tuyến.
Danh sách folder IMAP hiển thị ở tab Folder của inbox không phải nhập tay — nó được lưu tự động mỗi lần Test IMAP thành công (test = tiện thể fetch danh sách folder). Nếu đổi mật khẩu hộp thư ngoài đời và cần cập nhật lại danh sách folder, chạy lại Test IMAP để làm mới.