Markus Tenghamn

Programmer and Entrepreneur

A bot posted a message to Slack

Post updates to Slack with PHP

14th of September, 2016

What is Slack

So if you haven’t heard of Slack yet then you should probably check it out. I use it for work to communicate more easily with colleauges and also organize information better, I even set one up for myself at Slack is free to use with premium features starting at $8 per user.

How to create a Slack bot

You will need to pay for Slack in order to create bots I believe. Bots are referred to as integrations on Slack and are managed in the same way as all of your other integrations. Simply go to your custom integrations page and click on Bots to get started.

Once you get to the next page simply click on “Add Configuration” on the left hand side in order to create your first bot.

Create a Slack Bot

I’m just going to name my bot @myfirstbot, this is the username that will be used to refer to your bot in channels and will be the username that your messages are posted from (with some exceptions as you get into more advanced stuff which we won’t cover in this post).


You will then get to the settings page for your bot that you just created. You can give your bot a name here and upload an icon. I will just go ahead and keep mine the way it is. What we are most interested in here is the API Token which we will be using to authorize our requests as our bot. Please keep in mind that this API Token could be used to read anything that is posted to your channels and even post messages and change settings, keep it safe just like you would with a username and password.


Now the final step, let’s go ahead and invite this bot to one of our channels in the same way that we would add a normal user. You will see that the bots name now shows up when you type /invite.

Invite a Slack bot to a channel

How to post to Slack with PHP

So lets get to the good stuff. How do we make this bot post a message to Slack?

First think we need to do is enter our message and set up our array of post variables that we want to send to Slack.

// The message you would like to send
$message = "Hello this is a test!";
$parameters = array(
    // Simply type your channel name, make sure your bot is invited
    'channel' => 'testing',
    // Good idea to decode
    'text' => html_entity_decode($message),
    'as_user' => 'true'


Channel here is simply the name of the channel you created and invited your bot to. Text is the message you want to send, I try to make sure to always html_entity_decode my message just to make sure its formatted correctly. The as_user variable is an optional parameter and all it says is that we want to post as our bot called @myfirstbot.

Now on to the next part, we will need to enter the Slack URL which is always the same with the exception of the last part which is the method you want to call.

// Use groups.list if you run into channel_not_found
// issues with private channels, make sure your bot is invited

// chat.postMessage is the method
$url = ""."chat.postMessage";
// replace MY-API-TOKEN with the API Token for your bot
$parameters['token'] = "MY-API-TOKEN";


In this case we want to call the chat.postMessage method. I am also adding our API Token which we discussed earlier in this article. Simply replace MY-API-TOKEN with the token that you got when creating your bot.

Finally we will need to actually make the request to the Slack API, for this I have created a method which will use Curl if your installation supports it and fall back to file_get_contents if Curl isn’t available. This should work on most web hosts.

if (function_exists('curl_version')){
    // Use curl if we have it installed
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
    $result = curl_exec($ch);
} else {
    // If we don't have curl we use file_get_contents
    $post_data = http_build_query($parameters);
    $result = file_get_contents($url, false, stream_context_create(array(
        'http' => array(
            'content' => $post_data,
            'method' => 'POST',
            'protocol_version' => 1.1,
            'header' => "Content-type: application/x-www-form-urlencoded\r\n" .
                "Content-length: " . strlen($post_data) . "\r\n" .
                "Connection: close\r\n"
// Echo our result, this is returned as a
// json encoded string. Use json_decode($result, true) to turn it into an array
echo $result;


The if statement here checks if we have curl activated. If we have curl we make a curl request to the Slack API, if we don’t have curl we do the same thing but with file_get_contents instead. Both methods work in pretty much the same way and you should get the same result. The $result variable now holds the response from the Slack API. If it worked you should see something like the following.

{“ok”:true,”channel”:”XXXXXXXXX”,”ts”:”1473880390.000004″,”message”:{“type”:”message”,”user”:”UXXXXXXXX”,”text”:”Hello this is a test!”,”bot_id”:”XXXXXXXXX”,”ts”:”1473880390.000004″}}

If you get a different result like channel_not_found please make sure you have followed all the steps carefully. You may have missed inviting your bot to the Slack channel or another step. I have tried to comment the code in order to make it easier to understand and debug.

A message from your bot should now be in the channel you created earlier, success!

A bot posted a message to Slack

The things you could use this for are endless. I personally use it to keep track of things so that I can get instant notifications. It ranges from everything from when I get an important email to when my server starts getting a bit hot to when a new device has connected to my wifi network. Slack notifications are easy to configure and you are not limited to one way messages. I have made bots that communicate with users and ask questions, store answers and process them on a server. The things you can do with Slack bots are endless, especially now that Slack has added buttons to the messages that bots can post to Slack.

You will find all the source code on GitHub here:

If you are interested in exploring the Slack API and everything it can do you will find all of the documentation for Slack here.


Tracking UPAA numbers from Ebay’s Global Shipping Program

13th of September, 2016

Recently I made a purchase from an Ebay seller in Texas and had the item shipped via Ebay’s Global Shipping Program. This means that the seller will send the item to a location that they receive from Ebay, usually Erlanger, Kentucky. This location is where Ebay handles orders in their Global Shipping Program which will then send your order to your country where it will be handled by whatever local carrier handles shipping in your country. You will most likely receive a tracking number that has the UPAAXXXXXXXXXXXXXXXX format along with perhaps another tracking number. The other number is probably a domestic US carrier like UPS and won’t really be needed unless your order gets lost before reaching the global shipping center. The UPAA tracking number is what we are really interested in here. I tried lots of sites and none seem to be able to give me any information regarding this number. This is because the number is assigned by Ebay and pretty much only used by Ebay.

How to track UPAA numbers

So to figure out where your order is once it has reached your country this is what you need to do. After you login to ebay you need to select “Purchase History” from the “My Ebay” menu in the top right corner.

My Ebay Purchase HistoryOnce you have clicked on that link scroll to your order and look at the shipping information, it should look similar to this.

Ebay Shipping InfoYour UPAA tracking number should be a link that you can click on. This will open a popup that looks like this.

Ebay Global Tracking Popup for UPAA numberThe “# ABC=XXXX” link here should be clickable. When you click this you will be taken to another site which shows tracking information and a new tracking ID which can’t really be found anywhere else it seems. The page looks like the below image.

ebay-4The tracking number displayed above in blue should be a clickable link which takes you to your country’s shipping carrier along with their own tracking information which should make it easier for you to figure out where your package currently is and how long it will take to get there. Much easier than trying to figure out how to use the UPAA number Ebay gives you.

I hope this post was helpful and that both my own shipment and whatever shipment you are waiting for arrives soon!

I do hope that Ebay integrates this better into their own systems in the future, I work a lot with developing APIs and I think it is something that we really need in all places where computers are already used. It is much better than the “hacks” customers create themselves when they get tired of a broken system.

The Best Git Client Is Coming To Windows!

11th of July, 2016

I was recently invited to test out the Tower for Windows beta and it is now public and available to everyone, head over to the sign up page to try it for yourself right now!

Tower has been a great tool for me as a web developer and programmer. As I get more and more serious about the work I do, and as the projects get more complicated, I feel that the need for something like Git becomes really important to keep track of things. This is especially true for things that others work on, I like to be able to easily see what has been changed and I want others to have an easy way to review and critique my code.

Tower for mac was one of the programs I used a lot when I was getting started with git and it helped me learn git in the beginning. At the moment I have to admit that Tower is not used very often as it my favorite PHP IDE has an integrated git client, see my review of the best PHP IDE here. However Tower is really great and it is my go to program when I am not working with PHP or if I need to fix something.

The interface is super simple to use and easy to understand, many services like Github and Gitlab are integrated making it easy to get started with projects. I know I learned things like solving conflicts with the diff viewer in Tower, stashing and unstashig changes has also been super valuable to master. The best part of all of this is that you don’t need git installed, trust me you don’t want to have to manage a git installation when things go wrong.

All of this that I have had on the mac is now on Windows and I have used it to manage some of my projects and it’s great. I am impressed that they are moving forward with such a great product and making it available on Windows. If you missed it, you can find the public sign up page for the beta here.

.xyz domains fail for IDN domains with åäö

Error with åäö .xyz IDN domains for a majority of registrars

19th of June, 2016

So lately I tried registering a few .xyz domains containing the swedish characters åäö over at NameCheap which failed, NameCheap is one of my favorite registrars (See my review of the best and worst registrars here). The fact that my order failed surprised me since I had previously registered swedish domain names with åäö characters without a problem. I would get an error that said “IDN table ‘swe’ is not supported by this server.”. I contacted NameCheap support regarding the problem and they stated that the Swedish language was not supported for .xyz domains.

However I felt that this was wrong as the .xyz website NameCheap refers to mentions languages and scripts, I believe Swedish would fall under Latin. In addition to that, I had already registered Swedish .xyz domains that contained åäö without any issue previously and they would resolve to my server without a problem. So I went ahead and tested an order at which worked without a problem.

IDN table 'swe' is not supported by this server.

You can also check the domain Fö and see that it resolves without an issue. So clearly something was wrong but it seemed hard to get my point across to NameCheap, I went on a bit of a twitter rant but oh well 🙂

I also decided to test registering domains with other registrars that had discounted pricing for .xyz domains at the time.

Godaddy fails to register .xyz domainsI tested with Godaddy (please note that Godaddy has received some vary bad reviews in my previous posts) and they also seem to have the same issue but it does not say exactly why it occured.

Next I headed over to and tried registering a few domains, same problem there as you can see below.

Gandi orders fail for .xyz idn domains with åäö.I also headed over to another registrar called Hover and they also seem to be facing the same issue as you can see in the image below.

idn domain registrations fail for .xyz on hover.comMy orders were refunded so not a problem but I would like to register my domains and take advantage of the discounts offered by registrars currently.

Since this error affects multiple registrars it seems like this issue is related to a problem with the .xyz registry and we are waiting for an answer, I know that multiple registrars have sent support requests and NameCheap has been great in helping me get to the bottom of this issue.

Update June 20th

It’s monday and .xyz finally responded confirming that Swedish domains are supported by .xyz and fall under Latin.

Convert Punycode IDN domains to UTF-8 and back again with PHP

18th of June, 2016

So I am sitting here late at night and I registered a few swedish .xyz domains that contain characters åäö. For example you may have the domain for horse in swedish, hä, this domain is actually written as Now I wanted to create a  temporary catch-all page for these swedish domains until I can build a site for them. What I did was to get the domain name as a variable which I echo in the title and body of the page using the following server variable:


this works ok but for domains with äåö it will output the weird looking punycode which is not really seo or user friendly. To solve this we can use the idn_to_utf8() function in PHP which takes the punicode and converts it to UTF-8 characters which will show the åäö characters. For my site I also wanted to make the first character upper case so I used the ucfirst() function. My page ended up looking like this.

    <title><?php echo ucfirst(idn_to_utf8($_SERVER['HTTP_HOST'])); ?> - Coming soon!</title>
    <h1><?php echo ucfirst(idn_to_utf8($_SERVER['HTTP_HOST'])); ?></h1>

That takes care of that. Now the opposite function of idn_to_utf8() is the idn_to_ascii() function. This will take the åäö characters and convert them to the punycode.

I hope some of you find this useful.

4 Golden Rules To Keep Your WordPress Site Secure

11th of June, 2016

I have worked with WordPress for about 10 years, with my own websites and clients websites. My sites have been hacked in the past. While working at one of Sweden’s largest web hosts I would fix broken and hacked WordPress sites on a daily basis. Today I work as an IT Security Manager where I do everything from keeping our companys WordPress site secure to securing several servers and networks that we have at more than 5 different physical locations. From all of this experience I have learned a lot and this has led me to create a list of 4 golden rules which will keep your WordPress site safe and secure.

1. Update

Not updating WordPress or the themes and plugins installed in WordPress is by far the most common reason why most users get hacked. Personally I keep a todo list that along with a reminder every two weeks to go through all my installations (it can be WordPress, Servers, other websites, etc.) and just check on things and do all the needed updates. In the past I have also used InfiniteWP to keep track of many WordPress installations at the same time, for its basic features it is free to use.

2. Use popular plugins and themes

This is related to the above point about updating. There are lots and lots of themes and plugins out there that are old and that may be unmaintained. A large user base will keep you safer as it is more likely to be supported (check when the last update was made) and there is a greater chance that if a user finds a flaw it will be widely reported. When getting a new plugin or theme I always recommend googling the plugin or theme name like “Woocommerce WordPress” to see if there is anything negative that I should know about before I install it.

3. Only use the plugins or themes that you need

Think of your WordPress installation as you think of your computer. The repository of plugins and themes (along with third party websites) is the internet and whenever you install something you are taking a risk that it could be something malicious. This goes with #2, popular themes and plugins are generally less risky. Also keep in mind that there are malicious users who upload bad plugins and themes on purpose to hack websites or steal data (these usually get reported but there is always a chance with plugins or themes that nobody else has looked at). Another reason why you don’t want a bunch of themes and plugins clogging up your WordPress site is that it gives you more things to update and more ways that things could go wrong, more doorways that an attacker could use to get into your system. Security plugins for WordPress is an example of an extra plugin you don’t need, all these do is make it harder to find login pages and what not but in reality you are most likely taking more of a risk installing this addon as it could have potential vulnerabilities. WordPress is used by companies like Spotify, if you keep it updated there is no need for silly security plugins which are just a waste of time and money.

4. Remove the admin user

A simple way to attack a WordPress site is to brute force by guessing the administrator username and password. Having a username like admin and a password like “strongpass1234” is not really that safe. I highly recommend using a long username that is not admin or administrator, and preferably a username that contains a space. So for my WordPress site I might use the username “Markus Tenghamn” as it is long and then I like to generate a random password which is 15-20 characters long via this password generator website. Most of these bruteforce attacks are automated using the most common usernames, having a uncommon username along with a strong password makes your site extra safe. Keep in mind that I put this as my 4th rule, keeping your WordPress site updated is more important.

Stick to these 4 golden rules and you will have a safe and secure WordPress site. I hope the article was useful and I would love to hear your feedback in the comments section below.

How to automatically post emails to Slack

10th of June, 2016

Slack is an amazing service, it is basically a dumbed down (in a good way) and simplified IRC client which may sound bad but it makes it super efficent and great for work. It is also an easier sell to non-IT coworkers who may laugh at the idea of using an IRC server for work. Anyways, sometimes it can be a great idea to post email updates directly to Slack. I have done this for a server which runs CSF & LFD (our server firewall) which sends out notifications when ips get banned, suspicious files are found or if something is just not right with the server.

Anyways, to begin you will need to install the email app for your Slack team which can be found here This app is part of slack and will basically create an email like which you then can send email to. The email app will work like a bot, so once configured you can set a name and even upload an image for your bot.

Once you have your email you can either change the email in the settings of whatever you are sending from or you can go to your email client, preferably the web based version if you have gmail or outlook or something like that. Here you will want to configure a filter or rule that says if these conditions match then I want to forward this email to Slack. For me the conditions was the email that these emails were being sent from. I decided to forward those emails coming from LFD but also keep a copy in the mailbox just in case.

If you have attachements like images and what not it should also work as long as the files are not more than 25mb.

Now, try sending an email. The email will appear as a snippet usually along with any files you have attached.

Now keep on slacking! Hope you enjoyed the post.

Getting started with Ionic framework for building apps on OSX El Capitan

9th of June, 2016

First thing you need to do if you haven’t already done so is to download and install Node.js. You will find Node.js via their website here: I picked the recommended option as it is most likely more stable but you are free to try either one. Both will probably work with Ionic framework.

Once Node.js is installed you will need to open terminal, cmd + space and then type “terminal” to open it quickly. After this I will be following the getting started guide from the Ionic website which can be found here

So first thing we need to do is install the Cordova and Ionic command line tools, simply type “npm install -g cordova ionic” in the terminal and you should see a spinning line and then a loading bar which means it is loading.

If you run into an error here: You may get an error like “Error: EACCES, permission denied” and then it tells you to try running the command as an administrator. Usually the error is related to moving files or not being able to create symlinks. You could do sudo but I prefer to run this as a regular user. So this error basically means we have a permission issue. To fix the issue start by running “sudo npm update -g”, this will ask for your password, just type it in and it will update node. Then we clear the cache so we start of nice and cleanly using the command “npm cache clean”. Now let’s update our permissions, let’s run “sudo chown -R $USER:$GROUP /usr/local/lib/node_modules/” and also for the symlinks run “sudo chown -R $USER:$GROUP /usr/local/bin”. Then run “npm update -g” to see if things work and finally run “npm install -g cordova ionic” and things should now install without errors.

Now we can create a project, simply cd to the directory where you want your project, im just going to put it in my users folder so I type “cd –“. Then run “ionic start myApp tabs” to start our first project. You may get a promt to install command line tools, if you get this then you should install it. It may also ask if you want an account, you can create one if you want.

Now that your project is created we can cd to your app directory using “cd myApp“. Add the ios platform to ionic using “ionic platform add ios“.

If you get an error: You may get an error like “xcode-select: error: tool ‘xcodebuild’ requires Xcode, but active developer directory ‘/Library/Developer/CommandLineTools’ is a command line tools instance” which basically means you need to install xcode to run the app. Luckily Xcode is completely free to download, simply go here and proceed to download and install: Once this is done you are ready to run “ionic platform add ios” again and follow the next step in the guide.

Now we are ready to run our sample app. Simply type “ionic emulate ios” and the app will launch. You can navigate to the myApp folder in finder to view the files. Since Ionic uses Angular the functions are javascript based which you will find in the .js files. You can actually launch pages in the app by opening the .html files in your browser. This allows you to inspect css elements and make changes quickly with a visual guide before you actually build the app. When you need to make a new project simply open terminal, cd to your projects directory and then run “ionic start myApp2 tabs” where myApp2 is the name of the folder or project and tabs is the base build. You can change out tabs with blank or side menu depending on what type of app you want to create.

I hope this guide has helped you to get started with the Ionic framework!

Upgrade rsyslog on Centos to version 8

8th of June, 2016

So for some reason you would like to upgrade rsyslog to version 8. For me it was some issues with the logging, I wasn’t getting anywhere debugging version 5.8 and almost nothing was writing to /var/log/messages which is not good. So I decided to figure out how to make the upgrade.

First thing you need to do is to ssh to the server or if you have physical access just open a terminal and cd to the repo directory with “cd /etc/yum.repos.d/”.

Now me need to get the latest repository version which can be found here

Version 8 is the latest version while I write this so I simply download the repo using wget. Like so “sudo wget”

Then you can proceed to update rsyslog using “yum install rsyslog”.

Now you are done, you should be running the latest version of rsyslog! This was quick and simple and worked flawlessly for me but I know that it may not work so well for everyone. While searching I had this guide to help me from the rsyslog website which also helps with debugging: It can also be a very good idea to check that what you downloaded was actually what you wanted, the link above explains this part in more detail as well.

As always, be careful when making changes to your system, make a backup and read things 3 times before trying them, something could go wrong very easily if you don’t know what you are doing.

Hope the guide helped, thanks for reading!


Change Memory Limit on OSX running PHP 7

7th of June, 2016

Every now and then when testing local applications you may run into an error that says something like “Allowed memory size of xxxxx bytes exhausted (tried to allocate xxxx bytes)”. Now, sometimes this may be caused by a coding issue such as a loop that gets stuck which is way you may not want to set this limit too high. In my case I felt that I needed to raise this limit as I am working with parsing large excel files which require a lot more than the standard 128M of memory.

First thing you can do is check the memory limit php is currently set to by typing “php -i | grep memory” in the terminal. It will say something like 128M which is 128 megabytes.

Then type “php -i | grep php.ini” in the terminal, this will show you the path to the php.ini file. In my case the path is /usr/local/etc/php/7.0/php.ini. You can then use your favorite editor to change the file, you will probably need to use sudo. I prefer using nano to edit files.

Simply type “sudo nano /usr/local/etc/php/7.0/php.ini” to begin editing the file. You can use ctrl+w to search for memory_limit or 128M in order to get to the right line. I changed the value to 4G which is very high, you could try doubling the value to 256M to see if that is enough to get you going, Once you have changed the value press ctrl+x to close, press y and enter to save the changes.

All we have to do now is restart apache and we should be good to go, type “apachectl restart” in the terminal. Then you can check the memory limit again using “php -i | grep memory”.