"Pinging" an email address using VB.Net coding - vb.net

Is there a way in VB.Net to "Ping" an email address to see if that email is a real one that does not give any errors?
If yes, can you show what the VB.Net coding looks like to implement this?
I plan to use this in an app that requires the Customer email and it would be nice to validate it as the call taker enters it into a form before saving the Customer details.
Here is the code we are using to send an email promotion to all of the customers in our customer table:
Private Sub RibbonButtonSendTestEmail_Click(sender As System.Object, e As System.EventArgs) Handles RibbonButtonSendTestEmail.Click
Dim SmtpServer As New SmtpClient()
Dim mail As New MailMessage()
Dim strSqlStatement As String = "Select CustomerName, Email " & _
"From Customers "
Using objSqlCommand As SqlCommand = New SqlCommand(strSqlStatement, ObjConnection)
With objSqlCommand
' Open the SqlConnection before executing the query.
'---------------------------------------------------
Cursor = Cursors.WaitCursor
ObjConnection.Open()
Dim objDataReader As SqlDataReader = .ExecuteReader()
' Go through all the customers and send out the promotion emails.
'----------------------------------------------------------------
If objDataReader.HasRows Then
SmtpServer.Host = TextBoxSMTPServer.Text
SmtpServer.Port = TextBoxPort.Text
If TextBoxUseSSL.Text = "Yes" Then
SmtpServer.EnableSsl = True
Else
SmtpServer.EnableSsl = False
End If
If TextBoxUseDefaultCredentials.Text = "Yes" Then
SmtpServer.UseDefaultCredentials = True
Else
SmtpServer.UseDefaultCredentials = False
End If
SmtpServer.Credentials = New Net.NetworkCredential(TextBoxUserName.Text, TextBoxPassword.Text)
While objDataReader.Read()
Try
mail.To.Add(objDataReader("Email").ToString)
mail.From = New MailAddress(TextBoxEmailFrom.Text)
mail.Subject = "Promotion: " & TextBoxID.Text
mail.Body = "Dear " & objDataReader("CustomerName") & "," & vbCrLf & vbCrLf & TextBoxPromotionBodyText.Text
SmtpServer.Send(mail)
Catch exSMTP As SmtpException
MessageBox.Show("Sorry, I could not send an email for: " & _
vbCrLf & objDataReader("CustomerName") & "." & vbCrLf & _
"Please make sure it is correct.", _
"Error")
Catch exFormat As FormatException
MessageBox.Show("Sorry, this customer's email is not properly formatted: " & _
vbCrLf & objDataReader("CustomerName") & "." & vbCrLf & _
"Please make sure it is correct.", _
"Error")
End Try
End While
LabelEmail.Text = "Sent email promotions to the customers."
End If
objDataReader.Close()
ObjConnection.Close()
Cursor = Cursors.Default
End With ' objSqlCommand
End Using ' objSqlCommand
End Sub

Yes it's perfectly possible:
1 DNS Lookup the MX records for the domain
There may be multiples, you can pick anyone, although technically the one with the lowest preference indicator is the prefered one.
2 TCP Connect to the mail server (port 25)
Say hello: HELO
Identify yourself: mail from:<test#example.com>
Say who you're writing to: rcpt to<testaddress#example.com>
At this point the server will reply with a response, you'll get an OK or a 550 error with a message (like: The email account that you tried to reach does not exist)
Disconnect and the message will be dropped.
But dude, you want the VB code to do this? You just need a DNS talking piece and TCP connection building piece (or likely there are some SMTP libraries out there that'll do all this for you - or provide you with inspiration to figure it out yourself). Don't forget you can probably find a C# code example that does it and use Visual Studio's conversion tool to switch it to VB.
Note
Many domains have black holes/catch alls... the former will accept any email address and just delete it if it's invalid, the latter will accept any email address and forward them to a central account (no guarantees as to what happens then... sell the sender's address to spammers?) In both cases you won't get the 550 message, so you can never be certain.

There most reliable way to do this is to send a test email and have the recipient verify receipt by clicking on a link, which you then read and mark the email as active.
You should do primitive checks on the syntax of the email using regular expressions, but beyond that the most reliable way to validate an email is to attempt delivery and confirm the receipt.

Related

VBA code works in one box, throws an error in another

Alright, short background, I have a form, on which I have 3 Comboboxes.
Two of these comboboxes are tied to the same exact table, an accounts table. They use slightly different queries between them, see below.
In one box, cmb_GA I have set the box property "On Not in List" to the following code segment :
Private Sub cmb_GA_NotInList(NewData As String, Response As Integer)
Dim cnn As New ADODB.Connection
Dim strSQL As String
Dim password As String
Dim bytUpdate As Byte
On Error GoTo ErrHandler
Set cnn = CurrentProject.Connection
bytUpdate = MsgBox("Do you want to add " & NewData & " to the Accounts list?", vbYesNo, "Not in list of Accounts!")
If bytUpdate = vbYes Then
password = InputBox("Enter New Account Password")
strSQL = "INSERT INTO tbl_Accounts(Login, PW) " & "VALUES
('" & NewData & "#mcsnet.org' , '" & password & "')"
Debug.Print strSQL
cnn.Execute strSQL
Response = acDataErrAdded
Call AuditLogs("txt_DN", "New")
ElseIf bytUpdate = vbNo Then
Response = acDataErrContinue
Me!cmb_GA.Undo
End If
Exit Sub
ErrHandler:
MsgBox Err.Number & ": " & Err.Description, vbOKOnly, "Error"
End Sub
Note that for formatting here I put in an extra CR after "VALUES" that doesn't exist in the actual code, other than that, and some deleted comments, WYSIWIG.
This code works perfectly. 100% Does what I want.
I have another combobox, cmb_IA
I am using the same code for it (Yeah I probably should have done this as a module in retrospect, but I didn't yet.)
The problem is that it throws an error. "The text you entered isn't an item in the list. Select an Item from the list, or enter text that matches one of the listed items."
I've looked at the properties and can not find a difference between the two boxes on the property sheets: Here's a look at both boxes Data tab:
And here is the relevant SQL from the two queries:
SELECT *
FROM tbl_Accounts
WHERE tbl_Accounts.Association LIKE "*Device*";
and
SELECT *
FROM tbl_Accounts
WHERE tbl_Accounts.Association LIKE "*Intune*";
I would assume the question is obvious, but let me state this outright, what is happening here? Is there a way to suppress this error? Both comboboxes must let the user add new information to them, as the point of this form is to register new devices, cellphones and tablets, and the security accounts and corporate accounts that each device uses. What's puzzling me the most is that this error is only showing up on the one combobox.
Edited to add the code from the section that is throwing the error:
Private Sub cmb_IA_NotInList(NewData As String, Response As Integer)
Dim cnn As New ADODB.Connection
Dim strSQL As String
Dim password As String
Dim bytUpdate As Byte
On Error GoTo ErrHandler
Set cnn = CurrentProject.Connection
bytUpdate = MsgBox("Do you want to add " & NewData & " to the Accounts list?", vbYesNo, "Not in list of Accounts!")
If bytUpdate = vbYes Then
password = InputBox("Enter New Account Password")
strSQL = "INSERT INTO tbl_Accounts(Login, PW) " & "VALUES ('" & NewData & "#mcsnet.org' , '" & password & "')"
Debug.Print strSQL
cnn.Execute strSQL
Response = acDataErrAdded
Call AuditLogs("txt_DN", "New")
ElseIf bytUpdate = vbNo Then
Response = acDataErrContinue
Me!cmb_IA.Undo
End If
Exit Sub
ErrHandler:
MsgBox Err.Number & ": " & Err.Description, vbOKOnly, "Error"
End Sub
It was suggested I show the RowSource SQL generated by Access so here it is Working:
SELECT qry_DeviceAccounts.AccountIDKey, qry_DeviceAccounts.Login, qry_DeviceAccounts.PW
FROM qry_DeviceAccounts
ORDER BY qry_DeviceAccounts.[Login];
Not Working:
SELECT qry_SecurityAccounts.AccountIDKey, qry_SecurityAccounts.Login, qry_SecurityAccounts.PW
FROM qry_SecurityAccounts
ORDER BY qry_SecurityAccounts.[Login];
I can't believe I didn't see it earlier. This was the result of the difference between the two queries, and the way they filtered for the account information. I needed to set the new account information to be filtered for during the INSERT statement, which hadn't been done. Since the other one worked on the default value of one of the fields in the table, it wasn't relevant to that one's INSERT statement.
Moral of the story, check your fields, and make sure you carefully read what each is doing. I was so busy looking for an error in my VBA, I forgot to check my SQL.

VB.net SqlDataReader how to show messagebox if GetString function has null value?

I have a login form which I need to check my database whether the user input of email and password matches the database.
Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
myConn = New SqlConnection(My.Settings.MySQLData)
myCmd = myConn.CreateCommand
myCmd.CommandText = "SELECT Email FROM dbo.[User]" &
" WHERE Email = '" & tbEmail.Text & "'"
myConn.Open()
myReader = myCmd.ExecuteReader
myReader.Read()
If myReader.IsDBNull(0) Then
MessageBox.Show("The email address input is invalid or does not exist in database.")
ElseIf myReader.GetString(0) <> tbEmail.Text Then
MessageBox.Show("The email address input is invalid or does not exist in database.")
Else
MessageBox.Show("Email address is OK")
End If
myReader.Close()
myConn.Close()
This is only the email portion. I also have a password portion which I have yet to put in.
My code above does not work however. What is the best way to check against database for login?
Use the HasRows property to avoid the requirement to call the Read method of the DataTableReader if there are no rows within the current result set. - Msdn
If reader.HasRows Then
myReader.Read()
Else
MessageBox.Show("no data present")
End If
According to your comment above, the error is:
Invalid attempt to read when no data is present.
This means that the code assumes that at least one record is being returned by the SQL query, but no records are being returned. That is, there is no record matching the WHERE clause conditions.
You should check for the existence of records before trying to read them. When using a SqlDataReader, this is often done by examining the boolean result of the Read() method. For example:
While myReader.Read()
' read the values here, for example:
myReader.GetString(0)
End While
As soon as myReader.Read() evaluates to False, that means no more records are present in the query result. If it evaluates to False on the first attempt, that means there are no records in the query result in the first place.
From the youtube video shown here: https://www.youtube.com/watch?v=iyjGP4fP7IE
The code myReader.HasRows will check against the database with no hassle.
My new code:
myConn = New SqlConnection(My.Settings.MySQLData)
myCmd = myConn.CreateCommand
myCmd.CommandText = "SELECT Email, Password FROM dbo.[User]" &
" WHERE Email = '" & tbEmail.Text & "'" &
" AND Password = '" & tbPassword.Text & "'"
myConn.Open()
myReader = myCmd.ExecuteReader
If myReader.HasRows Then
LoginScreen.Show()
Else
MessageBox.Show("Invalid Email or Password")
End If
myReader.Close()
myConn.Close()

Multiple sms send in AT commands VB.NET

I'm trying to send many or bulk sms using AT Command. I try send all number inside the datagrid but only first number is sending.
this is my code
Dim sql As New MySqlDataAdapter("select StudentID, StudentName,StudentContact, DueDate FROM issue inner join student on student.StudentID = issue.Student ", conn)
Dim ds As New DataSet
sql.Fill(ds, 0)
For i As Integer = 0 To ds.Tables(0).Rows.Count - 1
Dim wholenum As String
Dim wholesms As String
wholenum = ds.Tables(0).Rows(i).Item(2).ToString
wholesms = "Hello " & ds.Tables(0).Rows(i).Item(1).ToString & ", this is your Due Date " & ds.Tables(0).Rows(i).Item(3).ToString & " pls return it on your due date"
If SerialPort1.IsOpen Then
Try
With SerialPort1
.Write("AT" & vbCrLf)
.Write("AT+CMGF=1" & vbCrLf)
.Write("AT+CMGS=" & Chr(34) & wholenum & Chr(34) & vbCrLf)
.Write(wholesms & Chr(26))
MsgBox("Success sa SEND")
'update one
'Call ConnectDatabase()
'com = New MySqlCommand("UPDATE issue SET Sent='1' ", conn)
'com.ExecuteNonQuery()
'Call DisconnectDatabase()
End With
Catch ex As Exception
MsgBox("Bad Signal or No load")
End Try
Else
MsgBox("Pls insert a modem")
End If
I think the looping is working 'cuz it apppears the successful message of how many inside in the datagrid view. But it only send the first number.
You need to fix your AT command handling significantly. First of all you need to read and parse everything the modem sends back to you after sending a AT command line (which by the way should be terminated with just "\r" and not vbCrLf).
You should never start sending a new command line before you have received the Final result code. And for AT+CMGS specifically you should never send the sms payload before you have received the "\r\n >" prefix.
These issues are covered in this and this answer. But the very first thing you should to is to read all of the text in chapter 5 in the V.250 specification. It is a really important document when working with AT commands.

register form wont work- Error in Code - dbCommand.ExecuteReader()

I am currently trying to develop a register system in visual studios, however for some reason it just does not work as it brings up an error message which is the following below.
On line line Dim read As OleDb.OleDbDataReader = cmd.ExecuteReader()it says:
An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dl.
Please can you help as I have done everything correct, however I just do not understand why the register system will not work.
'Enables the use of the OleDb classes.
Imports System
Imports System.Data.OleDb
Imports System.Net.Mail
Public Class Register
'Determines the connection and the location within the users file system.
Dim myConnString As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Environment.CurrentDirectory & "\BloodBank.mdb"
Private Sub Register_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'This line of code loads data into the 'BloodBankDataSet.User' table. You can move, or remove it, as needed.
Me.UserTableAdapter.Fill(Me.BloodBankDataSet1.User)
'BindingSource - Encloses the data source for a form, in this case Register.
' AddNew, adds a new record.
Me.UserBindingSource.AddNew()
End Sub
Private Sub Reg_Click(sender As Object, e As EventArgs) Handles Reg.Click
'creates the connection between the project and the database ensuring that any changes made will be updated within the database.
Dim con As New OleDbConnection(myConnString)
'creates a second connection between the project and the database ensuring that any changes made will be updated within the database.
Dim con2 As New OleDbConnection(myConnString)
'Opens the connections.
con.Open()
con2.Open()
'Creates a SQL command which...
'Selects the staff details dependendent on the value inputted by the user.
Dim cmd As OleDbCommand = New OleDbCommand("SELECT StaffID, FirstName, Surname FROM [Staff] WHERE (FirstName = '" & Me.FirstNameTextBox.Text & "') AND (Surname = '" & Me.SurnameTextBox.Text & "') ", con)
'sends the command above to the connection.
Dim read As OleDb.OleDbDataReader = cmd.ExecuteReader()
'Creates a SQL command which...
'Selects the User ID and Staff ID from user dependent on the value inputted by the user.
Dim cmd2 As OleDbCommand = New OleDbCommand("SELECT UserID, StaffID FROM [User] WHERE StaffID = '" & Me.StaffIDTextBox.Text & "' ", con2)
'sends the command above to the connection.
Dim read2 As OleDb.OleDbDataReader = cmd2.ExecuteReader()
'If there is no text within the staff ID text box...
If String.IsNullOrEmpty(StaffIDTextBox.Text) Then
'A message will appear telling the user to enter their staff ID.
MsgBox("Please enter StaffID")
'This will focus the user on the staff ID text box.
'Me. means the current form in use.
Me.StaffIDTextBox.Focus()
'If there is no text within the FirstName text box...
ElseIf String.IsNullOrEmpty(FirstNameTextBox.Text) Then
'A message will appear telling the user to enter their first name.
MsgBox("Please enter First Name")
'This will focus the user on the firstname text box.
Me.FirstNameTextBox.Focus()
'If there is no text within the Surname text box...
ElseIf String.IsNullOrEmpty(SurnameTextBox.Text) Then
'A message will appear telling the user to enter their surname.
MsgBox("Please enter Surname")
'This will focus the user on the surname text box.
Me.SurnameTextBox.Focus()
'If there is no text within the login ID text box...
ElseIf String.IsNullOrEmpty(UserLoginTextBox.Text) Then
'A message will appear telling the user to enter their login ID.
MsgBox("Please Enter LoginID")
'This will focus the user on the loginID text box.
Me.UserLoginTextBox.Focus()
'If there is no text within the user password text box...
ElseIf String.IsNullOrEmpty(UserPasswordTextBox.Text) Then
'A message will appear telling the user to enter their password.
MsgBox("Please Enter Password")
'This will focus the user on the password text box.
Me.UserPasswordTextBox.Focus()
'If there is no text within the user ID text box...
ElseIf String.IsNullOrEmpty(EmailAddressTextBox.Text) Then
'A message will appear telling the user to enter their email.
MsgBox("Please Enter Email")
'This will focus the user on the email text box.
Me.EmailAddressTextBox.Focus()
'If the items do not match up with that within the database then...
ElseIf read.Read = False Then
'A message box will appear informing of the failure of the registration and the reason why.
MsgBox("You must be a staff member to create a User")
'This will focus the user on the StaffID text box.
Me.StaffIDTextBox.Focus()
'If the items do match up with that within the database then...
ElseIf read2.Read = True Then
'Determines that the answer data type is a integer.
Dim answer As Integer
'creates a message box, which is assigned to answer with a question with a yes and no option
answer = MsgBox("There is already a User account with this Staff ID." & vbNewLine & "Have you forgotten your Password? ", vbYesNo + vbQuestion)
'if the user selects the yes button...
If answer = vbYes Then
'They will be redirected to the retrieve password form.
'.Show, opens the said form, in this case the retrieve password form.
RetrievePass.Show()
'.Close, closes the form, in this case it is the form currently in use.
Me.Close()
Else
'Do nothing.
End If
ElseIf read2.Read = False And Me.StaffIDTextBox.Text = read.Item("StaffID") And Me.FirstNameTextBox.Text = read.Item("FirstName") And Me.SurnameTextBox.Text = read.Item("Surname") Then
End If
MsgBox("Thank you for creating a User." & vbNewLine & "We have sent your User details to your Email")
'Security Level
'Makes a certain feild in a specified table usable or not usable for the user.
HomeF.ButForm.Enabled = True
HomeF.ButUse.Enabled = False
HomeF.Button2.Enabled = True
'Me. means the current form in use.
'.Validate checks that the information is correct and every aspect has been filled in.
Me.Validate()
'EndEdit, applies the changes to the data source.
Me.UserBindingSource.EndEdit()
'Updates the specified table within the specified dataset.
Me.UserTableAdapter.Update(Me.BloodBankDataSet1)
Me.UserLogin_L.Text = Me.UserLoginTextBox.Text
'.Validate checks that the information is correct and every aspect has been filled in.
Me.Validate()
'EndEdit, applies the changes to the data source.
Try
Dim Email As String = Me.EmailAddressTextBox.Text
Dim name As String = Me.FirstNameTextBox.Text
Dim userpassword As String = Me.UserPasswordTextBox.Text
Dim LoginID As String = Me.UserLoginTextBox.Text
Dim StaffID As Integer = Me.StaffIDTextBox.Text
Dim Smtp_Server As New SmtpClient("smtp.gmail.com")
Dim e_mail As New MailMessage
Smtp_Server.UseDefaultCredentials = False
'Have to put in the email account details to enable the use of sending emails via the account.
Smtp_Server.Credentials = New Net.NetworkCredential("blood4all1#gmail.com", "Blood1234")
Smtp_Server.Port = 587
Smtp_Server.EnableSsl = True
'smtp(Simple Mail Transfer Protocol)
e_mail.From = New MailAddress("blood4all#outlook.com")
e_mail.To.Add(Email)
e_mail.Subject = ("New User: Blood4All Blood Bank")
e_mail.IsBodyHtml = False
e_mail.Priority = MailPriority.High
e_mail.Body = ("Dear " & name & "" & vbNewLine & "" & vbNewLine & "A New User Account was created with Your StaffID: " & StaffID & ". If the account was not created by You Contact Blood4All immediately." & vbNewLine & "Your LoginID is: " & LoginID & "" & vbNewLine & "Your Password is: " & userpassword & "" & vbNewLine & "" & vbNewLine & "Regards" & vbNewLine & "Blood4All Blood Bank")
Smtp_Server.Send(e_mail)
Close()
HomeF.Show()
Catch error_t As Exception
MsgBox("Error when Sending Your Email: Email Address does not Exist or There is No Network Connection")
Close()
HomeF.Show()
End Try
End
'Closes the four objects.
read.Close()
read2.Close()
con.Close()
con2.Close()
End Sub

VB.Net, sending emails out uniquely

im an intern at a packaging company and we have an interface that sends out summary emails out to several people on mondays. There are about 70 groups that the code sees. every group has a specific section that people enter a log in. if you are a recipient in that group on monday you will recieve a summary email of all the active logs entered for groups you are in. if user A is in group 1 and 2, he or she should recieve 2 emails with active logs pretaining to those 2 groups. Problem is he or she is signed up in all 70 groups and if there are only 2 active logs from group 1 and 2 she recieves 70 identical emails with summaries containing active logs for those 2 groups. here is the code.
Private Sub SendEmails()
Try
Dim message As New PCA.Core.Messaging.Message(PCA.Core.Messaging.MessageTypes.JumperLog)
'Dim distLists As List(Of PCA.Core.DistributionList) = (From r In Trident.Core.Globals.TridentApp.ApplicationCache.DistributionLists.DistributionLists Where r.ID.Contains("JL_")).ToList
Dim distLists As List(Of PCA.Core.DistributionList) = (From r In PCA.Core.DistributionList.GetDistributionLists Where r.Id.Contains("JL_")).ToList
For Each distlist As PCA.Core.DistributionList In distLists
Dim recipients As System.Collections.Generic.List(Of Trident.Core.User)
recipients = Trident.Core.Core.Message.GetTridentDistributionList("TRIMAINT", distlist.Id)
If recipients.Count > 0 Then
message.Recipients.AddRange(recipients)
End If
Next
If message.Recipients.Count = 0 Then Exit Sub
Dim ds As New DataSet
Dim dbConn As New Trident.Core.DBConnection
Dim sql As String = "SELECT * FROM ***.Maintenance.JumperLogs WHERE Removed <> 1 AND Plant = #Plant ORDER BY InstallDate "
dbConn("#Plant") = Trident.Core.Globals.TridentApp.DefaultPlant.Plant
Dim tmpJL As Trident.Objects.Maintenance.JumperLogs.JumperLog
message.Subject = "Jumper Log - Active Jumpers"
ds = dbConn.FillDataSet(sql)
If ds.Tables(0).Rows.Count = 0 Then Exit Sub
For Each dr As DataRow In ds.Tables(0).Rows
tmpJL = New Trident.Objects.Maintenance.JumperLogs.JumperLog(dr)
message.Body += "Jumper Log # " & tmpJL.LogId & " - Installed: " & tmpJL.InstallDate & vbCrLf
message.Body += "Mill: " & Trident.Core.Globals.TridentApp.DefaultPlant.Description & vbCrLf
message.Body += "Facility: " & tmpJL.FacilityObject.Description & vbCrLf
If Not tmpJL.MachineAreaObject Is Nothing Then
message.Body += "Area: " & tmpJL.MachineAreaObject.Description & vbCrLf
End If
If Not tmpJL.LocationObject Is Nothing Then
message.Body += "Location: " & tmpJL.LocationObject.Description & vbCrLf
End If
If Not tmpJL.EquipmentObject Is Nothing Then
message.Body += "Equipment: " & tmpJL.EquipmentObject.Description & vbCrLf
End If
message.Body += "Installed By: " & tmpJL.InstalledBy.FullName & vbCrLf
'message.Body += "Install Date: " & tmpJL.InstallDate & vbCrLf
message.Body += "Tag: " & tmpJL.Tag & vbCrLf
message.Body += "Tag Attached To: " & tmpJL.TagAttachedTo & vbCrLf
message.Body += "Work Order: " & tmpJL.WorkOrder & vbCrLf
message.Body += vbCrLf
message.Body += "Reason: " & tmpJL.Reasons.ToUpper & vbCrLf
message.Body += vbCrLf
message.Body += "---------------------------------------------------------------------------------------------------------------------------------------------------" & vbCrLf
message.Body += vbCrLf
Next
message.Send()
Catch ex As Exception
Throw New PCA.Core.Exceptions.PCAErrorException(ex)
End Try
End Sub
Now i think that modifying the if statement that initializes the range, might do it?
Ok a user that is in "JL_001" group recieved a summary email on monday that JL_001 group is label by facilities and this one is called #1paper machine" since. he is only in one group that paper machine group he got one email with only one active jumperlog which happens to be from his facility (#1 paper Machine.) Now this is the issue, there is a group of users that have all been added to groups "JL_001 to JL_070". since there was only one acitve log entered that previous week on monday they should only get one summary email because they are also in the #1 paper machine facility group(JL_001). they shouldnt receive anything else from any other group because there were no active logs from those groups yet they recieved 70 emails of that same summary pretaining to JL_001. Does this help clear it up?
You should be building the message body for each recipient, and then send your messages by recipient instead of group. You could do this by following these steps:
Create a global list of recipients
Get the list of recipients a group
Loop through the recipients list. If the recipient already exists, append the additional message body to their record. If not, create a new record in the global list.
Repeat steps 2-3 through all groups.
Loop through the global list of recipients, and send one message per recipient.