Skip to content

Instantly share code, notes, and snippets.

@halilim
Last active May 24, 2017 18:57
Show Gist options
  • Save halilim/db9eea2210f0f2ebddb5a2963a378822 to your computer and use it in GitHub Desktop.
Save halilim/db9eea2210f0f2ebddb5a2963a378822 to your computer and use it in GitHub Desktop.
Simple AWS Lambda script to notify by SNS if a domain is expiring within 3 days
// Simple AWS Lambda function to notify if the domain halil.im is expiring within 3 days.
// Tested on Node.js 6.10 runtime.
// * Create an SNS topic and an SNS subscription with the email you want to be notified
// * Create the function with a trigger of "CloudWatch Events - Schedule" with rate: 1 day
// * Provide the SNS topic ARN to the function as an environment variable
// * Create and attach a policy to the role of this function with sns:Publish on the SNS topic ARN
// (logs:CreateLogGroup, logs:CreateLogStream & logs:PutLogEvents on a logs ARN should already be there)
/* eslint-env node,es6 */
/* eslint no-console: "off" */
'use strict';
const WHOIS_HOST = 'whois.nic.im';
const WHOIS_PORT = 43;
const DOMAIN = 'halil.im';
const SNS_TOPIC_ARN = process.env.sns_topic_arn;
const net = require('net');
const AWS = require('aws-sdk');
const SNS = new AWS.SNS({ apiVersion: '2010-03-31' });
function SNSpublish(subject, message, errorPrefix) {
SNS.publish(
{
Subject: subject,
Message: message,
TopicArn: SNS_TOPIC_ARN,
},
(err) => {
if (errorPrefix && err) {
console.error(`${errorPrefix}: ${err}`);
}
}
);
}
exports.handler = () => {
let socket = new net.Socket();
socket.setTimeout(10000);
socket.connect(WHOIS_PORT, WHOIS_HOST, () => {
socket.write(`${DOMAIN}\r\n`);
});
let received = '';
socket.on('data', (chunk) => {
received += chunk;
});
socket.on('timeout', () => {
socket.destroy();
console.error('The socket timed out');
});
socket.on ('error', (err) => {
console.error(`Socket error: ${err}`);
});
socket.on('close', () => {
if (!received) {
console.error('No data received');
SNSpublish('No data received', `No data received querying the domain ${DOMAIN}`);
return;
}
// .im specific
let matched = received.match(/Expiry Date: 0?(\d+)\/0?(\d+)\/(\d+)/mi);
if (!matched) {
const errTitle = "Couldn't detect the expiry date";
const errMsg = `${errTitle}, the format might have changed. Received data:\n${received}`;
console.error(errMsg);
SNSpublish(errTitle, errMsg);
return;
}
let [, day, month, year] = matched;
let expiryDate = new Date(year, month - 1, day);
let daysRemaining = Math.round((expiryDate.getTime() - Date.now()) / 86400000);
if (daysRemaining <= 3) {
SNSpublish(
`${DOMAIN} is expiring in ${daysRemaining} days`,
`The domain ${DOMAIN} is expiring in ${daysRemaining} days`,
"Couldn't publish expiry notification"
);
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment