get_paypal_accounts_csv.mjs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import RecurlyWrapper from '../../app/src/Features/Subscription/RecurlyWrapper.mjs'
  2. import async from 'async'
  3. import { Parser as CSVParser } from 'json2csv'
  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=${account.hosted_login_token}`,
  53. account_management_url: `https://sharelatex.recurly.com/account/${account.hosted_login_token}`,
  54. current_period_ends_at: `${endAt.getFullYear()}-${
  55. endAt.getMonth() + 1
  56. }-${endAt.getDate()}`,
  57. current_period_ends_at_segment: parseInt(
  58. ((endAt - NOW) / 1000 / 3600 / 24 / 365) * 7
  59. ),
  60. }
  61. callback(null, csvData)
  62. })
  63. })
  64. }
  65. const printAccountsCSV = callback => {
  66. RecurlyWrapper.getPaginatedEndpoint(
  67. 'accounts',
  68. { state: 'subscriber' },
  69. (error, accounts) => {
  70. if (error) {
  71. return callback(error)
  72. }
  73. async.mapSeries(accounts, printAccountCSV, (error, csvData) => {
  74. csvData = csvData.filter(d => !!d)
  75. callback(error, csvData)
  76. })
  77. }
  78. )
  79. }
  80. const csvFields = [
  81. 'email',
  82. 'first_name',
  83. 'last_name',
  84. 'hosted_login_token',
  85. 'billing_info_url',
  86. 'account_management_url',
  87. 'current_period_ends_at',
  88. 'current_period_ends_at_segment',
  89. ]
  90. const csvParser = new CSVParser({ csvFields })
  91. // print each account
  92. printAccountsCSV((error, csvData) => {
  93. if (error) {
  94. throw error
  95. }
  96. console.log(csvParser.parse(csvData))
  97. process.exit()
  98. })