Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [IMAP] - Wątkowanie wiadomości (INBOX + Sent)
Forum PHP.pl > Forum > PHP
Nosfi
Witam,
Dawien dawno już nic nie pisałem z powodu braku czasu na PHP, więc czas najwyższy coś sklepać jeśli jest okazja i problem do rozwiązania.

Na początek powiem że od kilku dni siedzę i grzebie na forum i w google aby coś wyłapać z tego, ale nic.
Znalazłem kilka opcji np. mailx który jest dla Unixa, więc odpada, i niestety nic nie sprawdza się w moim przypadku. Aczkolwiek nie twierdzę że wchłonąłem wszystko co tam leży - czasami pod latarnią najciemniej wink.gif

Do rzeczy ...

Mam własny serwer na Winde: XAMPP 1.7.3 => PHP5.3 + MySQL5.1 + Mercury4.7
Winda musi być bo jest kilka aplikacji (np. centrala tel.) które pod linuxem chodzić nie mogą.
XAMPP działa szybko, stabilnie. (Muszę tylko go zaktualizować do 1.7.4)

Na serwerku chodzi mały CRM do wewnętrznego obrotu danymi + kilka małych dodatków.

Wyjaśnienie ...
Aktualnie piszę moduł do CRMa który ma za zadanie sprawdzanie czasu reakcji (odpowiedzi na maila).

Np.
Klient wysyła maila, odbieramy go o godz. 10:32:56 [hh:mm:ss]
Odpowiadamy na maila o: 10:35:34 [hh:mm:ss]
Czyli uzyskujemy czas odpowiedzi: 2 minuty 38 sekund

W oparciu o te dane mają być tworzone wykresy i statystyki do raportów dla klienta.

Kod odpowiedzialny za sprawdzanie skrzynki wygląda tak:
  1. $imap_user = "login@host.pl";
  2. $imap_pass = "haselko3";
  3. $imap_server = "{host.pl:993/ssl/novalidate-cert}";
  4.  
  5. $mbox = imap_open({$imap_server}INBOX, $imap_user, $imap_pass);
  6. $check = imap_mailboxmsginfo($mbox);
  7.  
  8. $original_order = $mbox;
  9. $sorted_mbox = imap_sort($mbox, SORTARRIVAL, 1); // posortowana poczta od najnowszych
  10. $totalrows = imap_num_msg($mbox);
  11.  
  12. $i=0;
  13. for($m=0; $m<$totalrows; $m++)
  14. {
  15. if($header = imap_headerinfo($mbox, $sorted_mbox[$m]))
  16. {
  17. $from = $header->from;
  18. if(is_array($from))
  19. {
  20. while(list($key, $val) = each($from))
  21. {
  22. $fromName = $from[0]->personal;
  23. $fromAddress = $from[0]->mailbox . "@" . $from[0]->host;
  24. }
  25. }
  26.  
  27. $headerFrom = (!$fromName ? $fromAddress : $fromName.' ('.$fromAddress.')');
  28. if($header->Deleted == " ") // Pokazujemy tylko faktycznie istniejace - czasami na serwie jakies smieci zostaja
  29. {
  30. echo '<tr>';
  31. echo '<td>'.imap_uid($mbox, $header->Msgno).'</td>'; // Wyciagamy UID dla wiadomosci
  32. echo '<td>'.($headerFrom).'</td>';
  33. echo '<td>'.($header->Subject).'</td>';
  34. echo '<td>'.($header->udate).'</td>'; // unix'owa data do testów
  35. echo '</tr>';
  36. $i++;
  37. if($i>1) $i=0;
  38. }
  39. }
  40. }
  41.  
  42. imap_close($mbox);

Prosto, zwięźle i na temat. (jeśli coś można poprawić, sugestie mile widziane wink.gif)

PROBLEM:
Jak powątkować pocztę, czyli powiązać otrzymaną z wysłaną?


Już robiłem ...
Funkcja imap_headerinfo daje spore możliwości ale akurat nie ma tej która by mi pomogła, a przynajmniej takiej nie znalazłem.

Opcje z tej funkcji typu in_reply_to, message_id, references już testowałem ale nie zawsze posiadają wpis i nie można się przez nie odwołać do powiązanego maila.
Flagi mi nie pomagają bo nie posiadają żadnych dat (chyba że coś mi umyka).

Sprawdzałem i porównywałem różne dane z obu skrzynek (odbiorcza i wysłane) i nie znalazłem żadnego wspólnego mianownika, którym mógłbym połączyć wiadomości.

Próbowałem oprzeć system o wykorzystanie aliasu dla maila który jest sprawdzany, ale to "walka z wiatrakami".
Myślałem o sprawdzaniu konkretnych odbiorców i czasów dostarczania w skrzynkach ale to niewypał.
Klientów jest ogólnie 2, ale nie możemy uzależniać systemu od 1 czy kilku adresów mailowych i np. 2 domen, trzeba założyć że klient będąc na urlopie napisze maila z innego adresu i już ZONK.


Nie chciałbym ... na pewno robić własnego klienta poczty bo zależy mi tylko na części korespondencji a nie całej. No chyba że to będzie tylko i TOTALNIE jedyne rozwiązanie (można zapisywać pocztę wychodzącą do bazy z czasem i analizować wszystko szczegółowo) ale wolałbym znaleźć inne rozwiązanie jeśli to możliwe ...


Zastanawiałem się nad wykorzystaniem Mercury'ego z pakietu XAMPP, tak aby za pomocą jego odbierać i wysyłać pocztę, ale nie wiem czy to by do mojego CRMa można by to wykorzystać.
Nie chcę tracić czasu na próby które mogą nie przynieść dobrego rezultatu.


No i takim sposobem wylądowałem tu postując wink.gif


Wielkie dzięki z góry za wszelką pomoc.

PS. Mile widziane również inne rady jeśli chodzi o IMAP'a, wiedzy nigdy za wiele wink.gif

Widzę że na ciężkie (względnie) tematy to tłumy się rzucają smile.gif


W każdym razie problem po wielogodzinnej walce 2 dni później został rozwiązany.
Jak się okazało wszystko jest w manualu, a zmęczenie materiału (tj. mnie) stwarza czasami problemy w doglądaniu szczegółów.


W IMAP'ie w manualu występuje taka funkcja jak imap_thread która przy odpowiednim zastosowaniu spełnia wszystkie moje wymagania ...
Może się to komuś przyda.


Temat do zamknięcia.
nospor
Cytat
Opcje z tej funkcji typu in_reply_to, message_id, references już testowałem ale nie zawsze posiadają wpis
Hmmm, ja właśnie na tym parametrach polegam i jakoś to działa.

Cytat
W IMAP'ie w manualu występuje taka funkcja jak imap_thread która przy odpowiednim zastosowaniu spełnia wszystkie moje wymagania ...
Nie mam akurat czasu żeby przysiąść do tej tematyki a będzie mi potrzebna... mógłbyś napisać coś więcej na ten temat?
Czy jak łączysz się na konto pop, przy pomocy tych imapów, to też daje dobre wyniki ta funkcja? Z pop to w ogóle porażka bo nie ma wiadomości wysłanych.
Nosfi
Cytat(nospor @ 5.08.2011, 12:19:40 ) *
Cytat(Nosfi @ 5.08.2011, 09:33:25 ) *

Opcje z tej funkcji typu in_reply_to, message_id, references już testowałem ale nie zawsze posiadają wpis

Hmmm, ja właśnie na tym parametrach polegam i jakoś to działa.

No właśnie na tym testowałem na początku, i niestety wiele wątków z zewnętrznych serwerów (np. z Gmail'a) nie nadaje żadnych ID czy referencji do nagłówków, przez co zaczynamy mieć problem z powiązaniem odpowiednich wiadomości.
Do wewnętrznej analizy poczty można ich użyć bo mamy kontrolę nad nagłówkami, ale jeśli przychodzi o "globalizm" to nie zawierzył bym tym informacjom.

Cytat(nospor @ 5.08.2011, 12:19:40 ) *
Nie mam akurat czasu żeby przysiąść do tej tematyki a będzie mi potrzebna... mógłbyś napisać coś więcej na ten temat?
Czy jak łączysz się na konto pop, przy pomocy tych imapów, to też daje dobre wyniki ta funkcja? Z pop to w ogóle porażka bo nie ma wiadomości wysłanych.

Na POP w ogóle nie polecam, większość funkcji nie działa.
Nie testowałem imap_thread ale myślę że też będzie stwarzać problem, o ile w ogóle działać.


a teraz rozwiązanie problemu dla innych ...
  1. $imap_user = "UZYSZKODNIK"; // np. kontakt@domena.pl
  2. $imap_pass = "HASLO";
  3. $imap_server = "{SERWER_IMAP}"; // np. {domena.pl:993/ssl/novalidate-cert} - ja robie po SSL
  4. $imap_mbox = "INBOX"; // moze byc tez np. INBOX.Sent i inne zalezy od tego co chcemy badac
  5.  
  6. $mbox = imap_open("{$imap_server}".$imap_mbox, $imap_user, $imap_pass);
  7.  
  8. $threads = $rootValues = array();
  9. $thread = imap_thread($mbox);
  10. $root = 0;
  11. foreach($thread as $i => $messageId)
  12. {
  13. list($sequence, $type) = explode('.', $i);
  14.  
  15. if($type != 'num' || $messageId == 0 || isset($rootValues[$messageId])) // pokazuje wszystkie maile w skrzynce
  16. // LUB:
  17. //if($type != 'num' || $messageId == 0 || isset($rootValues[$messageId]) || ($root == 0 && $thread[$sequence.'.next'] == 0)) // a tu pokazuje TYLKO watki
  18. continue;
  19.  
  20. if($root == 0)
  21. $root = $messageId;
  22.  
  23. $rootValues[$messageId] = $root;
  24.  
  25. if($thread[$sequence.'.next'] == 0)
  26. $root = 0;
  27. }
  28.  
  29. $emails = imap_fetch_overview($mbox, implode(',', array_keys($rootValues)));
  30. foreach($emails as $email)
  31. {
  32. $root = $rootValues[$email->msgno];
  33. $threads[$root][] = $email;
  34. }


sprawdzamy:
  1. echo '<pre>'.print_r($threads, true).'</pre>';


no a dalej jedziemy z prezentacją danych ....
ja mam cos takiego (wersja uproszczona wiec moze zawierac jakis blad literowy):
  1. for($t=1; $t<=$email->msgno; $t++) // $email->msgno - najprosciej pokazuje mi jaki byl ostatni Msgno ostatniego watku, wiec wiem ile ich jest w skrzynce
  2. {
  3. if($threads[$t][0]->deleted == "0") // ukrywam usuniete bo smieci nie potrzebuje
  4. {
  5. for($tin=0; $tin<count($threads[$t]); $tin++) // wyswietlam maile w watkach
  6. {
  7. $header = imap_headerinfo($mbox, $threads[$t][$tin]->msgno);
  8.  
  9. // przerabiam sobie naglowek:
  10. $headerfrom = explode(" <", preg_replace('/>/', '', utf8_fix($threads[$t][$tin]->from))); // utf8_fix - to moja funkcja naprawiajaca kodowanie
  11. $from = htmlspecialchars($headerfrom[0]);
  12.  
  13. $subject = htmlspecialchars(utf8_fix($header->subject));
  14.  
  15. echo '
  16. <tr>
  17. <td>'.$from.'</td>
  18. <td>'.$subject.'</td>
  19. <td>'.date("Y-m-d H:i:s", $header->udate).'</td>
  20. </tr>
  21. ';
  22. }
  23. }
  24. }



dziala idealnie dla mnie, mam nadzieje ze i dla innych
ja potrzebowalem to do badania czasu odpowiedzi wiec tylko aktywne watki i max 2 maile dla watku

o rozbudowane wersje prosze pytac na priv

Pozdrowionka dla zainteresowanych wink.gif
nospor
Cytat
No właśnie na tym testowałem na początku, i niestety wiele wątków z zewnętrznych serwerów (np. z Gmail'a) nie nadaje żadnych ID czy referencji do nagłówków, przez co zaczynamy mieć problem z powiązaniem odpowiednich wiadomości.
Kiepsko...
Póki co ja nie trafiłem na takie maile, ale skoro ty trafiłeś to znaczy że są sad.gif

No nic, jak powrócę do tematu to jeszcze się tym pobawię.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.