In BizTalk 2004, to write any BAM event from the BizTalk pipeline, you will need to write some code :)  To simplify the learning, I will illustrate by adapting an SDK sample.

Adapt the SDK CustomComponent (found in .../SDK/Samples/Pipelines/CustomComponent) sample, you will find two directories:

  • FixMsg - the custom pipeline component (you will need to splice BAM code here) 
  • PipelineComponentSample - custom pipeline and will use the above custom pipeline component.

Modify the FixMsg to include the below sample (Search for Execute method):

public IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)
{

IBaseMessagePart bodyPart = inmsg.BodyPart;
if (bodyPart!=null)
{

...
...
//Splice BAM Code here:
WriteBAMEvent(pc, "Execute", inmsg);


}
return inmsg;

}


// Add a new method to write to BAM

private void WriteBAMEvent(IPipelineContext context, string StageDescription, IBaseMessage inmsg)
{

EventStream _BAMEventStr = null;
// Create an EventStream instance
try
{

// Use can use BES/DES or MES
// DES - DirectEventStream - writes direct to BAMPrimaryImport (Synchronous call, no latency)
//_BAMEventStr = new DirectEventStream("Integrated Security=SSPI;Data Source=.;Initial Catalog=BAMPrimaryImport",1);

// BES - BufferedEventStream - writes to MessageBox (Asynchronous call, no wait in call)
// _BAMEventStr = new BufferedEventStream("Integrated Security=SSPI;Data Source=.;Initial Catalog=BizTalkMsgBoxDb",1);

// MES - MessagingEventStream - Async and participates in Pipeline transaction context).
// - Note: Available in BizTalk 2004 with SP1 patch and Biztalk 2006
_BAMEventStr = context.GetEventStream();

}

catch(Exception e)
{

throw (e);

}

// Sample BAM Event Code here:
string ActivityID;
//Create a new, unique activity identifier to use as the ActivityID in BAM
ActivityID="BAM_" + Guid.NewGuid().ToString() + "_" + DateTime.Now + "_" + StageDescription;

//Start the activity record identified by ActivityID
_BAMEventStr.BeginActivity("PurchaseOrder",ActivityID);

_BAMEventStr.UpdateActivity("PurchaseOrder",ActivityID, "ProductName","QFE1117");

_BAMEventStr.EndActivity("PurchaseOrder",ActivityID);

// Optional Flush
//_BAMEventStr.Flush();

}

Reference on MessagingEventStream:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sdkmref[bts06]/html/M_Microsoft_BizTalk_Component_Interop_IPipelineContext_GetEventStream.asp

Reference on EventStream:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sdkmref[bts06]/html/T_Microsoft_BizTalk_Bam_EventObservation_EventStream.asp

To understand the above and details on how to fetch message specific data, please refer to sectio on Developing Pipeline Components in the help or use this link:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sdk/htm/ebiz_prog_pipe_qdri.asp
You would at least need to implement these interfaces.
IBaseComponent, IComponent, IComponentUI.

The above is tedious and is the only means for writing to BAM in Biztalk 2004. In Biztalk 2006, you can do some of this easily via TPE drag and drop.