[RISOLTO] Problema con invio sequenziale di email

di il
11 risposte

[RISOLTO] Problema con invio sequenziale di email

Salve,
sto realizzando un applicazione con Access che, tra i vari compiti, deve inviare molte email in sequenza ai soci presenti nel database.
Se provo a inviare poche email in modo manuale non riscontro nessun tipo di problema, ma quando devo inviare email in sequenza a tutti gli indirizzi ottenuti da una query ottengo (solitamente verso l'ottantesima email) il seguente errore:
Impossibile inviare il messaggio al server smtp. Codice errore di trasporto 80040217
Per l'invio delle email sto utilizzando il seguente codice:

Dim NewMail As Object
Dim mailConfig As Object
Dim fields As Variant
Dim msConfigURL As String

Dim rS As Recordset
Set rS = ...

Do While Not rS.EOF
    
    'late binding
    Set NewMail = CreateObject("CDO.Message")
    Set mailConfig = CreateObject("CDO.Configuration")
    
    ' load all default configurations
    mailConfig.Load -1
    
    Set fields = mailConfig.fields
    
    'Set All Email Properties
    With NewMail
        .From = "*****@gmail.com"
        .To = rS!email
        .Subject = "test subject"
        .TextBody = "test body"
    End With
    
    msConfigURL = "http://schemas.microsoft.com/cdo/configuration"
    
    With fields
        .Item(msConfigURL & "/smtpusessl") = True             'Enable SSL Authentication
        .Item(msConfigURL & "/smtpauthenticate") = 1          'SMTP authentication Enabled
        .Item(msConfigURL & "/smtpserver") = "smtp.gmail.com" 'Set the SMTP server details
        .Item(msConfigURL & "/smtpserverport") = 465          'Set the SMTP port Details
        .Item(msConfigURL & "/sendusing") = 2                 'Send using default setting
        .Item(msConfigURL & "/sendusername") = "*****@gmail.com"      'gmail address
        .Item(msConfigURL & "/sendpassword") = "*****"                'app password
        .Update                                               'Update the configuration fields
    End With
    NewMail.Configuration = mailConfig
    NewMail.Send
    
    Set NewMail = Nothing
    Set mailConfig = Nothing
    
    rS.MoveNext
Loop
Come provider per l'invio delle email sto utilizzando gmail. Ho provato anche ad abilitare l'accesso alle app meno sicure prima ed utilizzare una password per le app dopo, ma ottengo comunque lo stesso problema.

È un problema che dipende da gmail o dal codice?
Eventualmente esiste un metodo alternativo per inviare molte email in sequenza?

Grazie in anticipo.

11 Risposte

  • Re: [RISOLTO] Problema con invio sequenziale di email

    Con gmail puoi inviare al massimo 500 mail ogni 24 ore. Hai il problema sempre allo stesso punto con lo stesso destinatario?
  • Re: [RISOLTO] Problema con invio sequenziale di email

    oregon ha scritto:


    Con gmail puoi inviare al massimo 500 mail ogni 24 ore. Hai il problema sempre allo stesso punto con lo stesso destinatario?
    Ciao, grazie per la risposta.
    Ero a conoscenza del limite di invio giornaliero di gmail, infatti l query mi restituisce circa 150 indirizzi.

    Il problema non si presenta sempre allo stesso punto, a volte capita all'80esimo, altre all'83esimo, in pratica cambia sempre. Cercando in rete trovo che l'errore che ottengo è dovuto ad un problema di autenticazione, ma se le prime 80 email le ho inviate vuol dire che l'autenticazione prima ha funzionato.

    In più, dopo che ho ricevuto l'errore se aspetto 5 minuti e faccio ripartire il ciclo di invio da dove si era interrotto riesco ad inviare tutte le email.
  • Re: [RISOLTO] Problema con invio sequenziale di email

    Può essere un limite legato al numero di mail inviate al minuto.

    Prova a fare una prova inserendo un ritardo tra un invio e il auccessivo
  • Re: [RISOLTO] Problema con invio sequenziale di email

    oregon ha scritto:


    Può essere un limite legato al numero di mail inviate al minuto.

    Prova a fare una prova inserendo un ritardo tra un invio e il auccessivo
    Ho provato e funziona, riesco a inviare tutte le email di seguito adesso. Grazie. Evidentemente il problema era causato dalla rapidità con cui veniva effettuato l'accesso a gmail in modo consecutivo.

    Se può essere di aiuto ad altri ho aggiunto queste righe al codice:

    - nella sezione dichiarazioni:
    Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
    - nel ciclo while, prima di rS.MoveNext:
    Sleep (2000)
  • Re: [RISOLTO] Problema con invio sequenziale di email

    Probabilmente puoi abbassare sperimentalmente il tempo di attesa fino a trovare quello ottimale
  • Re: [RISOLTO] Problema con invio sequenziale di email

    Non serve una chiamata API... le form hanno il Timer... usa quello.
    Inizio invio setti TimerInterval=2000 ed invii la mail su evento Timer, ad ogni Timer ti sposti ed invii quando arrivi alla fine imposti TimerInterval=0
  • Re: [RISOLTO] Problema con invio sequenziale di email

    @Alex ha scritto:


    Non serve una chiamata API... le form hanno il Timer... usa quello.
    Inizio invio setti TimerInterval=2000 ed invii la mail su evento Timer, ad ogni Timer ti sposti ed invii quando arrivi alla fine imposti TimerInterval=0
    Ciao, grazie per il suggerimento.

    Ho capito cosa intendi ed è sicuramente più efficiente rispetto all'utilizzo delle API, ma non mi è ancora chiaro come implementarlo.
    Sull'evento Click del pulsante InviaEmail genero il recordset e imposto subito il TimerInterval della Form a 2000.
    Ciò che non mi è chiaro è come faccio a spostarmi nel recordset ad ogni evento OnTimer se il ciclo While e il recordset sono definiti nell'evento Click del pulsante.
  • Re: [RISOLTO] Problema con invio sequenziale di email

    Lo sleep addormenta il sistema... oltre che dover usare una chiamata esterna.
    Il timer di form no...

    Su Evento Timer dichiari una variabile static come recordset... ed inizi a leggere i record ed inviare la mail...

    Una cosa simile, buttata giù a braccio:
    
    Static rs As DAO.Recordset
    If rs is Nothing then
       ' se sei qui è il primo giro ed apri il recordset
       Set rs=DbEngine(0)(0).OpenRecordset(tua query, dbreadonly, dbSnapshot)
       Rs.movefirst
    Else
       ' se sei qui sei al 2° o successivo giro di timer
       Rs.movenext
    End if
    If rs.eof then
       ' se  sei qui il recordset è finito quindi chiudi
       Me.timerinyerval=0
       Set rs=nothing
       exit sub
    Else
       ' compila la mail con i dati del record ed invia
    End if
    
  • Re: [RISOLTO] Problema con invio sequenziale di email

    Dimenticavo...
    Si click invio devi attivare il timer
    
    Private Sub Nomebutton_Click()
       Me.TimwrInterval=1000
    End sub
    
    Come diceva Antonio devi trovare il tempo più adeguato... 2sec mi pare siano troppi... proverei con 500... ovvio che se la mail è pesante devi calibrare il tempo.
  • Re: [RISOLTO] Problema con invio sequenziale di email

    Grazie ad entrambi, ho risolto il problema.
    Alla fine ho applicato il metodo suggerito da @Alex.

    L'unico problema, ma forse dipende da come ho implementato tutto il resto, mi dava problemi questa riga di codice:

    @Alex ha scritto:


    ...
    
    Static rs As DAO.Recordset
    
    ...
    Per ovviare a questo, anziché dichiarare la variabile Static all'interno dell'evento OnTimer, l'ho dichiarata Public nelle dichiarazioni della Form.
  • Re: [RISOLTO] Problema con invio sequenziale di email

    Ah, come avete entrambi consigliato, ho diminuito il tempo di pausa. Ho provato con 1000 e non mi da problemi.
Devi accedere o registrarti per scrivere nel forum
11 risposte