Reporting

Dynamically Change Email Recipient?

Path Finder

Is there any easy to use the sendemail command to set the "to" field dynamically based on search results?

For example, if I have search results with the field toEmail="blah@blah.com" how can I use this with sendemail to send an email with results to blah@blah.com? When I do the following

| sendemail to=toEmail

it seems to take toEmail as a literal string. I'm hoping to avoid writing a complicated custom python script to be able to do this. Thanks!

Tags (1)
1 Solution

Path Finder

To answer my own question, I had to do this through a custom python script that loops through email fields, then calling the sendemail command in each loop with the email address as input. This actually works.

Caveat is that when calling the sendemail command through the python script, you need to be authenticated through the commandline. I created a Splunk-only (not LDAP) user with limited capabilities that gets authenticated each time the script is called using the auth tag.

Per request, here's the skeleton of the implementation (note, on Splunk 5):

  1. In Splunk manager, set up the scheduled search

    "whatever search that gets you the email addresses you want" | eval toEmail=fieldWithEmail | emailto

  2. On the server, in bin (I forget the precise details of how to get the script to get recognized, but I recall having to change permissions), create emailto.py with your custom bin locations and such:

    # this comment is here bc i couldnt figure out how to get code formatting to work otherwise
    

    import splunk.Intersplunk
    import subprocess
    from subprocess import Popen, PIPE, STDOUT

    class CustomEmail:
    def init(self, to_email):
    self.to = to_email

    def send_email(self):
        cc = 'some_email@to_be_cc_ed.com'
        command = 'YOUR_APP_DIR/bin/custom_email.sh %s %s' \
                  % (self.to, cc)
        output = 'none'
        try:
            p = Popen(command, shell=True, stdin=PIPE, stdout=PIPE,
                      stderr=PIPE, close_fds=True)
            output = p.stdout.read()
            if output == '':
                print p.stderr.read()
        except e:
            print e
        print('________________________________________________')
        print('Custom email ran for: %s' % self.to)
        print(output)
        return 'success'
    

    Get the previous search results

    (results, _, _) = splunk.Intersplunk.getOrganizedResults()

    Process each result

    for result in results:
    ce = CustomEmail(result["toEmail"])
    try:
    result["emailResults"] = ce.send_email()
    except Exception, e:
    print(str(e))

  3. Now write the shell script custom_email.sh contains the search that you want to run to be sent to the individual. It's first argument is the to email, and the second is the cc email. Play around with it to test outside of production. Having a hard time with code-formatting, so block quoting here...

export HOME=/opt/splunk
/opt/splunk/bin/splunk login -auth dummyuser:somepassword
/opt/splunk/bin/splunk search "sourcetype=\"whatever\" $1 earliest=-24h@h | sendemail to=\"$1\" bcc=\"$2\" from=\"from_address@you_re_using\" subject=\"Custom Email Report for $1\" sendresults=true"

View solution in original post

Super Champion

If you want to send all results to a single destination per alert, then you can do that by using the $result.<to_email>$ notation in the "To" field using modern version of Splunk (6.2, and later according to @tfruru), as mentioned in the docs. However, this is somewhat limited. It appears that Splunk just grabs $result.<field>$ based on the first output row.

If you need to get fancy and send emails to different to address on a per-row basis, then you should checkout the Sendresults add-on by Discovered Intelligence. Emails with the same email_to field will be grouped into a single email. Very nice!

0 Karma

Explorer

In Splunk 6.2 and above Just use mysearch | eval eMail="my@email.com" | sendemail to=$result.eMail$

Path Finder

Hi,
I am facing the problem while trying dynamic recipients for sendmail command. If you could share your script and relevant commands.conf file so that I check the arguments and options the sendmail.py, it will be great.
Thanks

0 Karma

Path Finder

To answer my own question, I had to do this through a custom python script that loops through email fields, then calling the sendemail command in each loop with the email address as input. This actually works.

Caveat is that when calling the sendemail command through the python script, you need to be authenticated through the commandline. I created a Splunk-only (not LDAP) user with limited capabilities that gets authenticated each time the script is called using the auth tag.

Per request, here's the skeleton of the implementation (note, on Splunk 5):

  1. In Splunk manager, set up the scheduled search

    "whatever search that gets you the email addresses you want" | eval toEmail=fieldWithEmail | emailto

  2. On the server, in bin (I forget the precise details of how to get the script to get recognized, but I recall having to change permissions), create emailto.py with your custom bin locations and such:

    # this comment is here bc i couldnt figure out how to get code formatting to work otherwise
    

    import splunk.Intersplunk
    import subprocess
    from subprocess import Popen, PIPE, STDOUT

    class CustomEmail:
    def init(self, to_email):
    self.to = to_email

    def send_email(self):
        cc = 'some_email@to_be_cc_ed.com'
        command = 'YOUR_APP_DIR/bin/custom_email.sh %s %s' \
                  % (self.to, cc)
        output = 'none'
        try:
            p = Popen(command, shell=True, stdin=PIPE, stdout=PIPE,
                      stderr=PIPE, close_fds=True)
            output = p.stdout.read()
            if output == '':
                print p.stderr.read()
        except e:
            print e
        print('________________________________________________')
        print('Custom email ran for: %s' % self.to)
        print(output)
        return 'success'
    

    Get the previous search results

    (results, _, _) = splunk.Intersplunk.getOrganizedResults()

    Process each result

    for result in results:
    ce = CustomEmail(result["toEmail"])
    try:
    result["emailResults"] = ce.send_email()
    except Exception, e:
    print(str(e))

  3. Now write the shell script custom_email.sh contains the search that you want to run to be sent to the individual. It's first argument is the to email, and the second is the cc email. Play around with it to test outside of production. Having a hard time with code-formatting, so block quoting here...

export HOME=/opt/splunk
/opt/splunk/bin/splunk login -auth dummyuser:somepassword
/opt/splunk/bin/splunk search "sourcetype=\"whatever\" $1 earliest=-24h@h | sendemail to=\"$1\" bcc=\"$2\" from=\"from_address@you_re_using\" subject=\"Custom Email Report for $1\" sendresults=true"

View solution in original post

New Member

Hi,
Can you please share the python script to send mail to dynamic recipients? It will be very helpful for me.

Thanks,
Santosh

0 Karma

Explorer

Is it possible to get a copy of your script?

0 Karma

Path Finder

yikes i just saw these requests. i'll see if i can find it / strip out stuff from it. no guarantees i will get back to this thread before another 5 years pass though 🙂