Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions AutomaticClockOuts/clock_out.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const _ = require('lodash');
const CosmosClient = require("@azure/cosmos").CosmosClient;
const config = require("./config");
const TimeEntry = require('./time_entry');
const axios = require('axios');
const MsalClient = require('./msal_client')
const TimeEntryDao = require('./time_entry_dao')
const MsalClient = require('./msal_client');
const TimeEntryDao = require('./time_entry_dao');
const SlackClient = require('./slack_client');

const doClockOut = async (context) => {
context.log(`I am going to check how many entries were not clocked out ${new Date()}`);
Expand All @@ -16,21 +18,27 @@ const doClockOut = async (context) => {

const response = await MsalClient.findUsersInMS();
const users = response.data.value;
const slackUsers = await SlackClient.findUsersInSlack();

const {resources: entries} = await timeEntryDao.getEntriesWithNoEndDate();
context.log(`Checking for time-entries that need to be clocked out`);

let totalClockOutsExecuted = 0;
const usersWithClockOut = []
const usersWithClockOut = [];
await Promise.all(entries.map(async (timeEntryAsJson) => {
const timeEntry = new TimeEntry(timeEntryAsJson)
if (timeEntry.needsToBeClockedOut()) {
usersWithClockOut.push(findUser(users, timeEntry.timeEntry.owner_id));
const user_email = findUserEmail(users, timeEntry.timeEntry.owner_id);
const userId = findSlackUserId(slackUsers,user_email);
if(userId){
usersWithClockOut.push("<@"+userId+">");
}
timeEntryAsJson.end_date = timeEntry.getTimeToClockOut()
await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson)
totalClockOutsExecuted++
}
}));
if (totalClockOutsExecuted > 0) {
if (usersWithClockOut.length) {
axios.post(slackWebHook,
{
"text": `OMG, you have been working more than 12 hours in a row. \nPlease take a break and visit https://timetracker.ioet.com/ to set the right end time for your entries, we just did a clock out for you :wink: \n- ${usersWithClockOut.join('\n- ')}`
Expand All @@ -46,9 +54,14 @@ const doClockOut = async (context) => {
context.log(`I just clocked out ${totalClockOutsExecuted} entries, thanks are not needed...`);
}

const findUser = (users, id) => {
const findUserEmail = (users, id) => {
const user = users.find(user => user.objectId === id)
return user.displayName
return _.first(user.otherMails)
}

const findSlackUserId = (users,email)=>{
const user = users.find(user => user.email === email);
return user? user.id:null
}

module.exports = {doClockOut};
3 changes: 2 additions & 1 deletion AutomaticClockOuts/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const config = {
clientId: process.env["CLIENT_ID"],
authority: process.env["AUTHORITY"],
clientSecret: process.env["CLIENT_SECRET"],
slackWebHook: process.env["SLACK_WEBHOOK"]
slackWebHook: process.env["SLACK_WEBHOOK_NOTIFY"],
slackApiToken: process.env["SLACK_TOKEN_NOTIFY"],
};

module.exports = config;
140 changes: 138 additions & 2 deletions AutomaticClockOuts/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions AutomaticClockOuts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"dependencies": {
"@azure/cosmos": "3.5.2",
"@azure/msal-node": "^1.0.0-alpha.5",
"@slack/web-api": "^6.0.0",
"axios": "^0.20.0",
"dotenv": "^8.2.0",
"moment": "^2.27.0",
Expand Down
3 changes: 2 additions & 1 deletion AutomaticClockOuts/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ KEY='XXX'
CLIENT_ID='XXX'
AUTHORITY='XXX'
CLIENT_SECRET='XXX'
SLACK_WEBHOOK='XXX'
SLACK_WEBHOOK_NOTIFY='XXX'
SLACK_TOKEN_NOTIFY='XXX'
```
Check the pinned message in our slack channel to get these values
18 changes: 18 additions & 0 deletions AutomaticClockOuts/slack_client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { WebClient, LogLevel } = require("@slack/web-api");
const { slackApiToken } = require("./config");

const client = new WebClient(slackApiToken,{logLevel: LogLevel.DEBUG});

const findUsersInSlack = async () => {
const response = await client.users.list();
let usersIdAndEmails = [];
if (response.ok) {
slackUsers = response.members;
usersIdAndEmails = slackUsers
.filter((user) => user.profile.hasOwnProperty("email") && !user.deleted)
.map((user) => ({ id: user.id, email: user.profile.email }));
}
return usersIdAndEmails;
};

module.exports = { findUsersInSlack };
Binary file modified nodejs-functions/.serverless/nodejs-functions.zip
Binary file not shown.
27 changes: 20 additions & 7 deletions nodejs-functions/src/handlers/automatic-clock-outs/clock_out.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const _ = require('lodash');
const CosmosClient = require("@azure/cosmos").CosmosClient;
const config = require("./config");
const TimeEntry = require('./time_entry');
const axios = require('axios');
const MsalClient = require('./msal_client')
const TimeEntryDao = require('./time_entry_dao')
const MsalClient = require('./msal_client');
const TimeEntryDao = require('./time_entry_dao');
const SlackClient = require('./slack_client');

const doClockOut = async (context) => {
context.log(`I am going to check how many entries were not clocked out ${new Date()}`);
Expand All @@ -16,21 +18,27 @@ const doClockOut = async (context) => {

const response = await MsalClient.findUsersInMS();
const users = response.data.value;
const slackUsers = await SlackClient.findUsersInSlack();

const {resources: entries} = await timeEntryDao.getEntriesWithNoEndDate();
context.log(`Checking for time-entries that need to be clocked out`);

let totalClockOutsExecuted = 0;
const usersWithClockOut = []
const usersWithClockOut = [];
await Promise.all(entries.map(async (timeEntryAsJson) => {
const timeEntry = new TimeEntry(timeEntryAsJson)
if (timeEntry.needsToBeClockedOut()) {
usersWithClockOut.push(findUser(users, timeEntry.timeEntry.owner_id));
const user_email = findUserEmail(users, timeEntry.timeEntry.owner_id);
const userId = findSlackUserId(slackUsers,user_email);
if(userId){
usersWithClockOut.push("<@"+userId+">");
}
timeEntryAsJson.end_date = timeEntry.getTimeToClockOut()
await container.item(timeEntryAsJson.id, timeEntryAsJson.tenant_id).replace(timeEntryAsJson)
totalClockOutsExecuted++
}
}));
if (totalClockOutsExecuted > 0) {
if (usersWithClockOut.length) {
axios.post(slackWebHook,
{
"text": `OMG, you have been working more than 12 hours in a row. \nPlease take a break and visit https://timetracker.ioet.com/ to set the right end time for your entries, we just did a clock out for you :wink: \n- ${usersWithClockOut.join('\n- ')}`
Expand All @@ -46,9 +54,14 @@ const doClockOut = async (context) => {
context.log(`I just clocked out ${totalClockOutsExecuted} entries, thanks are not needed...`);
}

const findUser = (users, id) => {
const findUserEmail = (users, id) => {
const user = users.find(user => user.objectId === id)
return user.displayName
return _.first(user.otherMails)
}

const findSlackUserId = (users,email)=>{
const user = users.find(user => user.email === email);
return user? user.id:null
}

module.exports = {doClockOut};
Loading