Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
AppMonitorSubscriber
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nongyingchen
AppMonitorSubscriber
Commits
58fb01b0
Commit
58fb01b0
authored
Jun 26, 2019
by
trace
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[feature] 邮件通知外部人员下线情况, 贷超只有在下线才通知贷超组
parent
eae22bf9
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
106 additions
and
75 deletions
+106
-75
play.js
+106
-75
No files found.
play.js
View file @
58fb01b0
let
version
=
'1.
0
'
let
version
=
'1.
1
'
let
release
=
`<div><br/>
let
release
=
`<div><br/>
<br/>1. <br/>
<br/>1. <br/>
加入对贷超 MGT 的支持. 支持点击"<贷超名MGT>"打开贷超对应管理系统, 点击包名 ID 打开 GooglePlay<br/>
加入邮件通知外部人员功能<br/>
配置文件添加新字段, 用于指名哪个客户, 以及其通知邮件(多个)<br/>
"outsideNotifier" {<br/>
"2060": { "emails": ["developer@xxxxx.com", "xxxxxx"] },<br/>
"2001": { "emails": ["developer@xxxxx.com", "xxxxx"] },<br/>
}<br/>
具体格式可以查看 config 文件中 "outsideNotifier" 字段.<br/>
添加新监控 APP 时只要像原来一样保持 "客户ID空格XXXXX" 的格式即可, 如: "2060 XXXXXX"<br/>
<br/>2. <br/>
<br/>2. <br/>
在线列表上下线颜色区分. 上线: 绿色, 下线: 红色.<br/>
贷超通知更改, 贷超有产品下架才通知贷超人员
<br/>other:<br/>
添加单独贷超 email 变量: "daichaoNotifyEmail": []
当监控中有上下线变化才会发送邮件, 并且会带上当前在线下线列表<br/>
上下线通知邮件中第一行, "《》" 中的是 VTPM 本次监控情况涉及 APP 数量, "【】" 中是本次监控通知中贷超 APP 涉及数量<br/>
<div/>
<div/>
<br/>
<br/>
<br/>
<br/>
...
@@ -17,6 +23,9 @@ let release = `<div><br/>
...
@@ -17,6 +23,9 @@ let release = `<div><br/>
var
gplay
=
require
(
'google-play-scraper'
)
var
gplay
=
require
(
'google-play-scraper'
)
var
nodemailer
=
require
(
'nodemailer'
)
var
nodemailer
=
require
(
'nodemailer'
)
let
developer
=
[
'yingchen.nong@starwin.com'
]
let
notifyEmail
=
developer
// 工具
// 工具
var
fs
=
require
(
'fs'
)
var
fs
=
require
(
'fs'
)
var
username
=
require
(
'os'
).
userInfo
().
username
var
username
=
require
(
'os'
).
userInfo
().
username
...
@@ -52,6 +61,10 @@ let aliveInterval = isTest() && 0.1 || 3 // 发送邮件间隔时间
...
@@ -52,6 +61,10 @@ let aliveInterval = isTest() && 0.1 || 3 // 发送邮件间隔时间
let
start
=
true
// 是否开始爬取监控
let
start
=
true
// 是否开始爬取监控
let
dailyOnlineStartHours
=
7
let
dailyOnlineStartHours
=
7
let
dailyOnlineEndHours
=
9
let
dailyOnlineEndHours
=
9
let
daichaoNotifyEmail
=
[]
// 外部通知客户
let
outsideNotifier
=
{}
let
crabName
=
`东南亚现金贷App监控
${
isTest
()
&&
'(Test)'
||
''
}
`
let
crabName
=
`东南亚现金贷App监控
${
isTest
()
&&
'(Test)'
||
''
}
`
let
monitorRegion
=
{
'vn'
:
'越南'
,
'ph'
:
'菲律宾'
,
'id'
:
'印尼'
}
let
monitorRegion
=
{
'vn'
:
'越南'
,
'ph'
:
'菲律宾'
,
'id'
:
'印尼'
}
...
@@ -60,8 +73,6 @@ let statusFile = `${process.cwd()}/status.json`
...
@@ -60,8 +73,6 @@ let statusFile = `${process.cwd()}/status.json`
let
monitorApps
=
`
${
process
.
cwd
()}
/google-play-monitor-apps.json`
let
monitorApps
=
`
${
process
.
cwd
()}
/google-play-monitor-apps.json`
let
base_gp_url
=
'https://play.google.com/store/apps/details?id='
let
base_gp_url
=
'https://play.google.com/store/apps/details?id='
let
developer
=
[
'yingchen.nong@starwin.com'
]
let
notifyEmail
=
developer
let
daichaoApps
=
[]
let
daichaoApps
=
[]
let
daichaoAppInfoes
=
{}
let
daichaoAppInfoes
=
{}
...
@@ -164,6 +175,7 @@ if (isTest()) {
...
@@ -164,6 +175,7 @@ if (isTest()) {
sendEmail
(
`开始监控-----------------------`
)
sendEmail
(
`开始监控-----------------------`
)
// mark - 监控主流程
async
function
startMonitor
()
{
async
function
startMonitor
()
{
log
(
'开始监控'
)
log
(
'开始监控'
)
while
(
start
)
{
while
(
start
)
{
...
@@ -171,7 +183,7 @@ async function startMonitor() {
...
@@ -171,7 +183,7 @@ async function startMonitor() {
await
getConfig
()
await
getConfig
()
.
then
(()
=>
{
// 部署通知, 更新说明
.
then
(()
=>
{
// 部署通知, 更新说明
if
(
newDeploy
)
{
if
(
newDeploy
)
{
sendEmail
(
`<div>爬虫部署版本:
${
version
}
</div>更新说明:
${
release
}
`
)
sendEmail
(
`<div>爬虫部署版本:
${
version
}
</div>更新说明:
${
release
}
`
,
[...
notifyEmail
,
...
daichaoNotifyEmail
]
)
newDeploy
=
false
newDeploy
=
false
}
}
})
})
...
@@ -186,6 +198,7 @@ async function startMonitor() {
...
@@ -186,6 +198,7 @@ async function startMonitor() {
.
then
(
allN
=>
monitorIfOnline
(
allN
))
.
then
(
allN
=>
monitorIfOnline
(
allN
))
.
then
(
genMail
)
.
then
(
genMail
)
.
then
(
sendEmail
)
.
then
(
sendEmail
)
.
then
(
notifyOutside
)
.
then
(()
=>
{
.
then
(()
=>
{
// 每日在线列表报告
// 每日在线列表报告
if
(
!
isInTimeInRangeToday
(
dailyOnlineStartHours
,
dailyOnlineEndHours
))
{
if
(
!
isInTimeInRangeToday
(
dailyOnlineStartHours
,
dailyOnlineEndHours
))
{
...
@@ -197,6 +210,10 @@ async function startMonitor() {
...
@@ -197,6 +210,10 @@ async function startMonitor() {
sendEmail
(
content
)
sendEmail
(
content
)
})
})
.
then
(()
=>
{
.
then
(()
=>
{
status
[
'lastLoopDate'
]
=
Date
()
})
.
then
(
clearLocalVariable
)
.
then
(()
=>
{
log
(
'成功'
)
log
(
'成功'
)
// 将status 写入到文件
// 将status 写入到文件
fs
.
writeFileSync
(
statusFile
,
JSON
.
stringify
(
status
))
fs
.
writeFileSync
(
statusFile
,
JSON
.
stringify
(
status
))
...
@@ -215,14 +232,7 @@ async function startMonitor() {
...
@@ -215,14 +232,7 @@ async function startMonitor() {
}
}
// 出错了需要重新抓, 需要清空之前缓存的状态
// 出错了需要重新抓, 需要清空之前缓存的状态
newOffline
=
[]
clearLocalVariable
()
newOnline
=
[]
permissionChange
=
{}
failedApps
=
[]
errorLog
=
[]
newTopMonitorNames
=
{}
hitDaichao
=
0
hitOurs
=
0
})
})
await
sleepForInterVal
(
lastIntervalTime
)
await
sleepForInterVal
(
lastIntervalTime
)
...
@@ -246,8 +256,6 @@ function generateDailyOnlineReport() {
...
@@ -246,8 +256,6 @@ function generateDailyOnlineReport() {
async
function
getDaichao
()
{
async
function
getDaichao
()
{
let
allRegionDaichaoApps
=
[]
let
allRegionDaichaoApps
=
[]
for
(
region
in
daichaoRegion
)
{
for
(
region
in
daichaoRegion
)
{
// for (index in Object.keys(daichaoRegion)) {
// let region = daichaoRegion[index]
daichaoApiUrl
=
region
+
daichao
daichaoApiUrl
=
region
+
daichao
log
(
` 贷超 url:
${
daichaoApiUrl
}
`
)
log
(
` 贷超 url:
${
daichaoApiUrl
}
`
)
await
getPromiss
(
daichaoApiUrl
)
await
getPromiss
(
daichaoApiUrl
)
...
@@ -289,42 +297,6 @@ async function getDaichao() {
...
@@ -289,42 +297,6 @@ async function getDaichao() {
log
(
`目前总共贷超数据:
${
daichaoApps
.
length
}
`
)
log
(
`目前总共贷超数据:
${
daichaoApps
.
length
}
`
)
}
}
// async function getDaichao(url) {
// await getPromiss(url)
// .then(val => {
// if (isTest()) {
// daichaoApps = []
// return
// }
// try {
// daichaoData = JSON.parse(val && val.body && val.body || "{}").data
// } catch (err) {
// errMsg = `贷超数据解析出错: ${err}`
// errorLog.push(errMsg)
// return
// }
// daichaoApps = daichaoData && daichaoData.map(app => app.packageName) || []
// daichaoAppInfoes = daichaoData && daichaoData.map(app => {
// let dcApp = {}
// dcApp[app.packageName] = {
// name: app.name,
// appId: app.id
// }
// return dcApp
// })
// log(`代超数据: ${daichaoApps.length} 个`)
// monitorNames["daichao"] = daichaoApps
// if (daichaoApps.length == 0) {
// log('代超数据为空')
// }
// })
// .catch(err => {
// errorLog.push(`贷超获取失败:${err.toString()}`)
// return
// })
// }
async
function
getConfig
()
{
async
function
getConfig
()
{
await
getPromiss
(
subApi
).
then
(
val
=>
{
await
getPromiss
(
subApi
).
then
(
val
=>
{
log
(
'------------ get congfig from gitlab -----------'
)
log
(
'------------ get congfig from gitlab -----------'
)
...
@@ -338,9 +310,11 @@ async function getConfig() {
...
@@ -338,9 +310,11 @@ async function getConfig() {
}
}
ourApps
=
dataes
.
ourApps
||
{}
ourApps
=
dataes
.
ourApps
||
{}
ourApps
=
{
...
ourApps
,
"com.globe.gcash.androida"
:
"2060 测试我的"
,
"com.globe.gcash.androids"
:
"2060 测试我的2"
}
ourAppIds
=
Object
.
keys
(
ourApps
).
slice
(
0
,
1
)
ourAppIds
=
Object
.
keys
(
ourApps
).
slice
(
0
,
1
)
ourAppIds
=
[...
ourAppIds
,
"com.globe.gcash.androida"
,
"com.globe.gcash.androids"
]
if
(
ourAppIds
.
length
==
0
)
{
if
(
ourAppIds
.
length
==
0
)
{
ourApps
=
{
"com.globe.gcash.android
"
:
"测试我的
"
}
ourApps
=
{
"com.globe.gcash.android
a"
:
"2060 测试我的"
,
"com.globe.gcash.androids"
:
"2060 测试我的2
"
}
ourAppIds
=
[
"com.globe.gcash.android"
]
ourAppIds
=
[
"com.globe.gcash.android"
]
}
}
monitorNames
[
"ourApps"
]
=
ourAppIds
monitorNames
[
"ourApps"
]
=
ourAppIds
...
@@ -362,6 +336,7 @@ async function getConfig() {
...
@@ -362,6 +336,7 @@ async function getConfig() {
}
}
let
config
=
dataes
.
config
let
config
=
dataes
.
config
let
subscriber
=
dataes
.
subscriber
let
subscriber
=
dataes
.
subscriber
daichaoNotifyEmail
=
dataes
.
daichaoNotifyEmail
||
daichaoNotifyEmail
ourApps
=
dataes
.
ourApps
||
{}
ourApps
=
dataes
.
ourApps
||
{}
ourAppIds
=
Object
.
keys
(
ourApps
)
ourAppIds
=
Object
.
keys
(
ourApps
)
monitorNames
[
"ourApps"
]
=
ourAppIds
monitorNames
[
"ourApps"
]
=
ourAppIds
...
@@ -398,6 +373,7 @@ async function getConfig() {
...
@@ -398,6 +373,7 @@ async function getConfig() {
start
=
config
.
start
||
start
start
=
config
.
start
||
start
dailyOnlineStartHours
=
config
.
dailyOnlineStartHours
||
dailyOnlineStartHours
dailyOnlineStartHours
=
config
.
dailyOnlineStartHours
||
dailyOnlineStartHours
dailyOnlineEndHours
=
config
.
dailyOnlineEndHours
||
dailyOnlineEndHours
dailyOnlineEndHours
=
config
.
dailyOnlineEndHours
||
dailyOnlineEndHours
outsideNotifier
=
config
.
outsideNotifier
||
outsideNotifier
log
(
JSON
.
stringify
(
config
))
log
(
JSON
.
stringify
(
config
))
log
(
JSON
.
stringify
(
notifyEmail
))
log
(
JSON
.
stringify
(
notifyEmail
))
}
}
...
@@ -559,7 +535,7 @@ function genMail() {
...
@@ -559,7 +535,7 @@ function genMail() {
let
lastLoopDate
=
status
[
'lastLoopDate'
]
&&
new
Date
(
status
[
'lastLoopDate'
])
||
new
Date
()
let
lastLoopDate
=
status
[
'lastLoopDate'
]
&&
new
Date
(
status
[
'lastLoopDate'
])
||
new
Date
()
let
loopInterval
=
(
new
Date
()).
getHours
()
-
lastLoopDate
.
getHours
()
let
loopInterval
=
(
new
Date
()).
getHours
()
-
lastLoopDate
.
getHours
()
let
lastGenerate
=
`<br/><br/><br/>上次循环时间
${
lastLoopDate
.
toLocaleString
()}
, 间隔:
${
loopInterval
}
小时`
let
lastGenerate
=
`<br/><br/><br/>上次循环时间
${
lastLoopDate
.
toLocaleString
()}
, 间隔:
${
loopInterval
}
小时`
status
[
'lastLoopDate'
]
=
Date
()
//
status['lastLoopDate'] = Date()
if
(
!
isFirstRun
if
(
!
isFirstRun
&&
!
needSendList
&&
!
needSendList
&&
newOffline
.
length
==
0
&&
newOffline
.
length
==
0
...
@@ -698,13 +674,6 @@ function genMail() {
...
@@ -698,13 +674,6 @@ function genMail() {
emailContent
+=
nowGenerate
emailContent
+=
nowGenerate
emailContent
+=
lastGenerate
emailContent
+=
lastGenerate
log
(
`生成邮件内容: \n
${
emailContent
}
`
)
log
(
`生成邮件内容: \n
${
emailContent
}
`
)
// 清空临时栈
newOffline
=
[]
newOnline
=
[]
permissionChange
=
{}
failedApps
=
[]
errorLog
=
[]
newTopMonitorNames
=
{}
return
`<div>
${
firstLine
}
</div><br/>
${
emailContent
}
<br/>version:
${
version
}
`
return
`<div>
${
firstLine
}
</div><br/>
${
emailContent
}
<br/>version:
${
version
}
`
}
}
...
@@ -749,6 +718,71 @@ function aliveContent(date, lastSend) {
...
@@ -749,6 +718,71 @@ function aliveContent(date, lastSend) {
return
emailContent
return
emailContent
}
}
function
clearLocalVariable
()
{
// 清除临时变量
newOffline
=
[]
newOnline
=
[]
permissionChange
=
{}
failedApps
=
[]
errorLog
=
[]
newTopMonitorNames
=
{}
hitDaichao
=
0
hitOurs
=
0
}
function
outLink
(
name
)
{
return
`<a href="
${
base_gp_url
}${
name
}
">
${
getRegion
(
name
)}
-
${
name
}
<br/>
名字:
${(
status
[
name
]
&&
(
status
[
name
].
appName
||
`(noName:这次更新数据里没有进前
${
requestTopAppNum
}
)`
))}
</a>`
}
function
notifyOutside
()
{
// 通知外部人员
// 拿到有变动的 ourappids 列表, 拿到对应名字, 截取客户 ID,
// 判断是需要通知的客户, 就生成对应内容
// 根据这个, 遍历发送邮件
if
(
Object
.
keys
(
outsideNotifier
).
length
==
0
)
return
;
// 预先构建结构
let
outsideNotifyDict
=
{}
for
(
var
key
in
outsideNotifier
)
{
outsideNotifyDict
[
key
]
=
{
mailTo
:
outsideNotifier
[
key
].
emails
,
appIds
:
[],
content
:
""
}
}
let
ourDown
=
ourAppIds
.
filter
(
val
=>
newOffline
.
includes
(
val
))
// 拿到自己登记的下线的产品
ourDown
.
forEach
(
val
=>
{
// 组合数据结构: {customerID: { mailTo: [], appIds: []}
// 拿到客户 ID
let
name
=
ourApps
[
val
]
||
"None ID"
let
customerID
=
name
.
split
(
' '
)[
0
]
// 是否要通知
if
(
customerID
in
outsideNotifier
)
{
outsideNotifyDict
[
customerID
].
appIds
=
[...
outsideNotifyDict
[
customerID
].
appIds
,
val
]
}
})
let
nowGenerate
=
`<br/><br/>邮件生成时间: <br/>
${
new
Date
().
toLocaleString
()}
`
let
lastLoopDate
=
status
[
'lastLoopDate'
]
&&
new
Date
(
status
[
'lastLoopDate'
])
||
new
Date
()
let
loopInterval
=
(
new
Date
()).
getHours
()
-
lastLoopDate
.
getHours
()
let
lastGenerate
=
`<br/><br/><br/>上次循环时间
${
lastLoopDate
.
toLocaleString
()}
, 间隔:
${
loopInterval
}
小时`
for
(
let
key
in
outsideNotifyDict
)
{
if
(
outsideNotifyDict
[
key
].
appIds
.
length
==
0
)
continue
;
let
emailContent
=
wrapSummary
(
"观察到下线"
,
outsideNotifyDict
[
key
].
appIds
.
map
(
val
=>
outLink
(
val
)),
"red"
,
true
)
emailContent
+=
nowGenerate
emailContent
+=
lastGenerate
outsideNotifyDict
[
key
].
content
=
`<div>下线通知</div><br/>
${
emailContent
}
<br/>version:
${
version
}
`
sendEmail
(
emailContent
,
outsideNotifyDict
[
key
].
mailTo
)
}
}
function
sendEmail
(
content
,
to
=
notifyEmail
)
{
function
sendEmail
(
content
,
to
=
notifyEmail
)
{
if
(
content
==
null
||
content
==
undefined
||
content
==
''
)
{
if
(
content
==
null
||
content
==
undefined
||
content
==
''
)
{
log
(
'没有生成内容, 检查心跳'
,
true
)
log
(
'没有生成内容, 检查心跳'
,
true
)
...
@@ -776,13 +810,13 @@ function sendEmail(content, to = notifyEmail) {
...
@@ -776,13 +810,13 @@ function sendEmail(content, to = notifyEmail) {
return
return
}
}
log
(
`发送email:
${
content
.
length
}
`
,
true
)
log
(
`发送email:
${
content
.
length
}
`
,
true
)
// if (content.indexOf('Error') != -1) {
// to = developer
// } else {
// // to = [...to, 添加只对自己app监控的人]
// }
let
myEmail
=
'yingchen.nong@starwin.com'
let
myEmail
=
'yingchen.nong@starwin.com'
// 有贷超下线才发送
let
daichaoDown
=
daichaoApps
.
filter
(
val
=>
newOffline
.
includes
(
val
))
if
(
daichaoDown
&&
daichaoDown
.
length
>
0
)
{
to
=
[...
to
,
...
daichaoNotifyEmail
]
}
let
emailTo
=
to
.
join
(
', '
)
let
emailTo
=
to
.
join
(
', '
)
let
trans
=
nodemailer
.
createTransport
({
let
trans
=
nodemailer
.
createTransport
({
host
:
'smtp.exmail.qq.com'
,
host
:
'smtp.exmail.qq.com'
,
...
@@ -813,11 +847,8 @@ function sendEmail(content, to = notifyEmail) {
...
@@ -813,11 +847,8 @@ function sendEmail(content, to = notifyEmail) {
})
})
dingDing
(
content
,
notifyDingding
)
dingDing
(
content
,
notifyDingding
)
// 清空计数
hitDaichao
=
0
hitOurs
=
0
}
}
function
dingDing
(
content
,
toDing
=
debugDingding
)
{
function
dingDing
(
content
,
toDing
=
debugDingding
)
{
log
(
`发送钉钉~`
)
log
(
`发送钉钉~`
)
content
=
`
${
crabName
}
\n`
+
content
content
=
`
${
crabName
}
\n`
+
content
...
@@ -888,9 +919,9 @@ function judgePermissionChanged(name, newPermission) {
...
@@ -888,9 +919,9 @@ function judgePermissionChanged(name, newPermission) {
}
}
}
}
function
wrapSummary
(
title
,
list
,
color
=
'black'
)
{
function
wrapSummary
(
title
,
list
,
color
=
'black'
,
open
=
false
)
{
let
emailContent
=
''
let
emailContent
=
''
emailContent
+=
`<details style="color:
${
color
}
">`
emailContent
+=
`<details style="color:
${
color
}
"
${
open
?
'open'
:
''
}
>`
emailContent
+=
`<summary>
${
title
}
: </summary>`
emailContent
+=
`<summary>
${
title
}
: </summary>`
emailContent
+=
`<dl>`
emailContent
+=
`<dl>`
list
.
forEach
(
l
=>
{
list
.
forEach
(
l
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment