I'm trying to intercept and possibly modify all calls to mailService.sendMail
to add/modify a bcc
to emails going out. It is a temporary experiment so I want to avoid finding/changing all of the existing code if possible.
Example:
mailService.sendMail {
to '[email protected]'
//bcc may be present
from '[email protected]'
subject 'Hello'
body 'Just testing'
}
I'm able to intercept the calls easily enough with this created in Bootstrap:
mailService.metaClass.invokeMethod = {String name, args ->
println "intercepting for ${name}..."
def res = delegate.metaClass.getMetaMethod(name, args).invoke(delegate, args)
println "done intercepting"
}
I am at a complete loss as to how to actually modify the call to either add a bcc if none is present, or add an address to it if it does exist. The args
parameter is the closure - I've looked at everything I can find on the topic and no joy.
This is running on Grails 1.3.7 (I know).
One way you can always add a bcc
irrespective of bcc
being defined earlier, is by composing the original closure arg with a new one:
mailService.metaClass.invokeMethod = {String name, args ->
if( name == 'sendMail' ) {
def newArgs = args[0] >> { bcc '[email protected]' }
//or def newArgs = { bcc '[email protected]' } << args[0]
def res = delegate.metaClass.getMetaMethod(name, newArgs)
.invoke(delegate, newArgs)
}
}
Assuming mail should be bcc'd and bcc
list remains same, this way we do not have to keep track of supplied bcc
list. Make sure name of method is always checked to be sendMail
in order to avoid interception for other methods, although all methods will be intercepted in mailService
bean they will be skipped for others but sendMail
.
UPDATE:
Closure composition is available from Groovy 1.8 and I highly doubt Groovy 1.8 is available with Grails 1.3.7. In that case you can try the below approach otherwise:
mailService.metaClass.invokeMethod = {String name, args ->
if(name == 'sendMail') {
println "intercepting for ${name}..."
def newClos = { cl ->
return {
cl.delegate = delegate
cl.resolveStrategy = Closure.DELEGATE_FIRST
cl()
//bcc
bcc '[email protected]'
}
}
def newArgs = newClos args[0]
def res = delegate.metaClass.getMetaMethod(name, newArgs)
.invoke(delegate, newArgs)
println "done intercepting"
}
}