← Back to docs

Mail Support Assistant

Language: SV | EN | SV

Mail Support Assistant

Mail Support Assistant är ett adminkonfigurerat supportmailflöde för Tools och den fristående PHP-klienten som ligger under public/tornevall-tools-mail-assistant.

Vad den gör

  • lagrar IMAP-mailboxar i Tools admin
  • lagrar regelstyrd matchning på From, To, Subject och valfri body-text
  • tillåter per regel statiska autosvar eller Tools/OpenAI-stödda svar
  • stöder per regel egen avsändare, BCC, footer, responder/persona/mood/custom instruction, vald AI-modell och reasoning effort
  • stöder mailboxnivåns AI-triage för omatchade mail med sorterade add-row If... + Instructions...-regler plus en strikt mailboxägd sista fallback
  • låter den fristående klienten avgöra om ett hanterat mail ska flyttas till en folder eller raderas efter svar
  • kan nu synka behandlade mailtrådar tillbaka till Tools som spårade supportärenden, med både trådad Tools-adminvy och publik ärendelänk som kan delas med mottagaren
  • varje oläst inkommande mailboxmail som inte redan är markerat som läst eller redan är ett assistentskickat loopmail rapporteras nu också direkt till Tools när standalone-runnern hittar det, redan innan svar/no-match-hanteringen har bestämt slututfallet
  • centraliserade Tools-ärenden kan nu också lagra additiva fullständiga inbound-/outbound-bodyfält samt metadata om vilken runner/server som hanterade mailet, så admin kan läsa själva innehållet även när cronjobbet kördes på en annan host
  • centraliserade Tools-ärenden kan nu också lagra råa inbound-headers, parsade headerkartor och rå/plain/HTML-varianter av bodyn, så admin kan inspektera hanterade eller ignorerade mail mer som i en riktig fjärrmailklient
  • obesvarade eller omatchade synkade trådar hålls nu också tydligt synliga i Tools som uppföljningsärenden, så operatören kan öppna dem senare i stället för att de bara försvinner i standalone-runnerns senaste körningssammanfattning
  • den trådade ärendesidan i Tools kan nu också utkastgenerera och skicka ett svar direkt från Tools med ett operatörsinstruktionsfält, en redigerbar svarstext och ett Tools-hostat utskick
  • samma trådade ärendesida i Tools har nu också en tillfällig mood-/tonruta samt explicita val för modell och reasoning effort, så operatören kan styra ett manuellt utkast tydligare utan att först ändra mailboxregeln
  • hälsning och avslutning normaliseras nu också automatiskt på den Tools-sidiga ärendesidan, så både genererade utkast och slutligt skickade svar inte längre råkar tappa inledande hälsning eller footer/signatur bara för att modellen utelämnade dem en gång
  • dessa Tools-svar från den trådade ärendesidan genererar och sparar nu också ett stabilt reply issue-id när ett äldre överlämnat ärende fortfarande saknade ett, så det utgående subjectet åter får samma spårningstagg i stil med [Ärende MSA-…] i stället för att falla tillbaka till ett vanligt Re:-subject
  • när ett relevant oläst mail har lämnats över framgångsrikt till det centraliserade uppföljningsflödet i Tools kan standalone-runnern nu markera mailboxkopian som läst, så samma olästa mail inte fortsätter komma tillbaka bara för att den manuella uppföljningen nu sker i Tools
  • gamla synkade trådar kan nu raderas direkt från Tools admins ärendelista/detaljsida, och admins kan också bulkstäda äldre synkade trådar efter ålder/status från samma adminyta
  • recent-case-korten på /admin/mail-support-assistant försvinner nu också direkt när en synkad tråd raderas, i stället för att operatören måste vänta på en full sidomladdning
  • kan valfritt skicka ett operatörsmejl efter en körning med en sammanfattning av de mail som inte besvarades
  • lämnar orörda mail helt orörda om ingen regel matchar
  • håller standalone-runtime helt framework-fri (vanlig PHP, inget Laravel-runtimekrav)

Förutsättningar

Innan Mail Support Assistant faktiskt kan fungera i drift behöver följande vara på plats:

Tools / konto

  • ett riktigt Tools- / ToolsAPI-konto på samma Tools-host som ska leverera config/API-anropen
  • åtkomst till admin-UI:t på /admin/mail-support-assistant
  • minst en konfigurerad mailbox i Tools admin
  • en personlig klienttoken från Tools admin:
    • provider_mail_support_assistant
    • aktiv
    • AI-kapabel (is_ai=1)
  • godkänd provider_openai-access för tokenägaren om någon regel eller omatchad fallback använder AI och ägaren inte är admin

Valfria Tools-krav

  • en dedikerad relay-token provider_mail_support_assistant_mailer om utgående mail ska skickas via POST /api/mail-support-assistant/send-reply
  • rättigheten mail-support-assistant.relay för relay-tokenets ägare när Tools-relay ska tillåtas för icke-admin-användare

Mail / runtime

  • fungerande IMAP-uppgifter lagrade i Tools admin för varje mailbox som runnern ska polla
  • en nåbar Tools base URL från standalone-runtime
  • en vald strategi för utgående transport:
    • lokal SMTP
    • PHP mail()
    • eget MTA-kommando
    • eller Tools relay
  • PHP-runtime med nödvändiga extensioner och skrivbar lokal storage/ för loggar, sammanfattningar och valfri lokal state

Praktisk driftnot

  • den fristående klienten hittar inte på mailboxkonfiguration lokalt; mailboxar, regler, responder-defaults, omatchade fallback-rader och större delen av beteendet styrs först i Tools
  • om det saknas Tools-konto, giltig klienttoken eller mailboxkonfiguration i Tools admin så har supportassistenten inte tillräckligt underlag för att köra

Support / ändringar / issue tracking

Om du behöver hjälp, vill beställa en ändring eller rapportera problem i den fristående klienten ska du använda GitHub tickets här:

Det repot är rätt plats för runtime-/klientproblem, installationsfrågor och feature requests för den fristående Mail Support Assistant-klienten.

Tools admin-UI

Admin-only-konfiguration finns på:

  • /admin/mail-support-assistant

Därifrån kan du:

  1. skapa/uppdatera mailboxar
  2. lägga till sorterade svarregler per mailbox
  3. rotera den dedikerade tokenen för standalone-klienten (provider_mail_support_assistant)
  4. rotera en dedikerad relay-token (provider_mail_support_assistant_mailer) för utgående mailskick via Tools
  5. granska nyligen synkade supportärenden som standalone-assistenten skickat tillbaka in i Tools
  6. radera en gammal synkad tråd direkt eller bulkstäda äldre synkade trådar efter ålder/status
  7. öppna ett trådat ärende och besvara det direkt från Tools genom att skapa ett utkast, redigera svarstexten och skicka det via Tools mailtransport
  8. styra ett direktutkast med en egen tillfällig mood/ton samt explicit modell och reasoning innan utkastet genereras

Mailboxinställningarna har nu också en sektion för generiskt AI-svar på omatchade mail. Där kan admin styra mailboxnivå-fallback för mail som inte träffar någon explicit regel, inklusive:

  • aktivera/inaktivera AI-fallback för omatchade mail
  • valfri modellöverskrivning för just den mailboxen
  • valfri reasoning-överskrivning för just den mailboxen
  • valfri mailboxnivå-tröskel för spam score som stoppar svar och lämnar mailet oläst när score är för hög
  • en strikt mailboxnivå-fallback med egen kryssruta, allow-condition och sista instruktionstext
  • mailboxspecifika add-row If...-regler som beskriver vilka annars omatchade mail som får besvaras före denna sista fallback
  • per-rad instruktionstext för dessa avancerade omatchade svar
  • valfri per-rad override för footer/modell/reasoning

Tools admin-sidan stöder nu också lättviktig AJAX-sparning för create/update/delete av mailboxar och regler, så vanliga ändringar inte längre måste gå genom en full sidomladdning. Omatchade fallback-IF-rader sparas nu också direkt via AJAX med lokal busy-/success-status under radens knapp, och radering tar bort raden direkt samt återställer tomläget när sista raden tas bort.

Viktig prioritetsregel:

  • mailboxnivåns generiska AI-inställningar används bara när ingen regel matchade mailet
  • fallbacken för omatchade mail aktiveras nu bara av mailboxens checkbox i Tools-konfigurationen; miljöflaggor räcker inte längre för att slå på den
  • om den checkboxen är avstängd får standalone-klienten inte utvärdera några avancerade no-match-rader eller mailboxens sista fallback alls, även om äldre IF-/instruktionstexter fortfarande råkar vara ifyllda
  • AI för omatchade mail körs nu först som ett strikt JSON-beslut: standalone-klienten skickar bara svar när AI uttryckligen returnerar ett strukturerat tillåt-beslut med hög säkerhet
  • om det varken finns aktiva no-match-rader eller mailboxens egen sista allow-condition/instruktion räknas no-match-AI som ofullständigt konfigurerad och inget fallbacksvar skickas
  • no-match-rader körs i sort_order-ordning och kan falla vidare till senare rader om en tidigare rad avvisas
  • efter dessa avancerade rader kan mailboxens egen sista fallback fortfarande köras som sista omatchade väg när checkboxen är aktiv och båda textfälten är ifyllda
  • samma fall-through gäller nu också när en enskild no-match-rad träffar ett radlokalt AI-/API-fel; standalone-runnern loggar den felande raden men fortsätter ändå med senare aktiva rader innan den ger upp
  • om flera regler matchar samma inkommande mail utvärderar standalone-klienten nu alla matchande regler och väljer först den mest specifika regeln (flest aktiva matchfält, sedan längst sammanlagd matchtext, därefter sort_order)
  • den valda regeln och övriga matchande kandidater sparas nu i standalone-diagnostiken så regelkrockar kan granskas i efterhand
  • om en matchad regel har ai_enabled=true skickar standalone-klienten nu regelns responder/persona/custom instruction/modell/reasoning till Tools som explicita AI-override-fält för just det svaret
  • den statiska templaten används bara som fallback om AI-anropet misslyckas eller returnerar ett tomt/icke-användbart svar
  • skippade eller obesvarade olästa mail trycks nu också uttryckligen tillbaka till oläst när IMAP-servern stöder att \\Seen rensas, vilket minskar att fetches råkar lämna fel read-state efter sig
  • lokal message-state kan nu också spara lätta tråd-/konversationsutdrag så senare AI-svar kan fortsätta en konversation mer naturligt utan att den historiken används som dedupe-gate
  • när In-Reply-To / References länkar ett uppföljningsmail till en tidigare hanterad konversation kan standalone-runnern nu också återanvända den tidigare matchade regeln eller prioritera den tidigare använda no-match-raden så tråden hålls kvar på samma supportspår
  • standalone-genererade svar sparar nu också ett genererat utgående reply_message_id i lokal state, vilket gör att senare Gmail-/Outlook-följdmail lättare kan kopplas tillbaka till samma konversation även när användaren svarar på assistentens skickade mail i stället för originalmailet
  • standalone-genererade svar kan nu också stämpla in ett stabilt ärende-/case-id i ämnesraden (standardformat ungefär [Ärende MSA-ABC12345]), och senare svar i samma tråd återanvänder samma tagg i stället för att appenda ett nytt ärende-id varje gång konversationen besvaras
  • standalone-genererade HTML-svar konverterar nu också vanlig markdown från AI-/operatörstext till riktig HTML-struktur (till exempel rubriker, listor, länkar, betoning och inline-kod) i stället för att visa råa markdown-markörer i det stylade svaret
  • om ett uppföljningsmail kommer i ett äldre/trasigare format där användbara In-Reply-To / References saknas kan standalone-runnern nu ändå prova en fallback via normaliserat subject + samma deltagare innan mailet behandlas som en helt ny no-match-konversation
  • om den länkade tidigare konversationen redan godkänts via no-match-AI kan standalone-runnern nu fortsätta direkt på samma tidigare använda no-match-rad för uttryckligt länkade följdmail i stället för att köra om det första allow-condition-steget från början på samma tråd
  • rate-limitade AI-fel (429 / Too Many Attempts) försöks nu om automatiskt innan standalone-klienten ger upp AI-svaret för regeln
  • om en AI-aktiverad regel saknar explicit template_text-fallback skickar standalone-klienten inte längre den gamla generiska meningen Thank you for your message. We have reviewed it. när AI fallerar; svaret avbryts i stället och felet loggas
  • klartextmail från kontaktformulär som innehåller body-labels som From:, Subject:, Sender IP: och Message Body: bevarar nu också själva problemtexten i standalone-sammanfattningar/AI-kontext i stället för att falla ner till bara den första headerliknande raden
  • HTML-baserade inkommande mail dekodas nu också till läsbar plain text innan regelmatchning, AI-triage för omatchade mail, bifogade request-sammanfattningar och sparade lokala message copies byggs, så standalone-klienten inte längre beter sig som om bara subject fanns när body kom som HTML
  • MIME-bodydekodningen är nu charset-medveten, vilket gör att icke-UTF8 eller på annat sätt trasiga inkommande mail oftare ger användbar body-text i stället för förvanskad AI-/regelmatchningskontext
  • multipart-baserade inkommande mail väljer nu också den rikaste läsbara MIME-delen i stället för att alltid behålla första icke-tomma delen, vilket minskar fallen där en kort wrapper- eller stubtext tidigare dolde nästan hela den riktiga bodyn
  • när den strikta omatchade fallbacken faktiskt skickar ett svar markerar standalone-runnern mailet som läst direkt så att det inte plockas upp igen av pollningen av olästa mail

Den genererade tokenen sparas som en personlig api_keys-rad och markeras automatiskt som AI-kapabel (is_ai=1).

Direktutkast på ärendesidan i Tools

På den trådade ärendesidan i Tools är direkt-svarsboxen nu avsiktligt uppdelad i fyra operatörsfält:

  • Instruction / operator note – huvudinstruktionen för just detta svar
  • Mood / tone – en tillfällig ton för detta utkast, till exempel kort, tydlig, fast
  • Model – explicit AI-modell för just detta genererade utkast
  • Reasoning effort – explicit resonemangsnivå för just detta genererade utkast

Viktigt beteende:

  • dessa tre utkastskontroller påverkar bara utkastgenereringen; de skriver inte permanent över mailboxregelns config
  • den slutliga svarstexten kan fortfarande redigeras fritt före skickning
  • Tools normaliserar nu hälsning och avslutning automatiskt både på genererade utkast och på det slutligt skickade svaret, så ett saknat Hej/Hello eller en tappad footer läggs tillbaka före utskick
  • den automatiska normaliseringen är tänkt att täcka oavsiktliga bortfall, inte att hindra operatören från att justera själva mitteninnehållet i svaret

Relay-token (provider_mail_support_assistant_mailer) är personliga icke-globala nycklar och är avsedda endast för POST /api/mail-support-assistant/send-reply. De är inte AI-mottagartokens.

Webbgränssnittet använder nu också mer generiska exempelvärden för vanliga supportflöden, till exempel orderstatus, referensnummer och allmän kundsupport, i stället för specialfallsliknande juridik- eller copyrightexempel.

Trådad ärendespårning

  • Tools lagrar nu synkade Mail Support Assistant-konversationer som trådade supportärenden.
  • Adminoperatörer kan granska dem direkt från /admin/mail-support-assistant och därifrån öppna en separat trådad ärendesida.
  • Standalone-runnern trycker nu också in varje relevant upptäckt oläst mail i den trådade Tools-vyn direkt när mailet hittas, så operatören fortfarande kan bygga regler eller begära ett manuellt AI-svar senare även när assistenten inte svarade under just den körningen.
  • Trådar vars senaste utfall blev omatchat, skippat eller "reply not sent" ligger nu kvar där som tydliga uppföljningsärenden i stället för att bara synas i standalone-diagnostiken för senaste körningen.
  • Den trådade ärendesidan kan nu också visa centralt lagrad full body-text/HTML samt vilken runner/server som synkade respektive meddelande.
  • Samma trådade ärendesida kan nu också generera AI-utkast från en operatörsinstruktion, skicka det färdiga svaret direkt via Tools eller markera ärendet som manuellt hanterat utan outbound-svar.
  • När ett skippat / omatchat / reply not sent-ärende har lämnats över framgångsrikt till Tools som needs_attention kan standalone-runnern nu markera det mailboxmailet som läst, så uppföljningen centreras i Tools i stället för att mailet återförsökas som oläst om och om igen.
  • Standalone-dashboarden kan också länka varje meddelandekort tillbaka till motsvarande Tools-ärende när tråden redan hunnit synkas.
  • Utgående assistentsvar kan nu också bifoga en publik ärendelänk till mottagaren när standalone-runtime först lyckas skapa den länken i Tools.
  • Den synkvägen kör nu också även när standalone-runnern inte kunde bygga någon stabil lokal message-state-nyckel, så hanterade eller ignorerade mail fortfarande ska dyka upp i Tools i stället för bara i den lokala runtime-miljön.
  • Admin kan nu radera en enskild synkad tråd från ärendelistan eller ärendedetaljen, och ärendelistan innehåller också ett bulkstädformulär för äldre synkade trådar som inte längre behövs.
  • Adminoperatörer kan nu också lägga återkommande avsändare i en mailboxnivålista för ignored senders direkt från den trådade ärendesidan, recent-case-korten eller mailboxsektionen på /admin/mail-support-assistant.
  • När en avsändare ignoreras på det sättet kan operatören samtidigt välja att radera redan lagrade synkade trådar för samma mailbox/avsändare.
  • Standalone-runnern får nu samma ignore-lista via Tools-configen och skippar framtida mail från de avsändaradresserna direkt i stället för att skapa nya follow-up-ärenden för dem.

Synlighet i standalone-inkorgen

  • Standalone-dashboarden är fortfarande inte tänkt att ersätta full mailboxadministration, men den kan nu också blanda in en live-preview av olästa IMAP-mail i aktivitetspanelen.
  • Det betyder att olästa mail nu kan dyka upp i assistentens webbgränssnitt även innan en ny sparad latest-run-sammanfattning har skrivits.
  • Tools admin visar den synkade/trådade ärendevyn; standalone-dashboarden visar den lokala live-previewen av olästa mail plus latest-run/manualhantering.
  • Standalone-dashboarden renderar nu också först ett lättviktigt skal och laddar därefter tyngre Tools-config + live-preview av olästa IMAP-mail direkt efter första page paint, så inloggningen inte längre måste vänta på att hela dashboardbygget blir klart innan sidan syns.

Valfri rapport över obesvarade mail

  • Standalone kan nu skicka ett sammanfattningsmail efter en körning med vilka meddelanden som inte besvarades.
  • Aktivera det med:
    • MAIL_ASSISTANT_UNANSWERED_REPORT_ENABLED=true
    • MAIL_ASSISTANT_UNANSWERED_REPORT_TO=user@example.com[,second@example.com]
  • Rapporten är avsedd för operatörsuppföljning och stoppar inte körningen även om själva rapportmailet misslyckas.

Nya API-endpoints som standalone-klienten använder

  • GET /api/mail-support-assistant/cases
    • Auth: samma personliga AI-kapabla tokenmodell som GET /api/mail-support-assistant/config
    • Syfte: hämta nyligen lagrade Tools-ärenden som är synliga för tokenägaren
  • POST /api/mail-support-assistant/cases/sync
    • Auth: samma personliga AI-kapabla tokenmodell som GET /api/mail-support-assistant/config
    • Syfte: låta standalone-klienten uppdatera ett inkommande/utgående supporttrådssnapshot tillbaka till Tools
    • Vanliga payloadfält: mailbox_id, message_id, message_key, reply_issue_id, thread_key, subject, from, to, status, reason, additiva headers_raw, additiva headers_map, additiva body_text_raw, additiva body_text, additiva body_text_reply_aware, additiva body_html, body_excerpt, valfritt reply_message_id, additiva reply_body_text, additiva reply_body_html och valfritt reply_excerpt

Eftersom den fristående klienten hämtar mailbox- och regelkonfiguration direkt från Tools med bearer-token räcker det i många installationer med CLI-runner eller cronjobb. Den lilla PHP-dashboarden är valfri och behöver normalt inte exponeras publikt.

Samma CLI-/dashboard-runner är nu också overlapsäker: varje körning tar en lokal icke-blockerande låsfil under storage/state/run.lock, så om cron eller dashboarden försöker starta en ny körning medan en annan redan arbetar hoppar det andra försöket över direkt med runner_already_active i stället för att samma olästa mailbox pollas dubbelt.

Shell-wrappern cron-run.sh håller nu dessutom en egen PID-medveten låskatalog (standard storage/state/cron-run.lock.d) med städning av stale-lås, så överlappande cronkörningar kan stoppas redan innan PHP-runnern startar. Den shell-låsvägen kan överskrivas via MAIL_ASSISTANT_CRON_LOCK_DIR när flera installationer delar samma filsystem.

Den fristående dashboarden är nu också mer operatörsvänlig än tidigare:

  • senaste körningen visas som mailbox-/meddelandekort i stället för bara råa JSON-block
  • konfigurerade mailboxkort visas nu där även innan någon dry-run eller riktig körning hunnit spara meddelandeaktivitet, med en tydlig not om att detta är en operatörsvy för senaste körningen och inte någon full live-IMAP-klient
  • varje meddelande kan expandera tråddiagnostik, vald regel/no-match-resonemang och valfri lokal header-/body-preview när en cachad message copy finns
  • runnern uppdaterar nu också en stabil lokal message copy för varje skannat mail, så dashboarden/manualhanteringen behåller läsbar body-text mer tillförlitligt i stället för att vara beroende av kortare latest-run-utdrag
  • den första dashboardrenderingen är nu också avsiktligt lättare: sidans skal visas först och de tyngre Tools-config-/live-IMAP-panelerna hämtas direkt därefter, vilket gör inloggning och manuell refresh snabbare på trögare IMAP-/Tools-hostar
  • operatören kan nu också agera direkt på senaste körningens meddelanden i dashboarden: välja lokal regelkontext, skicka manuellt svar eller markera meddelandet som manuellt hanterat/läst utan att vänta på nästa cronpass
  • manuella svar använder samma multipart plain-text + stylade HTML-svarspipeline som automatiska svar, så operatörens manuella svar får samma synliga format och samma request-summary-beteende
  • Tools-konfigurationen sammanfattas nu i en mer läsbar mailbox-/regelöversikt, och dashboarden visar nu även läsbara matchade regelrader, omatchade AI/IF-rader (inklusive footer/modell/reasoning) samt mailboxnivåns ignored senders samtidigt som rå JSON fortfarande finns kvar i kollapsbara advanced-sektioner
  • tydliga alertkort visar nu både Tools-sidans dagliga AI-budgettryck (när den metadata finns i config) och standalone-upptäckta quota-/billingfel från senaste körningen

Dashboarden ska fortfarande ses som en lightweight operatörsyta, inte som en full ersättning för det riktiga admin-UI:t i Tools.

Token för standalone-klienten

Den fristående PHP-klienten ska använda en personlig bearer-token, till exempel:

  • provider_mail_support_assistant

Viktiga regler:

  • mottagar-/klienttoken som pratar till Tools för OpenAI:s räkning ska sparas med is_ai=1
  • den uppströms provider_openai-secret som Tools använder mot OpenAI är inte en mottagartoken och utesluts automatiskt från is_ai
  • om en regel har AI aktiverat måste tokenägaren fortfarande ha godkänd provider_openai-access, om användaren inte är admin

API-endpoint för standalone-klienten

GET /api/mail-support-assistant/config

Auth:

  • Authorization: Bearer <personlig AI-kapabel token>
  • X-Api-Key: <personlig AI-kapabel token>
  • apikey=<personlig AI-kapabel token>

Förväntad tokenmodell:

  • personlig icke-global nyckel
  • aktiv
  • AI-kapabel (is_ai=1) eller äldre tools_ai_bearer

Lyckat svar:

{
  "ok": true,
  "message": "Mail Support Assistant config loaded.",
  "user": {
    "id": 1,
    "name": "Admin User",
    "email": "admin@example.com",
    "has_openai_access": true,
    "ai_daily_budget": {
      "feature": "social_media_extension",
      "default_model": "gpt-4o-mini",
      "max_output_tokens_default": 800,
      "cap": 60000,
      "used": 4200,
      "remaining": 55800,
      "is_unlimited": false,
      "source": "user_override"
    }
  },
  "token": {
    "provider": "provider_mail_support_assistant",
    "user_id": 1,
    "is_personal": true,
    "is_ai": true
  },
  "mailboxes": [
    {
      "defaults": {
        "spam_score_reply_threshold": 6.5,
        "generic_no_match_ai_enabled": true,
        "generic_no_match_ai_model": "gpt-4o-mini",
        "generic_no_match_ai_reasoning_effort": "medium",
        "generic_no_match_if": "Om det omatchade mailet är en normal supportfråga och tydligt inte är spam, bedrägeri, phishing eller vag säljkontakt får sista fallbacken svara.",
        "generic_no_match_instruction": "Svara kort, be om den saknade kontodetaljen och håll dig till avsändarens ursprungliga språk.",
        "generic_no_match_footer": "Med vänliga hälsningar",
        "ignored_senders": [
          {
            "id": 77,
            "email": "ignoreme@example.com",
            "label": "Ignore Me <ignoreme@example.com>",
            "notes": "Återkommande avsändare som operatören valt att ignorera"
          }
        ],
        "generic_no_match_rules": [
          {
            "id": 41,
            "sort_order": 0,
            "is_active": true,
            "if": "Om det omatchade mailet är ett oombett säljerbjudande ska vi tacka nej.",
            "instruction": "Avböj vänligt och bjud inte in till fortsatt kontakt.",
            "footer": "Med vänliga hälsningar",
            "ai_model": "gpt-4o-mini",
            "ai_reasoning_effort": "medium"
          }
        ]
      }
    }
  ]
}

Fel:

  • 401 om bearer-token saknas eller nekas

POST /api/mail-support-assistant/send-reply

Syfte:

  • relay:a ett utgående svar via Tools mailtransport när standalone-klienten inte kan eller ska använda lokal mail()/MTA.

Auth:

  • dedikerad personlig token med provider provider_mail_support_assistant_mailer
  • tokenägaren måste ha permission mail-support-assistant.relay (admin bypass gäller)

Body (exempel):

{
  "mailbox_id": 5,
  "rule_id": 11,
  "mode": "fallback_after_php_mail",
  "to": "customer@example.com",
  "cc": [],
  "bcc": ["audit@example.com"],
  "from": "Support Team <support@example.com>",
  "subject": "Re: Order status",
  "body": "Tack för ditt meddelande.",
  "body_html": "<html><body><p>Tack för ditt meddelande.</p></body></html>",
  "message_meta": {
    "message_id": "<abc@example.com>",
    "uid": 12345
  }
}

Lyckat svar:

{
  "ok": true,
  "message": "Reply relayed via Tools mail transport.",
  "relay": {
    "provider": "provider_mail_support_assistant_mailer",
    "user_id": 1,
    "mailbox_id": 5,
    "rule_id": 11,
    "mode": "fallback_after_php_mail"
  }
}

Fel:

  • 401 om relay-token saknas/är ogiltig/inaktiv
  • 403 om tokenägaren saknar mail-support-assistant.relay
  • 422 vid ogiltiga payloadfält

Additivt relay-fält:

  • body_html är valfritt.
  • När det skickas med relay:ar Tools svaret som multipart/alternative med både den ursprungliga plain-text-delen i body och HTML-delen i body_html.
  • Om fältet utelämnas behålls det tidigare plain-text-beteendet i relayläget.
  • Relay stämplar nu också utgående svar med X-Tornevall-Mail-Assistant: sent för anti-loop-detektering i standalone-pollning.

Driftnoteringar

  • Mailboxar/regler konfigureras i Tools, men själva IMAP-pollningen och reply-körningen är tänkt att köras från den fristående klienten/cronjobbet.
  • Mailboxuppgifter ligger i Tools admin; den fristående klienten är fortfarande databaslös lokalt och sparar bara env/session/logg/sammanfattningsdata plus valfria lokala meddelandekopior under storage/.
  • Standalone-svarstransporten är nu SMTP-först som standard (MAIL_ASSISTANT_MAIL_TRANSPORT=smtp) och kan styras med MAIL_ASSISTANT_SMTP_*-nycklar, så lokal Postfix/sendmail inte längre krävs i normalfallet.
  • För WSL-/self-signed-/lokal-CA-miljöer kan standalone nu också slå av eller styra om TLS-verifiering separat för Tools API-anrop (MAIL_ASSISTANT_TOOLS_SSL_VERIFY, MAIL_ASSISTANT_TOOLS_CA_BUNDLE) och SMTP (MAIL_ASSISTANT_SMTP_SSL_VERIFY, MAIL_ASSISTANT_SMTP_CA_FILE).
  • Om varken den matchade regeln eller mailboxens defaults anger någon BCC-mottagare kan standalone nu också falla tillbaka till MAIL_ASSISTANT_DEFAULT_BCC i sin lokala .env.
  • Standalone-svarstransporten stöder nu också en explicit ordnad fallbackkedja via MAIL_ASSISTANT_MAIL_FALLBACK_TRANSPORTS.
  • Om primär transport är tools_api men den dedikerade relay-token saknas hoppar runnern nu över relayläget och fortsätter med SMTP/lokala fallbacktransporter i stället för att avbryta hela svaret.
  • Om SMTP/lokal transport fallerar och fallback är aktiverad kan runnern försöka igen via POST /api/mail-support-assistant/send-reply.
  • Utgående svar från standalone-runtime genereras nu som multipart/alternative: en plain-text-del finns alltid kvar för kompatibilitet, och en stylad HTML-version läggs till för mailklienter som föredrar rikare formatering.
  • Den stylade HTML-delen renderar nu också vanlig markdown från AI-/operatörstext till riktig HTML i stället för att visa markdown-syntax direkt i det synliga mailet.
  • I statiskt footerläge rensar standalone nu bort trailing AI-genererade signoff-block innan den konfigurerade footern läggs till, vilket förhindrar dubbla avslut som både Best regards och Regards i samma svar.
  • Standalone behandlar nu inkommande olästa mail med X-Tornevall-Mail-Assistant: sent som assistant-originerade loopkandidater: de hoppas över före regelmatchning/svar och markeras lästa för att undvika återkommande självsvarsloopar.
  • Om ingen regel matchar ett mail ska klienten lämna det helt orört.
  • När mailboxnivåns AI-fallback för omatchade mail är aktiverad i Tools admin kan standalone-klienten i stället köra en strikt AI-triage via de additiva defaults.generic_no_match_*-fälten från /api/mail-support-assistant/config.
  • Mailboxens generic_no_match_if / generic_no_match_instruction beskriver nu mailboxens egen sista fallback och är inte längre alias för den första avancerade omatchade raden.
  • Avancerade omatchade rader ligger fortsatt i defaults.generic_no_match_rules[] och kontrolleras fortfarande före den sista mailboxfallbacken.
  • Mailboxnivåns ignoreringar visas nu också additivt i defaults.ignored_senders[]; standalone-klienter kan använda den listan för att hoppa över återkommande avsändaradresser innan mailet synkas tillbaka till Tools som ett nytt follow-up-ärende.
  • Dessa additiva mailboxdefaults kan nu också innehålla defaults.generic_no_match_ai_reasoning_effort.
  • Dessa additiva mailboxdefaults kan nu också innehålla defaults.generic_no_match_if.
  • AI instrueras nu att bortse från yttre SpamAssassin-wrappertext när den bara kapslar in originalmailet, samtidigt som SpamAssassin-score/tester fortfarande används som risksignaler.
  • Svar på omatchade mail skickas nu bara när AI returnerar giltig JSON, can_reply=true, certainty="high" och en icke-tom reply-payload. Allt annat lämnar mailet orört.
  • Standalone-parsern för omatchade mail tolererar nu också några vanliga mindre JSON-formatfel från provider/modell (till exempel smart quotes eller trailing commas) innan svaret slutligen klassas som ogiltig JSON.
  • Om denna strikta omatchade fallback verkligen skickar ett svar finaliserar runnern mailet genom att markera det som läst direkt (förutom vid dry-run).
  • Standalone-diagnostiken för den no-match-vägen innehåller nu också generic_ai_decision.evaluated_no_match_rules[], så operatören kan se vilka fallback-rader som faktiskt provades, i ordning, innan ett svar skickades eller mailet lämnades oläst.
  • Per-message-diagnostik i körresultatet visar nu också thread_key, in_reply_to och references[], vilket gör det lättare att se om ett skippat mail faktiskt bar med sig användbar reply-chain-metadata.
  • Matchade AI-aktiverade regler använder nu reply.responder_name, reply.persona_profile, reply.custom_instruction, reply.ai_model och additiva reply.ai_reasoning_effort som auktoritativa AI-override-värden för just det svaret i stället för att se ut som ett vanligt statiskt autosvar.
  • Standalone-klienten försöker nu också igen när tillfälliga AI-rate-limitfel inträffar innan den överger AI-spåret.
  • Standalone-AI-svar försöker nu också uttryckligen svara på samma språk som det inkommande mailet (response_language=auto) om inte avsändaren tydligt ber om ett annat språk.
  • Standalone-fallbackmodellen är nu o4 som standard; den fallbackkörningen skickar medvetet inte reasoning_effort, så o4 används här som en vanlig icke-reasoning fallback.
  • GET /api/mail-support-assistant/config kan nu också exponera additiv metadata i user.ai_daily_budget så standalone-klienten/operatören kan se effektiv daglig AI-tokenlimit, återstående budget, defaultmodell och standardgräns för output-tokens som Mail Support Assistants SocialGPT-baserade svar använder.
  • Om en AI-aktiverad matchad regel fortfarande fallerar efter retries och ingen explicit reply.template_text-fallback finns konfigurerad lämnas svaret nu oskickat och felet loggas, i stället för att en missvisande generisk standardsvarstext skickas.
  • Mailbox-/runnerfel från dessa misslyckade AI-svar innehåller nu också vilken modellkedja som faktiskt provades, vilket gör tomma svar/fallbackproblem lättare att felsöka.
  • Om ett mail hoppas över därför att ingen regel matchar, eller därför att den generiska fallbacken för omatchade mail är avstängd, ofullständigt konfigurerad, underkänd som osäker, ogiltig, tom eller i övrigt fallerar, lämnas mailet nu oläst även om mark_seen_on_skip är aktiverat.
  • Undantag: när den strikta AI-/slutfallbacken för omatchade mail faktiskt har utvärderats men landar i ett terminalt reject-/error-utfall markerar standalone-runnern nu mailet som läst för manuell uppföljning, så samma olästa mail inte fortsätter att bränna AI-försök i all evighet.
  • Quota-/billingfel från AI-mailflöden lyfts nu också upp som tydliga runtime-alerts och kan valfritt skicka cooldown-begränsad operatörsnotis via MAIL_ASSISTANT_QUOTA_ALERT_EMAIL i standalone-miljön.
  • mark_seen_on_skip ska därför främst ses som en bekvämlighetsinställning för medvetna heuristiska skippar, till exempel högscorat SpamAssassin-skräp, och inte som ett sätt att tysta konfigurationsdrivna no-match-mail.
  • Den fristående runnern pollar bara olästa mail. Mail som redan är markerade lästa vid inläsning hoppas över direkt.
  • Den lokala filen storage/state/message-state.json är nu bara diagnostikhistorik. Ett oläst mail kan alltså fortfarande omprövas i en senare körning även om samma Message-Id redan finns i filen, vilket gör att nya regler kan börja gälla utan att lokal state först rensas.
  • Samma lokala state kan ändå användas som kontinuitetshjälp för reply-kedjor: den kan återhämta tidigare vald regel eller tidigare matchad no-match-rad för ett länkat uppföljningsmail, men den får aldrig i sig själv blockera omprövning av oläst mail.
  • Den kontinuitetsuppslagningen förstår nu också sparade utgående reply_message_id-värden och kan falla tillbaka till normaliserat subject + samma deltagare när explicita reply-headers gått förlorade i ett äldre mailformat eller vid någon mellanliggande omskrivning.
  • AI ska bara aktiveras per regel när du uttryckligen vill att Tools/OpenAI ska blandas in.
  • Den fristående klienten tittar nu också på SpamAssassin-headers så att mycket högscorat skräppost kan hoppas över försiktigare, medan wrapper-liknande SpamAssassin-omskrivningar fortfarande kan kopieras lokalt och rensas bort innan regelmatchning eller AI-svar.
  • Mailbox-defaults kan nu också innehålla spam_score_reply_threshold; när ett mail har score över den nivån undertrycker standalone svarshantering för mailet och lämnar det oläst.
  • Score-tolkningen läser nu också X-Spam-Score direkt när X-Spam-Status saknar en parsebar score=-token.
  • Utgående svar lägger nu också till ett kompakt utdrag av den ursprungliga förfrågan, och wrapper-liknande felmail rensas nu hårdare först så vidarebefordrade .eml-headerdumpningar eller SpamAssassin-wrappers inte blir den synliga citerade sammanfattningen.