Accessing COM reference in Wix version

This forum is for discussing Mailtraq's Scripting features. Get help with Mailtraq scripts, templates and external ActiveX scripting.

Accessing COM reference in Wix version

Postby hottroc » Mon Mar 21st, 2011 3:21pm

Hi,

I want to revisit something I did years ago (Elric may remember). It's an Outlook "add-in" (for want of a better phrase) that accesses the Mailtraq bayesian anti-spam database and tells it that a message is spam or not spam from the mail client (ie without having to go into Webmail or the Mtq console).
This was complete and working fine when I was using Mtq on XP but now I use the Wix version on Win 7 64-bit. So I used to reference the COM object in VB but can't seem to do that now. Do I need to do something special to be able to enable it?

Thanks.
hottroc
Expert User
 
Posts: 106
Joined: Tue Jul 24th, 2007 4:23pm

Re: Accessing COM reference in Wix version

Postby Elric Pedder » Mon Mar 21st, 2011 10:15pm

hottroc wrote:I want to revisit something I did years ago (Elric may remember). It's an Outlook "add-in" (for want of a better phrase) that accesses the Mailtraq bayesian anti-spam database and tells it that a message is spam or not spam from the mail client (ie without having to go into Webmail or the Mtq console).

I do vaguely remember that. You are quite right in that the WiX version does not support the COM server that you describe, for good reasons. We have a much better system in place now and in fact much closer to what you originally needed.

Unfortunately you would have to rewrite the script to use the Remote API, which is unfortunately not yet documented. It may be a useful test case for everyone though so if you could explain a bit about your add-in and perhaps share your old code I could assist in providing an update.

The Remote API is a COM server that would be installed on the machine running Outlook, which in turn uses RPC calls to access Mailtraq on another computer, if that helps.
Mailtraq Development and Escalation Support
Novitraq Incorporated
User avatar
Elric Pedder
Mailtraq Escalation Support
 
Posts: 2675
Joined: Tue Nov 23rd, 2004 1:16pm
Location: Montreal, Canada

Re: Accessing COM reference in Wix version

Postby hottroc » Tue Mar 22nd, 2011 8:31am

OK well you asked for it! :-)

The reason I never shared it before was because it is rather amateurish and poorly documented (never had time to improve this) and very much a work in progress. I've also fiddled with it several times in different versions of Vb/Vs/.net and I'm now not 100% positive of which version was the working one. I'm not sure you will make head nor tail of it but here goes....

Code: Select all

Sub Main()
'Stage 1 - initialise things
Dim objApp As Outlook.Application
Dim mtqapp As Mailtraq.Control
Dim objSel As Selection
Dim objItem As MailItem
Dim outmsghead As String
Dim outmsgheadno As Variant
Dim filename As String
Dim archive As String
Dim success As Integer
Dim myNamespace As Object
Dim internetHeaders As String
Dim objCDO As MAPI.Session
    Dim objMessage As MAPI.Message
    Dim objFields As MAPI.Fields
    Dim strID As String
    Const CdoPR_TRANSPORT_MESSAGE_HEADERS = &H7D001E
archive = "mailstore"  ' this is just a mailbox that all incoming mail is copied into and kept for a while
On Error Resume Next 'better error-handling added in later version
MsgBox archive, 0, "Learning to Reject"
Set objApp = GetObject(, "Outlook.Application")
Set objSel = objApp.ActiveExplorer.Selection
Set mtqapp = New Mailtraq.Control
Dim mtqmslot As Object
Set mtqmslot = mtqapp.Config.GetMailslot(archive)
'Stage2 - run through the messages that have been preselected in Outlook that you want to teach
For Each objItem In objSel
   If objItem.Class = 43 Then
    strID = objItem.EntryID
    Set objCDO = CreateObject("MAPI.Session")
    objCDO.Logon "", "", False, False

    'Now get the item as a CDO Message
    Set objMessage = objCDO.GetMessage(strID)

    'Now get the headers from the message
    Set objFields = objMessage.Fields
    internetHeaders = objFields.Item(CdoPR_TRANSPORT_MESSAGE_HEADERS).Value
    'Now that the headers are captured in a string you can do whatever you want with them
    'MsgBox internetHeaders - uncomment to check this stage

    objCDO.Logoff

    Set objFields = Nothing
    Set objMessage = Nothing
    Set objCDO = Nothing
   
    'this section removes the message-id from the header string
    outmsghead = ""
    outmsgheadno = 0
    outmsgheadno = InStr(1, internetHeaders, "Message-ID")
    outmsgheadno = outmsgheadno + 13
'stage 3 - learn the message
    While (Mid(internetHeaders, outmsgheadno, 1)) <> ">"
        outmsghead = outmsghead & Mid(internetHeaders, outmsgheadno, 1)
        outmsgheadno = outmsgheadno + 1
    Wend
    filename = mtqmslot.FindMessageId(outmsghead)
    'MsgBox outmsghead
    'MsgBox filename
    'MsgBox "That's all folks"
    success = mtqmslot.AntiSpamLearn(filename, False)
    MsgBox success ' customise this
   End If
Next

Set objItem = Nothing
End Sub



I am happy to rewrite, the reason for this topic really, but need to know the equivalent to the Mailtraq.Control object or whatever.

Note the code above is only part of the story, there was also some code which identified the user and switched the relevant contexts etc using impersonation, the code was run using a bat file that called psexec to run it with admin rights etc but for simplicity I've just included the Mtq-relevant bit. also this is the "reject" version, there is an "accept" equivalent almost the same.

Thanks for any help you can supply.
hottroc
Expert User
 
Posts: 106
Joined: Tue Jul 24th, 2007 4:23pm

Re: Accessing COM reference in Wix version

Postby Elric Pedder » Tue Mar 22nd, 2011 10:14am

Firstly you will need the Mailtraq Remote COM Server. Extract and install with

Code: Select all
regsvr32 MailtraqRemote.dll

The Remote API starts with a "Connection" object and you need to log it in to the server using the credentials for an account with System Administration privileges. I'm using Javascript here (save files ending in ".js" to call with cscript.exe)

Code: Select all
var mailtraq = new ActiveXObject("MailtraqRemote.Connection");
var hr = mailtraq.Login("192.168.1.1", "admin", "password");
if (hr == 0) {
  // login succeeded
}

Getting objects is a little different in this system. To get a mailslot, use this

Code: Select all
var id = mailtraq.Server.Mailslots.FindByName("example");
if (id) {
  var slot = mailtraq.Server.Mailslots.Get(id);
} else {
  // couldn't find it
}

The FindMessageId() method is the same but to train the anti-spam database you use ConsentLearnMessages(idlist, ham, unlearn). I'll have a go at editing your message but the last time I successfully wrote a program in Basic was in the eighties.

Code: Select all
Sub Main()
'Stage 1 - initialise things
Dim objApp As Outlook.Application
Dim mtqapp As MailtraqRemote.Connection
mtqapp.Login("127.0.0.1", "admin", "password")
Dim objSel As Selection
Dim objItem As MailItem
Dim outmsghead As String
Dim outmsgheadno As Variant
Dim filename As String
Dim archive As String
Dim success As Integer
Dim myNamespace As Object
Dim internetHeaders As String
Dim objCDO As MAPI.Session
    Dim objMessage As MAPI.Message
    Dim objFields As MAPI.Fields
    Dim strID As String
    Const CdoPR_TRANSPORT_MESSAGE_HEADERS = &H7D001E
archive = "mailstore"  ' this is just a mailbox that all incoming mail is copied into and kept for a while
On Error Resume Next 'better error-handling added in later version
MsgBox archive, 0, "Learning to Reject"
Set objApp = GetObject(, "Outlook.Application")
Set objSel = objApp.ActiveExplorer.Selection
' Set mtqapp = New Mailtraq.Control
Dim mtqmslot As Object
' Set mtqmslot = mtqapp.Config.GetMailslot(archive)
Set mtqmslot = mtqapp.Server.Mailslots.Get(mtqapp.Server.Mailslots.FindByName(archive))
'Stage2 - run through the messages that have been preselected in Outlook that you want to teach
For Each objItem In objSel
   If objItem.Class = 43 Then
    strID = objItem.EntryID
    Set objCDO = CreateObject("MAPI.Session")
    objCDO.Logon "", "", False, False

    'Now get the item as a CDO Message
    Set objMessage = objCDO.GetMessage(strID)

    'Now get the headers from the message
    Set objFields = objMessage.Fields
    internetHeaders = objFields.Item(CdoPR_TRANSPORT_MESSAGE_HEADERS).Value
    'Now that the headers are captured in a string you can do whatever you want with them
    'MsgBox internetHeaders - uncomment to check this stage

    objCDO.Logoff

    Set objFields = Nothing
    Set objMessage = Nothing
    Set objCDO = Nothing
   
    'this section removes the message-id from the header string
    outmsghead = ""
    outmsgheadno = 0
    outmsgheadno = InStr(1, internetHeaders, "Message-ID")
    outmsgheadno = outmsgheadno + 13
'stage 3 - learn the message
    While (Mid(internetHeaders, outmsgheadno, 1)) <> ">"
        outmsghead = outmsghead & Mid(internetHeaders, outmsgheadno, 1)
        outmsgheadno = outmsgheadno + 1
    Wend
    filename = mtqmslot.FindMessageId(outmsghead)
    'MsgBox outmsghead
    'MsgBox filename
    'MsgBox "That's all folks"
    'success = mtqmslot.AntiSpamLearn(filename, False)
    success = mtqmslot.ConsentLearnMessages(filename, False)
    MsgBox success ' customise this
   End If
Next

Set objItem = Nothing
End Sub

Let me know how that goes.
Mailtraq Development and Escalation Support
Novitraq Incorporated
User avatar
Elric Pedder
Mailtraq Escalation Support
 
Posts: 2675
Joined: Tue Nov 23rd, 2004 1:16pm
Location: Montreal, Canada

Re: Accessing COM reference in Wix version

Postby hottroc » Tue Mar 22nd, 2011 11:08am

Thanks very much Elric.

I must have started to try this once before as I already had a MailtraqRemote.zip file in my Download folder, dated 2009. Probably I got stuck and never pursued it (I think perhaps around the time that the old mailing list stopped) but now hopefully, with your welcome pointers, I may be able to get it going.

I'll have a go and let you know how I get on.

Cheers and thanks again.
hottroc
Expert User
 
Posts: 106
Joined: Tue Jul 24th, 2007 4:23pm

Re: Accessing COM reference in Wix version

Postby hottroc » Wed Mar 23rd, 2011 5:30pm

Could you just clarify for me please...regarding this line:
Code: Select all
var hr = mailtraq.Login("192.168.1.1", "admin", "password");

...and indeed the whole MailtraqRemote object I suppose...basically will this work if the app is run from a normal user account ie not an administrator account, or will I have to jump through all the hoops I had to before with impersonation and changing contexts etc?
(Basically Outlook has to run as the user, because if it runs as the Administrator it wrongly shows the Administrators mailbox, so I had to fool the app in my code mid-process, it was messy)
hottroc
Expert User
 
Posts: 106
Joined: Tue Jul 24th, 2007 4:23pm

Re: Accessing COM reference in Wix version

Postby Elric Pedder » Wed Mar 23rd, 2011 5:34pm

hottroc wrote:Could you just clarify for me please...regarding this line:
Code: Select all
var hr = mailtraq.Login("192.168.1.1", "admin", "password");

It is just that currently the MailtraqRemote object can only be used by (Mailtraq) administrators, so you must authorise the connection accordingly.

hottroc wrote:...and indeed the whole MailtraqRemote object I suppose...basically will this work if the app is run from a normal user account ie not an administrator account, or will I have to jump through all the hoops I had to before with impersonation and changing contexts etc?
(Basically Outlook has to run as the user, because if it runs as the Administrator it wrongly shows the Administrators mailbox, so I had to fool the app in my code mid-process, it was messy)

I don't recall the issue with impersonation previously but as far as I know you can use the MailtraqRemote object in a user process. Previously the COM object may have required that an administrator's user context be used by because communication is now done via TCP/IP you don't need that any more.
Mailtraq Development and Escalation Support
Novitraq Incorporated
User avatar
Elric Pedder
Mailtraq Escalation Support
 
Posts: 2675
Joined: Tue Nov 23rd, 2004 1:16pm
Location: Montreal, Canada

Re: Accessing COM reference in Wix version

Postby hottroc » Wed Mar 23rd, 2011 6:12pm

Great thanks, that eliminates that as the problem. Basically I have the code working but it's not achieving the desired effect. I think I have tracked down the reason. I am still experimenting but it seems to be related to this:
Code: Select all
outmsgheadno = InStr(1, internetHeaders, "Message-ID", vbTextCompare)


Basically the Message-ID header used to be the 13-character id I needed but this seems to reference something else now and what I need is just called "id". Do you remember this changing sometime in the past or is it my imagination?

Either way I'll continue experimenting for now and let you know how I get on.
Thanks for your help so far.


EDIT - OK, I've resolved that bit now and I'm getting the header I need. But now the next bit that doesn't seem to work is:
Code: Select all
filename = mtqmslot.FindMessageId(msgidarray(i))

...where msgidarray(i) is correctly showing the id of the message and mtqmslot seems to be correctly returning the object, so "FindMessageId" does not appear to be supported or something. Can you help? Or is this step superfluous, sorry it's getting a little late and I might be confusing myself here, it's been a long day for other reasons.
hottroc
Expert User
 
Posts: 106
Joined: Tue Jul 24th, 2007 4:23pm

Re: Accessing COM reference in Wix version

Postby Elric Pedder » Wed Mar 23rd, 2011 6:58pm

hottroc wrote:OK, I've resolved that bit now and I'm getting the header I need. But now the next bit that doesn't seem to work is:
Code: Select all
filename = mtqmslot.FindMessageId(msgidarray(i))

...where msgidarray(i) is correctly showing the id of the message and mtqmslot seems to be correctly returning the object, so "FindMessageId" does not appear to be supported or something. Can you help? Or is this step superfluous, sorry it's getting a little late and I might be confusing myself here, it's been a long day for other reasons.

FindMessageId() should be working. It takes a string which contains the value of the "Message-Id" header. You could try it with and without the surrounding angle brackets to test. Do you have any idea what the function is returning? To test you could manually enter an ID you got from an existing message.
Mailtraq Development and Escalation Support
Novitraq Incorporated
User avatar
Elric Pedder
Mailtraq Escalation Support
 
Posts: 2675
Joined: Tue Nov 23rd, 2004 1:16pm
Location: Montreal, Canada

Re: Accessing COM reference in Wix version

Postby hottroc » Wed Mar 23rd, 2011 8:10pm

Hmmm. Thanks for the info. I'm a bit stuck.

Firstly in my Spam message I'm using to test, in the headers there is a field called " id" with a value HTTRE0A55C7B and a field
"Message-ID" with value "<bx7zmq4b9hmm26au6p8ctqchccabff.14706579166.6825@mta734.nextmail.co.uk>". So I use the latter in the FindMessageId function?

When I do that it returns a value of HTTRE0A55C82 which is similar to the " id" but not quite the same. But anyway when I try the ConsentLearnMessages function with this it doesn't appear to have the desired effect even though it returns 0 (success).

Here is the relevant part of the code:

Code: Select all
filename = mtqmslot.FindMessageId(strarraytemp)
            success = mtqmslot.ConsentLearnMessages(filename, False)
            If success = 0 Then
                MsgBox("Operation succeeded", , "Success")
            Else
                MsgBox("Something went wrong", , "Failed")
            End If


Any ideas?
hottroc
Expert User
 
Posts: 106
Joined: Tue Jul 24th, 2007 4:23pm

Re: Accessing COM reference in Wix version

Postby Elric Pedder » Wed Mar 23rd, 2011 8:47pm

hottroc wrote:Firstly in my Spam message I'm using to test, in the headers there is a field called " id" with a value HTTRE0A55C7B and a field "Message-ID" with value "<bx7zmq4b9hmm26au6p8ctqchccabff.14706579166.6825@mta734.nextmail.co.uk>".

The first one isn't a field, just a segment from the Received: header. That is the identifier of the message within the SMTP transaction. It is not necessarily the same as the filename within the mailbox. They are both generated from the same sequencer which is why they are similar. You need the second one (as you are doing) as a key to find the message in the mailbox.

hottroc wrote:But anyway when I try the ConsentLearnMessages function with this it doesn't appear to have the desired effect even though it returns 0 (success).

Actually it returns a boolean, true if the mailbox has anti-spam enabled and false if it doesn't. The result is not a measure of success unfortunately. What those values are in integers (which you are using to compare) depends on VB. When you say it isn't having the desired effect, how can you tell?
Mailtraq Development and Escalation Support
Novitraq Incorporated
User avatar
Elric Pedder
Mailtraq Escalation Support
 
Posts: 2675
Joined: Tue Nov 23rd, 2004 1:16pm
Location: Montreal, Canada

Re: Accessing COM reference in Wix version

Postby hottroc » Wed Mar 23rd, 2011 9:04pm

OK thanks for clarifying. I've realised with your help that the part that was going wrong getting the Message-ID was because I was using a vb string-compare function looking for "Message-ID" but unfortunately in the headers there was a mention of "Message-ID" before the actual Message-ID. I've changed my code to match "Message-ID: <" and it's now working fine and I've confirmed by checking the filename in the Console so that part is good.

Just the ConsentLearnMessages part now. Although it appears to work the reason I don't think it is is simply checking the numbers in the console for "Features in Database" and "Messages in Database" which don't appear to be changing. I'm fairly sure that I haven't taught the system this message before.
hottroc
Expert User
 
Posts: 106
Joined: Tue Jul 24th, 2007 4:23pm

Re: Accessing COM reference in Wix version

Postby Elric Pedder » Wed Mar 23rd, 2011 9:09pm

hottroc wrote:Just the ConsentLearnMessages part now. Although it appears to work the reason I don't think it is is simply checking the numbers in the console for "Features in Database" and "Messages in Database" which don't appear to be changing. I'm fairly sure that I haven't taught the system this message before.

Just to verify, can you find the message in the console and check the flags column. There is a flag to indicate the message has been trained and each message can only be trained once. You can untrain the message and then re-train though.
Mailtraq Development and Escalation Support
Novitraq Incorporated
User avatar
Elric Pedder
Mailtraq Escalation Support
 
Posts: 2675
Joined: Tue Nov 23rd, 2004 1:16pm
Location: Montreal, Canada

Re: Accessing COM reference in Wix version

Postby hottroc » Wed Mar 23rd, 2011 9:42pm

The Flags column is visible but there is nothing in it for this message so I guess that means it hasn't been trained one way or the other?
Just a quick thought, I may be way off, it wouldn't be that the database is full would it? It shows the size as 64Mb (Fixed)? I don't think it's that.
Another thought, could it be because I'm testing this from within Vis. Studio? Don't think it's that either.
More likely - I have been having a few permissions problems with Windows 7. Yes I'm the Administrator but still sometimes it won't let me write to certain folders. Maybe something to do with that?

PS Thanks again for your help with this.
hottroc
Expert User
 
Posts: 106
Joined: Tue Jul 24th, 2007 4:23pm

Re: Accessing COM reference in Wix version

Postby Elric Pedder » Wed Mar 23rd, 2011 10:39pm

hottroc wrote:The Flags column is visible but there is nothing in it for this message so I guess that means it hasn't been trained one way or the other?

That's what I think too.
hottroc wrote:Just a quick thought, I may be way off, it wouldn't be that the database is full would it? It shows the size as 64Mb (Fixed)? I don't think it's that.

No it isn't that. The database is always 64mb.
hottroc wrote:Another thought, could it be because I'm testing this from within Vis. Studio? Don't think it's that either.
More likely - I have been having a few permissions problems with Windows 7. Yes I'm the Administrator but still sometimes it won't let me write to certain folders. Maybe something to do with that?

No to either of those. The fact that the FindMessageId() worked means everything else is Ok. Could you try calling ConsentLearnMessages() with three parameters?
Code: Select all
mtqmslot.ConsentLearnMessages(filename, False, False)

hottroc wrote:PS Thanks again for your help with this.

No problem. I'm glad to see any experiments with this system.
Mailtraq Development and Escalation Support
Novitraq Incorporated
User avatar
Elric Pedder
Mailtraq Escalation Support
 
Posts: 2675
Joined: Tue Nov 23rd, 2004 1:16pm
Location: Montreal, Canada

Next

Return to Mailtraq Scripting

Who is online

Users browsing this forum: No registered users and 3 guests

cron