Twilio developer evangelist here.
Either of those approaches will work, though will have slightly different effects. Redirecting will cut the conference regardless of who is speaking at the time, but a bot joining in may get spoken over. It depends on which will work better for your use case.
To do the redirect, you'll need to run through the list of Conference participants, redirect them by updating their call to a new URL and return TwiML from that URL that plays the sound and redirects back to your original Conference URL. Something like:
$sid = "{{ account_sid }}";
$token = "{{ auth_token }}";
$client = new Services_Twilio($sid, $token);
// Loop over the list of participants and redirect ($client->account->conferences->get(CONFERENCE_SID)->participants as $participant) {
$call = $client->account->calls->get($participant->call_sid);
$call->update(array(
"Url" => "http://example.com/conference_message"
));
}
Then your /conference_message
endpoint would need TwiML like this:
<Response>
<Play>http://example.com/message.mp3</Play>
<Redirect>http://example.com/conference</Redirect>
</Response>
On the other hand, having a bot enter the room requires you to create a call to the conference number and supply a URL which points to the TwiML to play the message and then hangup. Like this:
$sid = "{{ account_sid }}";
$token = "{{ auth_token }}";
$client = new Services_Twilio($sid, $token);
$call = $client->account->calls->create(A_TWILIO_NUMBER, THE_CONFERENCE_NUMBER, "http://example.com/conference_message");
Then your /conference_message
endpoint would return TwiML like this:
<Response>
<Play>http://example.com/message.mp3</Play>
<Hangup/>
</Response>
Let me know if this helps at all.