I need to trigger a routine, when a new email is received on a smtp server.
I foun information about plug-in develpment for outlook but i figure pugins have to be installed in client.
Well, the only way that should work for me is cacthing theNEW_MAIL envet on smtp server using a Service.
Is that possible? Thanks.
I have to catch de new email when it is received.
Validate If has an attached file.
Validate file name,
if file name is correct
get the attached file and download to a file server...
I created an script in the OutlookSession and applied as rule.
There is a tutorial: Apply rule.... has an attachment and run script
Public Sub Drc(emailItem As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim targetFolder As String
Dim fileName As String
Dim regxpr As String
Dim fileType As String
Dim iFrom As String
iFrom = "******"
Dim isubject As String
isubject = emailItem.Subject
If emailItem.Sender = iFrom And ValidateFileName(isubject) Then
For Each objAtt In emailItem.Attachments
fileType = Split(objAtt.DisplayName, ".")(1)
targetFolder = "C:\TestCsvDirectory\ToProcess"
If ValidateFileName(objAtt.DisplayName) And LCase(fileType) = "csv" Then
objAtt.SaveAsFile (targetFolder & "\" & objAtt.DisplayName)
End If
Next
End If
Related
All of the documentation for SpeechClient that I've found involves either running a command line after downloading the SDK, or awkwardly setting up a "GOOGLE_APPLICATION_CREDENTIALS" environment variable to point to a local credential file.
I hate the environment variable approach, and instead want a solution that loads a shared, source-controlled dev account file from the application root. Something like this:
var credential = GoogleCredential.FromStream(/*load shared file from app root*/);
var client = SpeechClient.Create(/*I wish I could pass credential in here*/);
Is there a way to do this so that I don't have to rely on the environment variable?
Yes, by converting the GoogleCredential into a ChannelCredentials, and using that to initialize a Channel, which you then wrap in a SpeechClient:
using Grpc.Auth;
//...
GoogleCredential googleCredential;
using (Stream m = new FileStream(credentialsFilePath, FileMode.Open))
googleCredential = GoogleCredential.FromStream(m);
var channel = new Grpc.Core.Channel(SpeechClient.DefaultEndpoint.Host,
googleCredential.ToChannelCredentials());
var speech = SpeechClient.Create(channel);
Update 2018-02-02 https://cloud.google.com/docs/authentication/production now shows all they possible ways to authenticate to a Google Cloud Service, including a sample like this one.
In latest version SpeechClient.Create does not have any parameters.
Now it is possible to do it using SpeechClientBuilder:
var client = new SpeechClientBuilder { ChannelCredentials = credentials.ToChannelCredentials() }.Build();
'Install-Package Google.Cloud.Speech.V1 -Version 3.0.0
Imports Google.Cloud.Speech.V1
'Dim sCredentialsPath As String = "C:\google_keys\deft.json"
'Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", sCredentialsPath)
'Dim oSpeechClient As SpeechClient = Google.Cloud.Speech.V1.SpeechClient.Create()
Dim oSpeechSettings As New SpeechSettings()
Dim oSpeechClient = New SpeechClientBuilder With {
.CredentialsPath = sCredentialsPath
}.Build()
Dim oRecognitionAudio As RecognitionAudio = RecognitionAudio.FromFile("C:\Temp\test.weba")
Dim oRecognitionConfig As New RecognitionConfig
'oRecognitionConfig.SampleRateHertz = 44100
oRecognitionConfig.LanguageCode = LanguageCodes.English.UnitedStates '"en-US"
oRecognitionConfig.Encoding = RecognitionConfig.Types.AudioEncoding.WebmOpus
Dim oRecognizeResponse As RecognizeResponse = oSpeechClient.Recognize(oRecognitionConfig, oRecognitionAudio)
Dim sRet As String = ""
For Each oResult As Google.Cloud.Speech.V1.SpeechRecognitionResult In oRecognizeResponse.Results
For Each oAlternative As Google.Cloud.Speech.V1.SpeechRecognitionAlternative In oResult.Alternatives
sRet += oAlternative.Transcript
Next
Next
Frequently undesirable messages are received even after any good spam/virus filter.
As a secondary wall, we suggest our user to check the suspicious message properties ('internet headers') to verify the real origin. This action, for the non-tech guys is not easy.
I wrote a simple application to drag the message into it and analyze the headers locating IP addresses and origin: obviously, if the message is from your mother, you know she is not in China...
How can we get the 'internet headers' from the message? Is there any hidden property there?
Private Sub MainForm_DragDrop(sender As Object, e As DragEventArgs) Handles Me.DragDrop
Dim myOlApp As New Outlook.Application
Dim myExp As Outlook.Explorer = myOlApp.ActiveExplorer
Dim myMailItem As Outlook.MailItem = DirectCast(myExp.Selection.Item(1), Outlook.MailItem)
Dim x = myMailItem.Body
myExp = Nothing
myMailItem = Nothing
myOlApp = Nothing
End Sub
This works fine to get the body and other data like To, From etc, however no property expose 'Internet Headers'.
You need to read the PR_TRANSPORT_MESSAGE_HEADERS MAPI property:
Dim headers As String = myMailItem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001F")
I'm trying to move a mail item form 1 store to another, using Outlook 2010 and C#
I'm gotten quite far, but not sure how I perform the 'move'. I'm assuming it's saveas and then delete
My attempt (code greatly reduced)
foreach (var mail in folder.Items)
{
//I am in the correct folder, and all I want to do is move all items to the 'inbox' of the store. I have already gotten the destination store and saved it as a variable called store
Microsoft.Office.Interop.Outlook.MailItem mailItem = (Microsoft.Office.Interop.Outlook.MailItem)mail; //got the item
mailItem.SaveAs(store.FilePath, Microsoft.Office.Interop.Outlook.OlSaveAsType.olMSG); // throws exception
mailItem.Delete();
}
I'm not sure if this is the best approach, but the line mailItem.SaveAs(store.FilePath, Microsoft.Office.Interop.Outlook.OlSaveAsType.olMSG); throws an exception:
The operation failed
I see no more detail other than that
The SaveAs method saves the Microsoft Outlook item to the specified path and in the format of the specified file type. If the file type is not specified, the MSG format (.msg) is used. So, the method is used to save items on the disk, not another store in Outlook.
You can use the Move method of the MailItem class to move a Microsoft Outlook item to a new folder. For example:
Sub MoveItems()
Dim myNameSpace As Outlook.NameSpace
Dim myInbox As Outlook.Folder
Dim myDestFolder As Outlook.Folder
Dim myItems As Outlook.Items
Dim myItem As Object
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myItems = myInbox.Items
Set myDestFolder = myInbox.Folders("Personal Mail")
Set myItem = myItems.Find("[SenderName] = 'Eugene'")
While TypeName(myItem) <> "Nothing"
myItem.Move myDestFolder
Set myItem = myItems.FindNext
Wend
End Sub
I run the following code but nothing shows up in ALM:
AttachmentFactory attachmentFactory = (AttachmentFactory)tsTest.Attachments;
TDAPIOLELib.Attachment attachment = (TDAPIOLELib.Attachment)attachmentFactory.AddItem("test");
attachment.Post();
The AddItem method on the second line keeps asking for "object ItemData" but I have no idea what that is exactly. HP has such poor documentation that there is really nothing explaining it. Does anyone know how to programatically using c# add a file attachment to a test run in HP ALM?
After much pain and research I have found an answer. I'm sure there are other ways of accomplishing this that are more efficient but since HP's documentation is the worst on the planet this is the best I could come up with. If anyone has a better way I would LOVE to see it so please post it!
I hope this helps!
try
{
if (qcConn.Connected)
{
string testFolder = #"Root\YourFolder";
TestSetTreeManager tsTreeMgr = (TestSetTreeManager)qcConn.TestSetTreeManager;
TestSetFolder tsFolder = (TestSetFolder)tsTreeMgr.get_NodeByPath(testFolder);
AttachmentFactory attchFactory = (AttachmentFactory)tsFolder.Attachments;
List tsList = tsFolder.FindTestSets("YourTestNameHere", false, null);
foreach (TestSet ts in tsList)
{
TestSetFolder tstFolder = (TestSetFolder)ts.TestSetFolder;
TSTestFactory tsTestFactory = (TSTestFactory)ts.TSTestFactory;
List mylist = tsTestFactory.NewList("");
foreach (TSTest tsTest in mylist)
{
RunFactory runFactory = (RunFactory)tsTest.RunFactory;
Run run = (Run)runFactory.AddItem("NameYouWantDisplayedInALMRuns");
run.CopyDesignSteps();
//runResult just tells me if overall my test run passes or fails - it's not built in. It was my way of tracking things though the code.
if(runResult)
run.Status = "Failed";
else
run.Status = "Passed";
run.Post();
//Code to attach an actual file to the test run.
AttachmentFactory attachmentFactory = (AttachmentFactory)run.Attachments;
TDAPIOLELib.Attachment attachment = (TDAPIOLELib.Attachment)attachmentFactory.AddItem(System.DBNull.Value);
attachment.Description = "Attach via c#";
attachment.Type = 1;
attachment.FileName = "C:\\Program Files\\ApplicationName\\demoAttach.txt";
attachment.Post();
//Code to attach a URL to the test run
AttachmentFactory attachmentFactory = (AttachmentFactory)run.Attachments;
TDAPIOLELib.Attachment attachment = (TDAPIOLELib.Attachment)attachmentFactory.AddItem(System.DBNull.Value);
//Yes, set the description and FileName to the URL.
attachment.Description = "http://www.google.com";
attachment.Type = 2;
attachment.FileName = "http://www.google.com";
attachment.Post();
//If your testset has multiple steps and you want to update
//them to pass or fail
StepFactory rsFactory = (StepFactory)run.StepFactory;
dynamic rdata_stepList = rsFactory.NewList("");
var rstepList = (TDAPIOLELib.List)rdata_stepList;
foreach (dynamic rstep in rstepList)
{
if (SomeConditionFailed)
rstep.Status = "Failed";
else
rstep.Status = "Passed";
rstep.Post();
}
else
{
rstep.Status = "No Run";
rstep.Post();
}
}
}
}
}
}
I have done something similar, but in Python and against Test Steps, so even if I don't have code you can copy & paste it, this might point you to the right direction.
Instead of calling:
attachmentFactory.AddItem( filename )
Call the function with no parameters (or a null paramer, can't tell since I never used the OTA API with C#):
file = attachmentFactory.AddItem()
Now assign the file to the attachment item, and the rest of its properties:
file.Filename = "C:\\Users\\myUser\\just\\an\\example\\path" + fileName
file.Description = "File description"
file.Type=1
file.Post()
The type specifies it's a local file, and not an URL.
If anyone is wondering how to do that on the requirement-module, here is the code:
Req req = Globals.Connection.ReqFactory.Item(*ID*));
VersionControl versionControl = ((IVersionedEntity)req).VC as VersionControl;
versionControl.CheckOut(string.Empty);
AttachmentFactory attFac = req.Attachments;
Attachment att = (Attachment)attFac.AddItem(System.DBNull.Value);
att.Description = "*Your description here";
att.Type = (int)TDAPI_ATTACH_TYPE.TDATT_FILE; //for URL, change here
att.FileName = "*Your path including filename here*";
att.Post();
versionControl.CheckIn("*Your check-in comment here*");
No valuable information on Internet!
After some digging on OTA documentation I have found this:
AttachmentFactory attachmentFactory = (AttachmentFactory)TstTest.Attachments;
TDAPIOLELib.Attachment attachment = (TDAPIOLELib.Attachment)attachmentFactory.AddItem("demoAttach.txt");
attachment.Description = "Bug Sample Attachment";
attachment.Post();
IExtendedStorage exStrg = attachment.AttachmentStorage;
exStrg.ClientPath = "E:\\TestData";
exStrg.Save("demoAttach.txt", true);
actually, was in VB script form but I managed to transform in C#.
OTA reference:
'-----------------------------------------
'Use Bug.Attachments to
' get the bug attachment factory.
Set attachFact = bugObj.Attachments
'Add a new extended storage object,an attachment
' named SampleAttachment.txt.
Set attachObj = attachFact.AddItem("SampleAttachment.txt")
' Modify the attachment description.
attachObj.Description = "Bug Sample Attachment"
' Update the attachment record in the project database.
attachObj.Post
' Get the bug attachment extended storage object.
Set ExStrg = attachObj.AttachmentStorage
'Specify the location of the file to upload.
ExStrg.ClientPath = "D:\temp\A"
'-----------------------------------------
'Use IExtendedStorage.Save to
' upload the file.
ExStrg.Save "SampleAttachment.txt", True
I'm trying to do a repeater (as a proxy) for logging the data exchange between a SMTP client and a server. I thought it was only easy as:
Listening the client;
Listening client IP connection;
On call, connect to the server;
Send back server message;
Send the client messages to the server and return the server feedback to the client;
But, as I saw, some servers as MS exchange send multiple feedback witch are breaking the handshaking.Like:
250-SIZE 41943040
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-AUTH LOGIN
250-8BITMIME
250-BINARYMIME
250 CHUNKING
Here is the class
Imports System.Text
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Public Class SmtpProxy
Private client As TcpClient
Private cltstream As NetworkStream
Private cltreader As System.IO.StreamReader
Private cltwriter As System.IO.StreamWriter
Private smtpserver As New TcpClient
Private srvstream As NetworkStream
Private srvreader As System.IO.StreamReader
Private srvwriter As System.IO.StreamWriter
Private Shared mHostSrv As String
Public Shared Property HostSrv() As String
Get
Return mHostSrv
End Get
Set(ByVal value As String)
mHostSrv = value
End Set
End Property
Private Shared mServerPort As Integer = 25
Public Shared Property ServerPort() As Integer
Get
Return mServerPort
End Get
Set(ByVal value As Integer
)
mServerPort = value
End Set
End Property
Private Shared mUserNm As String
Public Shared Property UserNm() As String
Get
Return mUserNm
End Get
Set(ByVal value As String)
mUserNm = value
End Set
End Property
Private Shared mPassword As String
Public Shared Property Password() As String
Get
Return mPassword
End Get
Set(ByVal value As String)
mPassword = value
End Set
End Property
Public Sub New(ByVal client As TcpClient)
Me.client = client
cltstream = client.GetStream()
cltreader = New System.IO.StreamReader(cltstream)
cltwriter = New System.IO.StreamWriter(cltstream)
cltwriter.NewLine = vbCr & vbLf
cltwriter.AutoFlush = True
End Sub
Public Shared Sub Start() 'ByVal args As String())
Dim listener As New TcpListener(IPAddress.Loopback, 2525)
listener.Start()
While True
Dim handler As New SmtpProxy(listener.AcceptTcpClient())
Dim thread As Thread = New System.Threading.Thread(New ThreadStart(AddressOf handler.Run))
thread.Start()
End While
End Sub
Public Sub Run()
If mHostSrv Like "*.*.*.*" Then
Dim IpS As IPAddress = Nothing
IpS = IPAddress.Parse(mHostSrv)
smtpserver.Connect(IpS, mServerPort)
Else
smtpserver.Connect(mHostSrv, mServerPort)
End If
srvstream = smtpserver.GetStream
srvreader = New System.IO.StreamReader(srvstream)
srvwriter = New System.IO.StreamWriter(srvstream)
srvwriter.NewLine = vbCrLf
srvwriter.AutoFlush = True
Dim srvline As String = srvreader.ReadLine
cltwriter.WriteLine(srvline)
Debug.Print("Server sent: {0}", srvline & vbCrLf)
Try
Dim line As String = cltreader.ReadLine
While line IsNot Nothing
Debug.Print("Read line {0}", line)
srvwriter.WriteLine(line)
Application.DoEvents()
srvline = srvreader.ReadLine()
Debug.Print("Server sent: {0}", srvline)
cltwriter.WriteLine(srvline.Replace("-", " "))
Application.DoEvents()
line = cltreader.ReadLine()
End While
Catch ex As Exception
client.Close()
smtpserver.Close()
End Try
End Sub
End Class
I tried to read multiple server lines at a time but in the meantime the client return and error if I send the whole returned server lines...
Private Function ReadSrvLines() As String
Dim strRet As String = ""
Do
If strRet Like "220*" OrElse srvreader.EndOfStream Then Exit Do
Dim strTmp As String = srvreader.ReadLine
If strTmp Is Nothing Then Exit Do
strRet &= strTmp.Replace("-", " ") & vbCrLf
cltwriter.WriteLine(strTmp.Replace("-", " "))
Debug.Print("Server sent: {0}", strTmp.Replace("-", " ") & vbCrLf)
Loop
Return strRet
End Function
Then is anyone have any solutions to propose?
Thanks all!!
Frank
You will need to perform simultaneous asynchronous reading/writing between client and server to make this work properly. SMTP responses can contain any number of lines and client or server can return a message without the need for a command (to say bye for example). Parsing the data is also unnecessary to achieve a basic log.
Edit: If it helps, if the 3 digit message number if followed by a (minus) rather than a (space) it means that there is another line to follow.