No MessageId set for Attachments?

I started to look at a way to find ticket ID based on message ID. It
would be useful for us when needing to find out where a specific
message ended up in RT.

Lookin in the database, I noticed that the messageid column in the
attachments table always is NULL (Rt 3.2.1). Looking further, I
discovered that the Attachment class fail to parse out the MessageId,
and thus the value is never set.

This patch should fix the problem. Is this the correct location to
add this code?

Index: lib/RT/Attachment_Overlay.pm
— lib/RT/Attachment_Overlay.pm (revision 1413)
+++ lib/RT/Attachment_Overlay.pm (working copy)
@@ -153,6 +153,11 @@
defined($Subject) or $Subject = ‘’;
chomp($Subject);

  • #Get the MessageID
  • my $MessageId = $Attachment->head->get( ‘messageid’, 0 );
  • defined($MessageId) or $MessageId = ‘’;
  • chomp($MessageId);
    #Get the filename
    my $Filename = $Attachment->head->recommended_filename || eval {
    ${ $Attachment->head->{mail_hdr_hash}{‘Content-Disposition’}[0] }
    @@ -167,6 +172,7 @@
    Parent => 0,
    ContentType => $Attachment->mime_type,
    Headers => $Attachment->head->as_string,
  •        MessageId => $MessageId,
           Subject => $Subject);
    
       foreach my $part ( $Attachment->parts ) {

Petter Reinholdtsen wrote:

I started to look at a way to find ticket ID based on message ID. It
would be useful for us when needing to find out where a specific
message ended up in RT.

Lookin in the database, I noticed that the messageid column in the
attachments table always is NULL (Rt 3.2.1). Looking further, I
discovered that the Attachment class fail to parse out the MessageId,
and thus the value is never set.

This patch should fix the problem. Is this the correct location to
add this code?

Index: lib/RT/Attachment_Overlay.pm

— lib/RT/Attachment_Overlay.pm (revision 1413)
+++ lib/RT/Attachment_Overlay.pm (working copy)
@@ -153,6 +153,11 @@
defined($Subject) or $Subject = ‘’;
chomp($Subject);

  • #Get the MessageID
  • my $MessageId = $Attachment->head->get( ‘messageid’, 0 );
    I don’t think that MessageId should be ‘’ if it’s undefind. I prefer
    NULL, but anyway next code is more readable
    my $MessageId = $Attachment->head->get( ‘messageid’, 0 ) || ‘’;

then this trick with defined:

  • defined($MessageId) or $MessageId = ‘’;
    or:
    $MessageId = ‘’ unless defined $MessageId;
  • chomp($MessageId);
    useless

[Ruslan U. Zakirov]

I don’t think that MessageId should be ‘’ if it’s undefind. I prefer
NULL, but anyway next code is more readable

I just duplicated the code for subject. I agree that NULL would be
better.

  • chomp($MessageId);
    useless

If this is useless for MessageId, it is probably useless for the
subject as well.

Second try, making sure $MessageId is NULL if not available, and
dropping the useless chomp().

Index: lib/RT/Attachment_Overlay.pm
— lib/RT/Attachment_Overlay.pm (revision 1413)
+++ lib/RT/Attachment_Overlay.pm (working copy)
@@ -153,6 +153,9 @@
defined($Subject) or $Subject = ‘’;
chomp($Subject);

  • #Get the MessageID, or undef if not available
  • my $MessageId = $Attachment->head->get( ‘messageid’, 0 );
    #Get the filename
    my $Filename = $Attachment->head->recommended_filename || eval {
    ${ $Attachment->head->{mail_hdr_hash}{‘Content-Disposition’}[0] }
    @@ -167,6 +170,7 @@
    Parent => 0,
    ContentType => $Attachment->mime_type,
    Headers => $Attachment->head->as_string,
  •        MessageId => $MessageId,
           Subject => $Subject);
    
       foreach my $part ( $Attachment->parts ) {
    

[Petter Reinholdtsen]

  • #Get the MessageID, or undef if not available
  • my $MessageId = $Attachment->head->get( ‘messageid’, 0 );

Small typo here. ‘messageid’ should be ‘message-id’ to match the RFC
822 header name.

@@ -167,6 +170,7 @@
Parent => 0,
ContentType => $Attachment->mime_type,
Headers => $Attachment->head->as_string,

  •        MessageId => $MessageId,
           Subject => $Subject);
    
       foreach my $part ( $Attachment->parts ) {
    

This did not work. Adding the value as an argument to Create() did
not make it appear in the database. Any idea what is wrong?

There is two cases message is multipart and not in
Attachments_Overlay::Create(), you’ve added argument only in one place.

Petter Reinholdtsen wrote:

[Ruslan U. Zakirov]

There is two cases message is multipart and not in
Attachments_Overlay::Create(), you’ve added argument only in one place.

Doh, of course. I should get a larget terminal. :slight_smile:

Thank you very much for pointing this out.

This patch is tested and work as it should. Please include in a
future version of RT.

Now I just need to find a way to map a message id to ticket id. :slight_smile:

— lib/RT/Attachment_Overlay.pm 2004-07-12 20:00:53.000000000 +0200
+++ local/lib/RT/Attachment_Local.pm 2004-09-03 14:31:19.000000000 +0200
@@ -131,6 +131,10 @@
defined($Subject) or $Subject = ‘’;
chomp($Subject);

  • #Get the MessageID, or undef if not available
  • my $MessageId = $Attachment->head->get( ‘message-id’, 0 );
  • $RT::Logger->info( “Found message id ‘$MessageId’” );
    #Get the filename
    my $Filename = $Attachment->head->recommended_filename || eval {
    ${ $Attachment->head->{mail_hdr_hash}{‘Content-Disposition’}[0] }
    @@ -145,6 +149,7 @@
    Parent => 0,
    ContentType => $Attachment->mime_type,
    Headers => $Attachment->head->as_string,
  •        MessageId     => $MessageId,
           Subject => $Subject);
    
       foreach my $part ( $Attachment->parts ) {
    

@@ -176,6 +181,7 @@
ContentEncoding => $ContentEncoding,
Parent => $args{‘Parent’},
Headers => $Attachment->head->as_string,

  •                                   MessageId       => $MessageId,
                                      Subject       =>  $Subject,
                                      Content         => $Body,
                                      Filename => $Filename, );
    

[Ruslan U. Zakirov]

  • chomp($MessageId);
    useless

While trying to map from message id to ticketid, I discovered that
this ‘chomp’ call is needed to avoid a trailing newline in all message
ids.

With this change, I can look up ticket IDs by message ids using this
SQL code:

SELECT t.ticket from attachments a, transactions t
WHERE a.messageid = ‘message@id
AND (a.contenttype = ‘text/plain’ or a.contenttype = ‘text/html’)
AND a.parent = 0
AND a.transactionid = t.id;

How do I represent this using the Perl objects available in RT? I
posted some code I hoped would do this in January based on your input,
but didn’t get any comments. I am still very unskilled with this API,
so I do not understand why it fail.

This is my current test code. What is wrong with it? This is the
error message I get:

[Fri Sep 3 21:27:18 2004] [crit]: Can’t locate object method
“Ticket” via package “RT::Attachments” at ./rt-msgid line 75.
(/site/rt3/lib/RT.pm:257)

Here is the code:

#!/site/perl-5.8.4/bin/perl

rt-msgid: test if a message id is in RT.

use lib (“/site/rt3/lib”, “/site/rt3/local/lib”);
use strict;
use warnings;
use English;
use RT::Interface::CLI qw(CleanEnv);
use RT::User;
use RT::Template;
use RT::Attachments;

my $msgid = shift || “<rt-3.2.1-18-472-2.7.16367876566103@uio.no>”;

CleanEnv();
RT::LoadConfig();
RT::Init();

my $UserObj = new RT::User(RT::SystemUser);

print “Ticket: “,FindByMsgId($msgid),”\n”;

Look up ticket IDs given MessageID of attachment

SELECT t.ticket from attachments a, transactions t WHERE

a.messageid = ‘rt-3.2.1-18-472-2.7.16367876566103@uio.no

AND (a.contenttype = ‘text/plain’ or a.contenttype = ‘text/html’)

AND a.parent = 0

AND a.transactionid = t.id;

sub FindByMsgId {
my $msgid = shift;

print "Looking up msgid '$msgid'\n";

my @ids = ();

my $Attachs = RT::Attachments->new($RT::SystemUser);
$Attachs->Limit( FIELD => 'MessageId',
                 OPERATOR => '=',
                 VALUE => $msgid
                 );
$Attachs->Limit( FIELD => 'ContentType',
                 OPERATOR => '=',
                 VALUE => 'text/plain'
                 );
$Attachs->Limit( FIELD => 'ContentType',
                 OPERATOR => '=',
                 VALUE => 'text/html'
                 );
$Attachs->Limit( FIELD => 'Parent',
                 OPERATOR => '=',
                 VALUE => '0'
                 );
my $trs = $Attachs->NewAlias('Transactions');
my $tis = $Attachs->NewAlias('Tickets');

$Attachs->Join( ALIAS1 => 'main',
                FIELD1 => 'TransactionId',
                ALIAS2 => $trs,
                FIELD2 => 'id'
                );

$Attachs->Join( ALIAS1 => $trs,
                FIELD1 => 'Ticket',
                ALIAS2 => $tis,
                FIELD2 => 'id'
                );

while (my $ticket = $Attachs->Next) {
    my $ticketid = $Attachs->Ticket;
    print "Found ID $ticketid\n";
    push(@ids, $ticketid) if $ticketid;
}
return @ids;

}

Petter Reinholdtsen pere@hungry.com writes:
<-snip->

This is my current test code. What is wrong with it? This is the
error message I get:
[Fri Sep 3 21:27:18 2004] [crit]: Can’t locate object method
“Ticket” via package “RT::Attachments” at ./rt-msgid line 75.
(/site/rt3/lib/RT.pm:257)
<-snip->
while (my $ticket = $Attachs->Next) {

I’d rename $ticket to $attachment, as that’s what you’re looping over.

    my $ticketid = $Attachs->Ticket;

Here, you’ll need to do something like

      my $ticketid = $attachment->TransactionObj->Ticket;

instead. You might possibly want EffectiveTicket and not Ticket.

Espen Wiborg espenhw@empolis.no
“Stewardesses” is the longest word that is typed with only the left
hand.

[Espen Wiborg]

I’d rename $ticket to $attachment, as that’s what you’re looping over.

Good idea.

Here, you’ll need to do something like

      my $ticketid = $attachment->TransactionObj->Ticket;

Thank you. This worked. I now have the feature I want working. :slight_smile:

instead. You might possibly want EffectiveTicket and not Ticket.

I did not have to do this, as I send the ticket id into
Ticket::Load(), and it uses EffectiveTicket when needed.