{"id":15098,"date":"2021-06-14T03:35:50","date_gmt":"2021-06-14T07:35:50","guid":{"rendered":"https:\/\/qxf2.com\/blog\/?p=15098"},"modified":"2021-06-24T08:08:53","modified_gmt":"2021-06-24T12:08:53","slug":"work-anniversary-image-skype-bot-using-aws-lambda","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/work-anniversary-image-skype-bot-using-aws-lambda\/","title":{"rendered":"Work Anniversary Image &#8211; Skype Bot using AWS Lambda"},"content":{"rendered":"<p>At <a href=\"https:\/\/qxf2.com\/\">Qxf2 services<\/a>, we get to pick and work on any problem area (eg: Onboarding, Training, etc.) based on our interest. The one I take care of is &#8216;Employee Engagement. As a part of this initiative, I started congratulating employees on their work anniversary in the form of a Work Anniversary Image.<\/p>\n<hr>\n<h3>Why Work Anniversary Image Skype Bot using AWS Lambda?<\/h3>\n<p>Prior to the development of the Work Anniversary Image Skype Bot, the entire process was manual right from finding out which employee has a Work Anniversary, designing Work Anniversary Image and finally posting it on skype. This approach started to consume a lot of my work time as Qxf2 started to grow bigger. Therefore, I felt the need to automate the process in the form of a Work Anniversary Image Skype Bot. I thought of using the same AWS Lambda tech which we found useful to automate a couple of our internal tasks, one of them being the <a href=\"https:\/\/qxf2.com\/blog\/holiday-reminder-skype-bot\/\">Holiday Reminder blog<\/a>.<\/p>\n<hr>\n<h3>How I solved the problem?<\/h3>\n<h5> Breaking down the problem into mini problems<\/h5>\n<p>I began breaking down my problem into 4 sub problems and found respective solutions for each which were :-<\/p>\n<h6>1. Maintaining and polling employees data to look for upcoming work anniversary<\/h6>\n<p>Firstly, the problem was maintaining and polling employee details to find out which employee has a work anniversary. However, a major part of it was already solved by my colleague <a href=\"https:\/\/qxf2.com\/employees\/arun\">Arunkumar<\/a> by building an employee web service to aid in the development of our internal applications which would return employees data at any given point in time.<\/p>\n<h6>2. Get Work Anniversary Images designed<\/h6>\n<p>Secondly, designing work anniversary images on the fly along with specific text overlapped on top of it had to be tackled. For this, I found an image processing python package called <a href=\"https:\/\/pypi.org\/project\/Pillow\/\">Pillow<\/a> to be useful.<\/p>\n<h6>3. Posting Image on the skype channel on the day of Work Anniversary<\/h6>\n<p>Thirdly, and most importantly the major hurdle I had to overcome was posting these images on the Skype channel. We had an existing <a href=\"https:\/\/qxf2.com\/blog\/skype-sender-python-web-service\/\">skype sender web service designed using Skypy<\/a> but it could only send the text messages. As a result, I skimmed through Skypy documentation to check if it can offer a capability to send images as well. I found out an API method documented <a href=\"https:\/\/skpy.t.allofti.me\/reference\/api.html?highlight=send#skpy.chat.SkypeChat.sendFile\">sendFile<\/a>. Accordingly we updated our skype sender web service with the capability to send images to skype.<\/p>\n<h6>4. Base template design &#038; work anniversary quotes<\/h6>\n<p>After that, I was left with two one-time tasks of getting a work anniversary base template image designed in coordination with our illustrator <a href=\"https:\/\/in.linkedin.com\/in\/edward-alan-68286868\/\">Edward<\/a> and creating a list of work anniversary quotes. <\/p>\n<p>When all the pieces were integrated, the entire flow looked like<a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/03\/Work-Anniversary-Image.png\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/03\/Work-Anniversary-Image-300x182.png\" alt=\"Work Anniversary image flow\" width=\"400\" height=\"300\" class=\"aligncenter size-medium wp-image-15148\" \/><\/a><\/p>\n<h5>Code Implementation<\/h5>\n<p>Work Anniversary Image Creation lambda function is subdivided into 4 major methods:<br \/>\n1. Fetching employees data<br \/>\n2. Calculating Work Anniversary<br \/>\n3. Generating Work Anniversary Image<br \/>\n4. Sending Image to Skype Channel<\/p>\n<h6>1. Fetching employees data from our internal employees service<\/h6>\n<pre lang=\"python\">\r\ndef get_all_employees():\r\n    \"Query allEmployees\"\r\n    query = \"\"\"query\r\n    findAllEmployees{\r\n        allEmployees{\r\n            edges{\r\n                node{\r\n                    email\r\n                    firstname\r\n                    lastname\r\n                    dateJoined\r\n                    isActive\r\n                }\r\n            }\r\n        }\r\n    }\"\"\"\r\n    access_token = authenticate()\r\n    headers = {'Authorization': f'Bearer {access_token}'}\r\n    response = requests.get(url = BASE_URL, json = {'query': query}, headers =\\\r\n        headers)\r\n    all_employees = response.json().get('data', {}).get('allEmployees', {}).get('edges', [])\r\n    return all_employees\r\n<\/pre>\n<h6>2. Calculating Work Anniversary <\/h6>\n<p> &#8211; Employee data is looped through to check if a given employee has a work anniversary. After that, an anniversary quote is fetched from predefined list saved in work_anniversary_quotes.txt file.<\/p>\n<pre lang=\"python\">\r\ndef calculate_work_anniversary(emp_joined_date, current_date, emp_name):\r\n    \"Calculate the difference\"\r\n    msg,quote_string = None,None\r\n    if (emp_joined_date.month == current_date.month and emp_joined_date.day == current_date.day):\r\n        difference_in_years = inflect_obj.ordinal(relativedelta(current_date, emp_joined_date).years)\r\n        msg = f'Happy {difference_in_years} work anniversary {emp_name}'\r\n        with open('anniversary_quotes.txt',encoding=\"utf8\") as json_file:\r\n            data = json.load(json_file)\r\n        \r\n        if emp_name in data.keys() :\r\n            if len(data[emp_name]) >= 1:\r\n                quote_string = random.choice(data[emp_name])\r\n            else:\r\n                quote_string = get_default_quotes(data,difference_in_years)\r\n        else:\r\n            quote_string = get_default_quotes(data,difference_in_years)    \r\n    final_quote_string = '\\n'.join(textwrap.wrap(quote_string, 70, break_long_words=False,subsequent_indent='\\n')) if quote_string is not None else ''\r\n    return msg,final_quote_string\r\n<\/pre>\n<h6>3. Generating Work Anniversary Image<\/h6>\n<p> &#8211; Employees name , anniversary quote is superimposed on a base Work Anniversary template image and saved to \/tmp\/ location with employees name prefixed to it. This involved use of Pillow and textwrap python packages for image processing and text formatting respectively.<\/p>\n<pre lang=\"python\">\r\ndef add_text_to_image(message,emp_name,quote_string):\r\n    image = Image.open('Work_anniversary_template.png')\r\n    draw = ImageDraw.Draw(image)\r\n    font1 = ImageFont.truetype('Casanova_Font_Free.ttf', size=130)\r\n    font2 = ImageFont.truetype('Casanova_Font_Free.ttf', size=95)\r\n\r\n    # starting position of the message\r\n    (x, y) = (650, 500)\r\n    color = 'rgb(128, 0, 128)' # purple color\r\n    draw.text((x, y), message, fill=color, font=font1)\r\n\r\n    (x, y) = (400, 700)\r\n    color = 'rgb(255, 69, 0)' # orange color\r\n    draw.text((x, y), quote_string, fill=color, font=font2)\r\n\r\n    filepath = '\/tmp\/' +emp_name+ '_greeting_card.png'\r\n    image.save(filepath,quality=95)\r\n    return filepath\r\n<\/pre>\n<p>Generated Work Anniversary Image looks like this <a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/03\/work_anniversary_rohan_dudam-1-1.png\" data-rel=\"lightbox-image-1\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/03\/work_anniversary_rohan_dudam-1-1-300x213.png\" alt=\"Work Anniversary Image\" width=\"300\" height=\"213\" class=\"aligncenter size-medium wp-image-15147\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/03\/work_anniversary_rohan_dudam-1-1-300x213.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/03\/work_anniversary_rohan_dudam-1-1-1024x727.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/03\/work_anniversary_rohan_dudam-1-1-768x546.png 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/03\/work_anniversary_rohan_dudam-1-1-1536x1091.png 1536w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/03\/work_anniversary_rohan_dudam-1-1-2048x1455.png 2048w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h6>4. Sending Image to Skype<\/h6>\n<p> &#8211; Generated Work Anniversary Image from step 3 is then sent to Skype channel via skype image sender web service hosted on EC2 instance by our Qxf2Bot skype user. Post sending the image to skype channel, image is deleted from<em> &#8216;\/tmp&#8217; <\/em>location.<\/p>\n<pre lang=\"python\">\r\ndef send_image(img, img_name, channel_id = credentials.CHANNEL_ID):\r\n    data = {'API_KEY' : credentials.API_KEY,\r\n    'img_name' : img_name,\r\n    'channel' : channel_id}\r\n    files = [\r\n        ('document', (img_name, open(img, 'rb'), 'application\/octet')),\r\n        ('data', ('data', json.dumps(data), 'application\/json')),\r\n        ]\r\n    response = requests.post(SKYPE_URL, files = files)\r\n    time.sleep(2)\r\n    return response.status_code\r\n<\/pre>\n<p>You can view the complete code on <a href=\"https:\/\/github.com\/qxf2\/qxf2-lambdas\/tree\/master\/work-anniversary\">Github<\/a>.<\/p>\n<hr>\n<h3>Triggering the event<\/h3>\n<p>Work Anniversary Image lambda function gets triggered everyday via a Cloudwatch event which results in posting the image on Skype channel by our Qxf2 bot skype user<a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/04\/Qxf2_bot_wrok_anniversary.png\" data-rel=\"lightbox-image-2\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/04\/Qxf2_bot_wrok_anniversary-300x204.png\" alt=\"Qxf2 bot work anniversary image\" width=\"300\" height=\"204\" class=\"aligncenter size-medium wp-image-15158\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/04\/Qxf2_bot_wrok_anniversary-300x204.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2021\/04\/Qxf2_bot_wrok_anniversary.png 425w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Hope you liked this blog post !! If you have any questions then please leave your comments below.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>At Qxf2 services, we get to pick and work on any problem area (eg: Onboarding, Training, etc.) based on our interest. The one I take care of is &#8216;Employee Engagement. As a part of this initiative, I started congratulating employees on their work anniversary in the form of a Work Anniversary Image. Why Work Anniversary Image Skype Bot using AWS [&hellip;]<\/p>\n","protected":false},"author":17,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[282,18],"tags":[],"class_list":["post-15098","post","type-post","status-publish","format-standard","hentry","category-aws-lambda","category-python"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/15098","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/17"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=15098"}],"version-history":[{"count":22,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/15098\/revisions"}],"predecessor-version":[{"id":15336,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/15098\/revisions\/15336"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=15098"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=15098"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=15098"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}