0x0x230x

Untitled

Nov 25th, 2024
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.44 KB | None | 0 0
  1. // import chromium from '@sparticuz/chromium-min';
  2. // import puppeteer from 'puppeteer-core';
  3. import * as cheerio from 'cheerio';
  4.  
  5. import { ScrapperServiceResponse } from './scrapper.schema';
  6. import { Address, privateKeyToAccount } from 'viem/accounts';
  7. import { env } from '@/app/lib/env';
  8. import { createWalletClient, http, parseEther, WalletClient } from 'viem';
  9. import { degen } from 'viem/chains';
  10. import { actionsService } from '@/app/modules/actions/actions.service';
  11. import { ETH_NATIVE_ADDRESS, EXT_REVIEW_ACTION_ID } from '@/app/lib/constants';
  12. import { UserType } from '@/app/lib/types';
  13.  
  14. class ChromeStoreScraperService {
  15. async scrapeReviews(user: UserType): Promise<ScrapperServiceResponse> {
  16. const isCompleted = await actionsService.checkIfActionIsCompleted(
  17. user,
  18. EXT_REVIEW_ACTION_ID
  19. );
  20.  
  21. if (isCompleted) {
  22. return {
  23. type: 'error',
  24. error: 'User has already completed the action',
  25. status: 400
  26. };
  27. }
  28.  
  29. try {
  30. const response = await fetch(
  31. 'https://chromewebstore.google.com/detail/pjolohbafcgpmdingblobfffkmobopec/reviews'
  32. );
  33. const html = await response.text();
  34.  
  35. const $ = cheerio.load(html);
  36.  
  37. // Create today's date in PST
  38. const today = new Date();
  39. // Convert to PST (UTC-8)
  40. const pstOffset = -8;
  41. const userOffset = today.getTimezoneOffset() / 60;
  42. const offsetDiff = pstOffset - userOffset;
  43.  
  44. const pstDate = new Date(today.getTime() + offsetDiff * 60 * 60 * 1000);
  45.  
  46. const todayString = pstDate.toLocaleDateString('en-US', {
  47. month: 'short',
  48. day: 'numeric',
  49. year: 'numeric'
  50. });
  51.  
  52. const reviews = $('section.T7rvce')
  53. .map((_, element) => {
  54. const author = $(element).find('.LfYwpe').text().trim();
  55. const ratingText = $(element)
  56. .find('[aria-label*="stars"]')
  57. .attr('aria-label');
  58. const rating = ratingText
  59. ? parseInt(ratingText.match(/(\d+)/)?.[1] || '0')
  60. : 0;
  61. const date = $(element).find('.ydlbEf').text().trim();
  62. const content = $(element).find('.f2bEpf').text().trim();
  63.  
  64. return {
  65. author,
  66. rating,
  67. date,
  68. content
  69. };
  70. })
  71. .get();
  72.  
  73. console.log('Scraped reviews:', reviews);
  74. console.log('Today (UTC):', todayString);
  75. console.log('First review date:', reviews[0]?.date);
  76.  
  77. const hasReviewToday = reviews.some(
  78. (review) => review.date === todayString
  79. );
  80.  
  81. if (!hasReviewToday) {
  82. return {
  83. type: 'error',
  84. error: 'No review found today',
  85. status: 400
  86. };
  87. }
  88.  
  89. await this.tipUser(user);
  90.  
  91. return {
  92. type: 'success',
  93. data: {
  94. reviews,
  95. total_reviews: reviews.length,
  96. has_review_today: hasReviewToday
  97. },
  98. status: 200
  99. };
  100. } catch (error) {
  101. return {
  102. type: 'error',
  103. error:
  104. error instanceof Error
  105. ? error.message
  106. : 'An unexpected error occurred',
  107. status: 500
  108. };
  109. }
  110. }
  111.  
  112. // Rest of the class remains the same
  113. async tipUser(user: UserType) {
  114. const amount = 5;
  115. const walletClient = this.generateWallet();
  116.  
  117. const hash = await this.sendTransaction(
  118. walletClient,
  119. user.address as Address,
  120. amount
  121. );
  122.  
  123. await actionsService.completeAction(user, {
  124. action_id: EXT_REVIEW_ACTION_ID,
  125. value: {
  126. hash,
  127. chain_id: degen.id,
  128. amount,
  129. token_address: ETH_NATIVE_ADDRESS,
  130. symbol: 'degen'
  131. },
  132. activity_text: `Left a review for the extension and earned ${amount} $DEGEN! 🎉`
  133. });
  134. }
  135.  
  136. private generateWallet() {
  137. const account = privateKeyToAccount(env.TIP_SHOTS_PRIVATE_KEY as Address);
  138.  
  139. return createWalletClient({
  140. account,
  141. chain: degen,
  142. transport: http()
  143. });
  144. }
  145.  
  146. private async sendTransaction(
  147. walletClient: WalletClient,
  148. userAddress: Address,
  149. amount: number
  150. ) {
  151. const hash = await walletClient.sendTransaction({
  152. account: walletClient.account!,
  153. to: userAddress,
  154. value: parseEther(amount.toString()),
  155. chain: degen
  156. });
  157.  
  158. return hash;
  159. }
  160. }
  161.  
  162. export const chromeStoreScraperService = new ChromeStoreScraperService();
Advertisement
Add Comment
Please, Sign In to add comment