config.ts 4.1 KB
Newer Older
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
1 2
/**
 * Wechaty - Wechaty for Bot, Connect ChatBots, Chat as a Service
3
 *
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
4 5
 * https://github.com/wechaty/wechaty/
 */
6
import { execSync } from 'child_process'
7
import * as fs from 'fs'
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
8

9 10
import Puppet from './puppet'

11
export type PuppetType = 'web' | 'android' | 'ios'
12
export type HeadName = 'chrome' | 'phantomjs' | 'firefox'
13

14
export interface ConfigSetting {
15

16 17
  DEFAULT_HEAD: HeadName
  DEFAULT_PUPPET: PuppetType
18 19 20
  DEFAULT_APIHOST: string
  DEFAULT_PROFILE: string
  DEFAULT_TOKEN:  string
21 22
  DEFAULT_PROTOCOL: string
  CMD_CHROMIUM: string
23 24 25 26 27 28 29 30
  DEFAULT_PORT: number

  port: number
  profile: string
  token: string
  debug: boolean

  puppet: PuppetType
31
  head: HeadName
32 33

  apihost: string
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
34
  validApiHost: (host: string) => boolean
35 36 37

  httpPort: number

38 39 40 41 42
  _puppetInstance: Puppet | null
  puppetInstance(): Puppet
  puppetInstance(empty: null): void
  puppetInstance(instance: Puppet): Puppet
  puppetInstance(instance?: Puppet | null): Puppet | void
43

44
  isDocker: boolean
45 46

}
47 48
/* tslint:disable:variable-name */
/* tslint:disable:no-var-requires */
49
export const Config: ConfigSetting = require('../package.json').wechaty
50

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
51 52 53
/**
 * 1. ENVIRONMENT VARIABLES + PACKAGES.JSON (default)
 */
54
Object.assign(Config, {
55 56 57
  head:       process.env['WECHATY_HEAD']      || Config.DEFAULT_HEAD
  , puppet:   process.env['WECHATY_PUPPET']    || Config.DEFAULT_PUPPET
  , apihost:  process.env['WECHATY_APIHOST']   || Config.DEFAULT_APIHOST
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
58
  , validApiHost
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
59 60
})

61
function validApiHost(apihost: string): boolean {
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
62 63 64 65 66 67 68
  if (/^[a-zA-Z0-9\.\-\_]+:?[0-9]*$/.test(apihost)) {
    return true
  }
  throw new Error('validApiHost() fail for ' + apihost)
}
validApiHost(Config.apihost)

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
69 70 71 72
/**
 * 2. ENVIRONMENT VARIABLES (only)
 */
Object.assign(Config, {
73 74 75 76
  port:       process.env['WECHATY_PORT']       || null // 0 for disable port
  , profile:  process.env['WECHATY_PROFILE']    || null // DO NOT set DEFAULT_PROFILE, because sometimes user do not want to save session
  , token:    process.env['WECHATY_TOKEN']      || null // DO NOT set DEFAULT, because sometimes user do not want to connect to io cloud service
  , debug:    !!(process.env['WECHATY_DEBUG'])  || false
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
77
})
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
78

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
79 80 81 82 83
/**
 * 3. Service Settings
 */
Object.assign(Config, {
  // get PORT form cloud service env, ie: heroku
84
  httpPort: process.env['PORT'] || process.env['WECHATY_PORT'] || Config.DEFAULT_PORT
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
85 86 87 88 89 90
})

/**
 * 4. Envioronment Identify
 */
Object.assign(Config, {
91
  isDocker:   isWechatyDocker()
92
})
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
93

94
function isWechatyDocker() {
95 96 97
  /**
   * Continuous Integration System
   */
98 99 100 101
  const isCi = require('is-ci')
  if (isCi) {
    return false
  }
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
102

103 104 105 106 107 108 109 110 111 112
  /**
   * Cloud9 IDE
   */
  const c9 = Object.keys(process.env)
                  .filter(k => /^C9_/.test(k))
                  .length
  if (c9 > 7 && process.env['C9_PORT']) {
    return false
  }
  
113
  const cgroup = '/proc/1/cgroup'
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
114
  try       { fs.statSync(cgroup).isFile() }
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
115 116
  catch (e) { return false }

117
  const line = execSync(`sort -n ${cgroup} | head -1`)
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
118 119 120
                .toString()
                .replace(/\n$/, '')

121
  // instead of `/`, docker will end with a container id
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
122 123 124
  if (/\/$/.test(line)) {
    return false
  }
125

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
126 127 128
  return true
}

129 130 131
/**
 * 5. live setting
 */
132
function puppetInstance(instance?: Puppet | null): Puppet | void {
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
133
  if (instance !== undefined) {
134 135 136 137
    if (instance) {
      Config._puppetInstance = instance
      return instance
    }
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
138 139
    Config._puppetInstance = null
    return
140
  }
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
141

142 143
  if (!Config._puppetInstance) {
    throw new Error('no puppet instance')
144 145 146 147
  }
  return Config._puppetInstance
}

148 149 150 151
Object.assign(Config, {
  puppetInstance
})

Huan (李卓桓)'s avatar
bug fix  
Huan (李卓桓) 已提交
152 153 154 155
export type WatchdogFoodName = 'HEARTBEAT'
                              | 'POISON'
                              | 'SCAN'

156
export type WatchdogFood = {
157 158
    data: any
  , timeout?: number  // millisecond
Huan (李卓桓)'s avatar
bug fix  
Huan (李卓桓) 已提交
159
  , type?: WatchdogFoodName
160 161
}

162
export type ScanInfo = {
163 164 165 166
  url: string
  code: number
}

167
export type RecommendInfo = {
168 169 170 171 172 173 174
  UserName:   string
  NickName:   string
  Content:    string // request message
  Ticket:     string // a pass token
  VerifyFlag: number
}

175
export interface Sayable {
176
  say(content: string, replyTo?: any|any[]): Promise<void>
177
}
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
178 179 180
export interface Sleepable {
  sleep(millisecond: number): Promise<void>
}
181

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
182 183
export * from './brolog-env'

184
export default Config