Reading Time: 4 minutes

Introduction

I figured I’d do one more article on scriptable emailing and show off my latest work, PHP function that leverages PHPMailer module to send email notifications from your PHP code. This function can be found in a wrapper PHP test page on my GitHub at https://github.com/siggib007/phptest/blob/master/phpmailer.php and you are welcome to use it if you want.

As with my article on Emailing from python3 I set out with some simple requirements

  • Configurable To, From and Subject
  • Configurable custom email headers
  • Full support for HTML email body that is RFC compliant, including a text only alternative
  • Be able to accept a large text block (formatted or not) that gets turned into an email attachment
  • Be able to accept an absolute path to a file that should be added as an attachment.
  • Does not trigger spam filters

The Script

Just like the python function, this PHP function accomplishes all these goals, although I only tested the file path thing on a Linux PHP server. As with the python function just grab this file from GitHub and copy the SendHTMLAttach function along with the StripHTML function. Anything outside of those functions is simply wire frame so the function can be tested, and something shows up on the web page.

How to use

Grab the file and place it on your PHP web server. I’m using docker to run my PHP server and if you clone the whole phptest repo you’ll have my docker-compose file and can just run it from there. If you rather not deal with docker and already have a PHP server ready to go just put phpmailer.php on that server. If you don’t want to deal with GitHub either just wget or curl this URL https://raw.githubusercontent.com/siggib007/phptest/master/phpmailer.php directly into your web directory.

You will also need to have PHPMailer installed on your box. The PHPMailer maintainers recommend you use composer to install it, but I don’t like to use composer as I like to keep dependencies to absolute minimum. I typically have zero dependencies, but occasionally I add one or two max. In these cases I manually install the required files. In this case I download https://github.com/PHPMailer/PHPMailer/archive/master.zip as instructed on https://github.com/PHPMailer/PHPMailer. You are also free to grab the PHPMailer directory from my phptest repo. Whichever route you choose just make sure you have the module on your server and the require statements in the function are adjusted so the script can find it.

Also make sure you are including the two use statement at the top of my test script.

Setup the following environment variables. I recommend you use Doppler for that for maximum security. See my article on docker and doppler for details on how to do that.

  1. EMAILUSER: This the username the script should use when logging into the SNMP server
  2. EMAILPWD: The password to use when logging into the SNMP server
  3. EMAILSERVER: The FQDN of the SNMP server
  4. EMAILPORT: The TCP port number that the SNMP connection should use
  5. USESSL: Whether the SNMP server supports full SSL or TLS connections (True or False)
  6. USESTARTTLS: If the server doesn’t support full connection security, can it switch to a secure connection post connection, known as StartTLS. (True or False)

This should also work if you just setup those appropriate environment variables. If you have another way to fetch these information, just make the appropriate changes in the test script. After you grabbed PHPMailer module and setup those variables you should be able to Load the page and have it send an email. Unless you are using MailTrap (see section, Testing with MailTrap, in article Emailing from python3 for details on MailTrap) or similar service, you won’t actually see any email unless you also change variable on line 130 in the script to be a real email address you can check.

Make sure the SMTP server you are sending through has the proper SPF/DMARC records to be authenticated as authorized to send email for the domain you are using in line 135 in variable $FromEmail. Otherwise the email will be considered spam by pretty much every email service out there. For example if you are sending through your Gmail account, this email address needs to be configured as a send-as email in your configuration. If you are using your work email service you may need to check with your email administrators, but it likely needs to be your work email domain. If you are running your own domains and email server or you are the email administrator, you most likely didn’t read anything beyond SPF/DMARC 😀

To use this in your own PHP do the following

  1. copy SendHTMLAttach function along with the StripHTML function into your function library
  2. Setup the above variables either through Secret Manager such as Doppler, environment variables or however you are used to configure such things.
  3. Then call the SendHTMLAttach function with following arguments in this order, to skip an optional argument and include one later you either pass in an empty string or just put the comma.
    1. Message Body in HTML format, as a simple string. Note: A string doesn’t have to have HTML formatting to be a valid HTML string. However <br> is required at the end of a line you want to break. Normal line breaks are not rendered in HTML, only the text only view.
    2. Name and email that email should come from in the form of “Joe User |joe.user@example.com”
    3. Name and email address to send the email to, in the form of “Joe User |joe.user@example.com”
    4. Email Subject, as a simple string
    5. [Optional] Filename you want the attachment, created from the string in next parameter, to have. The script will not create the attachment if you leave this off. It is up to you to make this filename appropriate for the content. If you generate a HTML attachment but name the file MyFile.txt the recipient will by default, just see the actual HTML, not the rendering as one might expect.
    6. [Optional] Email Attachment in the form of a simple string. This would be the content of the attachment file, appropriately formatted for the intended file format. I assume this would be created by your script but could be read in from a file as well. Only text formats are supported, binary attachments have not been tested.
    7. [Optional] List of custom headers to add to the email. Either supply a single header as a simple string in the format “name: value” or as an array of simple strings in that format. For example “X-Testing: This is my test header”.
      1. See how I do this in my script by looking at how I create $arrname in the starting on line 127.
    8. [Optional] Absolute path to a file on the php server you want to include as an attachment.

Here is an example of how you might call the send function assuming all the above have been assigned to appropriate variables.

$resp = SendHTMLAttach ($strHTMLMsg, $FromEmail, $toEmail, $strSubject, $strFileName, $strAttach, $arrname, $FullPath2File);

If you want to pass only required parameters plus FullPath2File you would do this

$resp = SendHTMLAttach ($strHTMLMsg, $FromEmail, $toEmail, $strSubject,,,, $FullPath2File);

The function will return “Message has been sent” upon success or error message upon failure.

That should cover it, as always feel free to reach out if you have questions or comments.

Picture of command line windows Reading Time: 6 minutes

Introduction

In this article I want to deviate from my normal cybersecurity related posts while still staying technical and focus on the python automation topic of using Slack to send notifications from your python scripts.

There are many useful reasons why you’d want to send slack messages to a specific person or a team during the execution of your automation scripts. Anything from error notifications, condition notifications or even just completion notifications. I find these kinds of notification in my automation scripts extremely useful and figured others might as well. While the Slack API guide is very detail and helpful it can be a bit daunting to those of us that aren’t full fledged developers looking to write a major Slack Bot with tons of functionality. When I set out, I certainly felt that way as I am by now means a professional developer, I just put together some python scripts from time to time to automate something and I was just looking for something super simple. All I wanted was to be able to send a message to a specific person or a channel.

The Function

After some time I figured out a way to do this and wrote a little function to accomplish this. This function is just 40 lines, and you are welcome to use it in your code if you want. I have a script that just tests the function on GitHub at https://github.com/siggib007/Utils/blob/master/SlackNotify.py. Just copy the SendNotification function from that script and use it in your python scripts.

You need three things to call that function:

  1. The message you want to send. In the script I truncate long messages so not to run into message length errors on Slack. Plus I found that messages longer than 1000 char on slack aren’t all that useful. I default this truncation to 199 characters, but you can adjust that. I would recommend staying below 500 characters. This shouldn’t be a logging mechanism, more notification that someone should check the logs.
  2. The channel ID, which identifies who should be getting the message, either a person or a channel. I’ll show you how to find this shortly.
  3. The Authentication token, which authorizes your script into the right slack workspace. I’ll explain this better later.

In my test script this is how I call the function with “More Testing” being the message I want to send.:

print(SendNotification("More testing",strNotifyChannel,strNotifyToken))

BTW you’ll see in the script that I am fetching the channel ID and notification token from an environment variable. I’m actually storing this in a Doppler project which allows me to store this and access it in a very secure manner. Naturally only the access token needs to be stored securely, however I choose to store the notification ID as well for this demo to make it easy to switch test cases. For more details on how this works check out my Secrets Management article.

The Channel ID

OK here is how you find the right channel number to send.

A specific user

Let’s start with how to find the channel user for a specific person. There is more than one way to approach this, and this is just my favorite way and assumes you are already chatting with this person in slack. The channel ID for each user is in users’ profile in the more menu, if you already know how to get there, just do that, otherwise follow along here.

Start by finding the person in your direct messages list and click on their name in the list as if you were going to manually send them a message. Then click on their name in the message.

screenshot of slack

Then click on View Full Profile

screenshot of slack with users profile summary

In the profile side bar, click on the “more …” button.

screenshot of slack with profile sidebar

Click “copy member ID” in the menu that comes up

screenshot of slack with the "More ..." menu in profile sidebar expanded

Now you have the channel ID for this person in your clipboard, paste it someplace safe.

A specific Channel

Now for the ID of a specific channel. Start by finding the channel you want to send messages to in your channel list and click on it as if you were going to manually post something in that channel. Then click on the little down arrow (or chevron) next to the channel name the top of the screen.

Screenshot of slack #general channel

The channel ID is at the bottom of the screen that comes up. There is a little copy icon next to it that will put the channel ID in your clipboard

screenshot of slack #general channel details with channel ID

The Authorization Token

OK now you two thirds of what you need to call the function. The authorization token is the only thing left and this one is a little more complicated.

You start by going to https://api.slack.com/ and click on Your Apps in top right corner

screenshot of slack api web site

Then sign into the slack workspace where you want to send your messages to. If you have multiple workspaces you want to send automated messages to, you’ll need separate auth tokens for each workspace (also the channel ID is workspace specific), so you’ll just repeat this process for each of them. If you are already logged in for whatever reason you will not see this, so just jump to the next step, and create new app.

screenshot of slack api web site focused on the sign in link

Once you are logged in, you should see a “create new app” button.

  • Click Create New App
  • Then click “from scratch”
  • Give the Bot a cool name, I recommend something short that makes it clear what this bot does.
  • Select the workspace this bot will go into. If the workspace you want isn’t in your list, click on the “sign into a different workspace” link
  • Click “Create App”
screenshot of slack api app creation wizard, step 1
screenshot of slack api app creation wizard, step 2

Now on the left under Features, click on “OAuth & Permissions”

screenshot of slack api app configuration menu

Scroll down the page to the Scopes section and click on “Add an OAuth Scope” under Bot Token Scopes

screenshot of slack api app scope screen, step 1

Add “chat:write” scope.

screenshot of slack api app scope screen, step 2
screenshot of slack api app scope screen, step 3

Now scroll back up and click on the “Install to Workspace” and approve the request screen that comes up.

screenshot of slack api app installation screen

Now your authorization token will be shown where the install button once was.

screenshot of slack api app oauth token

Now you have everything you need to send slack messages from your script, but there is one final task left. You need to add the bot to all the channels you want it to be able to send to. While there are at least couple of different approaches I’m just going to illustrate the one I recommend, which involves adding the bot directly into the channel one by one. Start by going back to the screen where you got the Channel ID and click on integrations

screenshot of slack #general channel details with integration tab pointed out

Click on add apps

screenshot of slack #general channel  integration tab with add apps pointed out

Find the name of your new bot and click Add

You should be all set now. Please feel free to reach out if you have any questions.