get_paypal_accounts_csv.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. const RecurlyWrapper = require('../../app/src/Features/Subscription/RecurlyWrapper')
  2. const async = require('async')
  3. const CSVParser = require('json2csv').Parser
  4. const NOW = new Date()
  5. const slowCallback = (callback, error, data) =>
  6. setTimeout(() => callback(error, data), 80)
  7. const handleAPIError = (type, account, error, callback) => {
  8. console.warn(
  9. `Errors getting ${type} for account ${account.account_code}`,
  10. error
  11. )
  12. if (typeof error === 'string' && error.match(/429$/)) {
  13. return setTimeout(callback, 1000 * 60 * 5)
  14. }
  15. slowCallback(callback)
  16. }
  17. const getAccountSubscription = (account, callback) =>
  18. RecurlyWrapper.getSubscriptions(account.account_code, (error, response) => {
  19. if (error) {
  20. return handleAPIError('subscriptions', account, error, callback)
  21. }
  22. slowCallback(callback, null, response.subscriptions[0])
  23. })
  24. const isAccountUsingPaypal = (account, callback) =>
  25. RecurlyWrapper.getBillingInfo(account.account_code, (error, response) => {
  26. if (error) {
  27. return handleAPIError('billing info', account, error, callback)
  28. }
  29. if (response.billing_info.paypal_billing_agreement_id) {
  30. return slowCallback(callback, null, true)
  31. }
  32. slowCallback(callback, null, false)
  33. })
  34. const printAccountCSV = (account, callback) => {
  35. isAccountUsingPaypal(account, (error, isPaypal) => {
  36. if (error || !isPaypal) {
  37. return callback(error)
  38. }
  39. getAccountSubscription(account, (error, subscription) => {
  40. if (error || !subscription) {
  41. return callback(error)
  42. }
  43. const endAt = new Date(subscription.current_period_ends_at)
  44. if (subscription.expires_at) {
  45. return callback()
  46. }
  47. const csvData = {
  48. email: account.email,
  49. first_name: account.first_name,
  50. last_name: account.last_name,
  51. hosted_login_token: account.hosted_login_token,
  52. billing_info_url: `https://sharelatex.recurly.com/account/billing_info/edit?ht=${
  53. account.hosted_login_token
  54. }`,
  55. account_management_url: `https://sharelatex.recurly.com/account/${
  56. account.hosted_login_token
  57. }`,
  58. current_period_ends_at: `${endAt.getFullYear()}-${endAt.getMonth() +
  59. 1}-${endAt.getDate()}`,
  60. current_period_ends_at_segment: parseInt(
  61. ((endAt - NOW) / 1000 / 3600 / 24 / 365) * 7
  62. )
  63. }
  64. callback(null, csvData)
  65. })
  66. })
  67. }
  68. const printAccountsCSV = callback => {
  69. RecurlyWrapper.getPaginatedEndpoint(
  70. 'accounts',
  71. { state: 'subscriber' },
  72. (error, accounts) => {
  73. if (error) {
  74. return callback(error)
  75. }
  76. async.mapSeries(accounts, printAccountCSV, (error, csvData) => {
  77. csvData = csvData.filter(d => !!d)
  78. callback(error, csvData)
  79. })
  80. }
  81. )
  82. }
  83. const csvFields = [
  84. 'email',
  85. 'first_name',
  86. 'last_name',
  87. 'hosted_login_token',
  88. 'billing_info_url',
  89. 'account_management_url',
  90. 'current_period_ends_at',
  91. 'current_period_ends_at_segment'
  92. ]
  93. const csvParser = new CSVParser({ csvFields })
  94. // print each account
  95. printAccountsCSV((error, csvData) => {
  96. if (error) {
  97. throw error
  98. }
  99. console.log(csvParser.parse(csvData))
  100. process.exit()
  101. })