Commit 9900220b authored by soheib's avatar soheib
Browse files

add get comments add get profile func for azadi gold

parents
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
# compiled output
/dist
/node_modules
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# OS
.DS_Store
# Tests
/coverage
/.nyc_output
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
\ No newline at end of file
{
"singleQuote": true,
"trailingComma": "all"
}
\ No newline at end of file
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a>
</p>
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
## Description
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation
```bash
$ npm install
```
## Running the app
```bash
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
```
## Test
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
```
## Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
## License
Nest is [MIT licensed](LICENSE).
{
"collection": "@nestjs/schematics",
"sourceRoot": "src"
}
This diff is collapsed.
{
"name": "instagram",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^7.6.15",
"@nestjs/core": "^7.6.15",
"@nestjs/mongoose": "^8.0.0",
"@nestjs/platform-express": "^7.6.15",
"instagram-private-api": "^1.45.1",
"instagram-web-api": "^2.2.2",
"mongoose": "^5.13.3",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^6.6.6"
},
"devDependencies": {
"@nestjs/cli": "^7.6.0",
"@nestjs/schematics": "^7.3.0",
"@nestjs/testing": "^7.6.15",
"@types/express": "^4.17.11",
"@types/jest": "^26.0.22",
"@types/lodash": "^4.14.171",
"@types/node": "^14.14.36",
"@types/supertest": "^2.0.10",
"@typescript-eslint/eslint-plugin": "^4.19.0",
"@typescript-eslint/parser": "^4.19.0",
"eslint": "^7.22.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^3.3.1",
"jest": "^26.6.3",
"prettier": "^2.2.1",
"supertest": "^6.1.3",
"ts-jest": "^26.5.4",
"ts-loader": "^8.0.18",
"ts-node": "^9.1.1",
"tsconfig-paths": "^3.9.0",
"typescript": "^4.2.3"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
import { Document, Types } from 'mongoose'
export type AccountFollowersDocument = AccountFollowers & Document
@Schema({timestamps:true})
export class AccountFollowers {
@Prop()
_id: Types.ObjectId
@Prop()
account_username: string
@Prop()
username: string
@Prop()
user_id: string
@Prop()
profile_pic: string
@Prop()
full_name: string
}
export const AccountFollowersSchema = SchemaFactory.createForClass(AccountFollowers)
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('get-comments')
async getCommentsFromIG() {
return await this.appService.getComments();
}
@Get('get-followers')
async getFollowers() {
return await this.appService.getFollowers();
}
}
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { AccountFollowersSchema } from './account.followers';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CommentSchema } from './comment.schema';
import { RequestSchema } from './request.schema';
import { UserSchema } from './user.schema';
@Module({
imports: [
MongooseModule.forRoot('mongodb://localhost/netware'),
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
MongooseModule.forFeature([{ name: 'Request', schema: RequestSchema }]),
MongooseModule.forFeature([{ name: 'Comment', schema: CommentSchema }]),
MongooseModule.forFeature([{ name: 'AccountFollower', schema: AccountFollowersSchema }]),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
import { HttpException, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { IgApiClient } from 'instagram-private-api';
import { sample } from 'lodash';
import { Model, Types } from 'mongoose';
import { CommentDocument } from './comment.schema';
import { IFollower } from './interface/Ifollower';
import { IncomingComment } from './interface/IncomingComment';
import { RequestDocument } from './request.schema';
import { UserDocument } from './user.schema';
const Instagram = require('instagram-web-api')
const { username, password } = process.env
@Injectable()
export class AppService {
constructor(
@InjectModel('User')
private userModel: Model<UserDocument>,
@InjectModel('Request')
private requestModel: Model<RequestDocument>,
@InjectModel('Comment')
private commentModel: Model<CommentDocument>,
@InjectModel('AccountFollower')
private followerModel: Model<CommentDocument>
) { }
async getFollowers(postShortCode: string = 'CRWNkkchs2x') {
try {
const username = 'sohe.ibs'
const password = "kaka1374"
const client = new Instagram({ username, password })
await client.login()
console.log('user logged in...');
let hasNextPage: boolean = true
let requestCount = 0
let followersCount = 0
let cursor: string = ''
let reqList = await this.requestModel.find({ $and: [{ createdAt: -1 }, { type: "follower" }] })
console.log("Request History:", reqList.length)
if (reqList.length != 0) {
let nextCursor = await this.getNextCursor(client, postShortCode, reqList[0].cursor)
cursor = nextCursor
}
while (hasNextPage) {
console.log("seted cursor", cursor)
console.log("sending request....")
let collectedFollower = await this.sendFollowerRequest(client, cursor)
console.log("request sended. request count:", requestCount);
requestCount++
await this.requestModel.create({ _id: new Types.ObjectId(), cursor: cursor, type: "follower" })
cursor = collectedFollower.cursor
hasNextPage = collectedFollower.hasNextPage
console.log("==================================");
console.log("nextCursor:", cursor)
console.log("has a next page", hasNextPage)
for await (const follower of collectedFollower.followers) {
let check = await this.followerModel.findOne({
$and: [
{ username: follower.username, },
{ user_id: follower.user_id, },
{ full_name: follower.full_name, }
]
})
if (!check) {
await this.followerModel.create({
_id: new Types.ObjectId(),
account_username: "azadi.gold",
username: follower.username,
user_id: follower.user_id,
full_name: follower.full_name,
profile_pic: follower.full_name
})
}
}
console.log(collectedFollower.followers.length, "follower imported")
followersCount += collectedFollower.followers.length
console.log("total added", followersCount)
console.log("================ end of this iterration ==================");
}
return { totalAdded: followersCount }
}
catch (err) {
console.log(err)
}
}
async getComments(postShortCode: string = 'CRWNkkchs2x') {
try {
const username = 'sohe.ibs'
const password = "kaka1374"
const client = new Instagram({ username, password })
await client.login()
console.log('user logged in...');
let hasNextPage: boolean = true
let requestCount = 0
let commentCount = 0
let cursor: string = ''
let reqList = await this.requestModel.find({ $and: [{ createdAt: -1 }, { type: "comment" }] })
console.log("Request History:", reqList.length)
if (reqList.length != 0) {
let nextCursor = await this.getNextCursor(client, postShortCode, reqList[0].cursor)
cursor = nextCursor
}
while (hasNextPage) {
console.log("seted cursor", cursor)
console.log("sending request....")
let collectedComments = await this.sendRequest(client, postShortCode, cursor)
console.log("request sended. request count:", requestCount);
requestCount++
await this.requestModel.create({ _id: new Types.ObjectId(), cursor: cursor, type: "comment" })
cursor = collectedComments.cursor
hasNextPage = collectedComments.hasNextPage
console.log("==================================");
console.log("nextCursor:", cursor)
console.log("has a next page", hasNextPage)
for await (const comment of collectedComments.comments) {
let check = await this.commentModel.findOne({
$and: [
{ user_profile: comment.owner_id },
{ comment: comment.comment_value },
{ date: comment.date }
]
})
if (check) {
await this.commentModel.create({
_id: new Types.ObjectId(),
user_profile: comment.owner_id,
comment: comment.comment_value,
date: comment.date
})
}
}
console.log(collectedComments.comments.length, "comment imported")
commentCount += collectedComments.comments.length
console.log("total added", commentCount)
console.log("================ end of this iterration ==================");
}
return { totalAdded: commentCount }
}
catch (err) {
console.log(err)
}
}
async getNextCursor(client, cursor: string, postShortCode: string) {
let incomingComments = await client.getMediaComments({ shortcode: postShortCode, first: "49", after: cursor })
return incomingComments.page_info.end_cursor
}
async sendRequest(client, postShortCode, cursor) {
try {
let comments: IncomingComment[] = new Array<IncomingComment>()
let incomingComments = await client.getMediaComments({ shortcode: postShortCode, after: cursor })
await this.delay(30000)
for (const comment of incomingComments.edges) {
console.log(comment);
comments.push({
owner_id: comment.node.owner.username,
comment_value: comment.node.text,
date: comment.node.created_at
})
console.log(`${comment.node.text} is pushed.`)
}
return {
comments,
cursor: incomingComments.page_info.end_cursor,
hasNextPage: incomingComments.page_info.has_next_page
}
}
catch (err) {
console.log(err)
throw new HttpException(err.message, 500)
}
}
async sendFollowerRequest(client, cursor) {
try {
let Infollowers: IFollower[] = new Array<IFollower>()
const azadiGoldUser = await client.getUserByUsername({ username: 'azadi.gold' })
const followers = await client.getFollowers({ userId: azadiGoldUser.id, after: cursor })
await this.delay(30000)
for (const user of followers.data) {
Infollowers.push({
user_id: user.id,
username: user.username,
full_name: user.full_name,
profile_pic: user.profile_pic_url
})
console.log(`${user.username} is pushed.`)
}
return {
followers,
cursor: followers.page_info.end_cursor,
hasNextPage: followers.page_info.has_next_page
}
}
catch (err) {
console.log(err)
throw new HttpException(err.message, 500)
}
}
async delay(ms) {
// return await for better async stack trace support in case of errors.
return await new Promise(resolve => setTimeout(resolve, ms));
}
}
// const ig = new IgApiClient();
// ig.state.generateDevice('sohe.ibs');
// await ig.simulate.preLoginFlow();
// const loggedInUser = await ig.account.login('sohe.ibs', "kaka1374");
// process.nextTick(async () => await ig.simulate.postLoginFlow());
// let azadiGold = await ig.search.users("azadi.gold")
// console.log(azadiGold);
// const userFeed = ig.feed.user(loggedInUser.pk);
// const myPostsFirstPage = await userFeed.items()
// const followersFeed = ig.feed.accountFollowers(loggedInUser.pk);
// const wholeResponse = await followersFeed.request();
// console.log("=>",wholeResponse); // You can reach any properties in instagram response
// const items = await followersFeed.items();
// console.log("=>2",items); // Here you can reach items. It's array.
// const thirdPageItems = await followersFeed.items();
// console.log("=>3",thirdPageItems);
// const feedState = followersFeed.serialize(); // You can serialize feed state to have an ability to continue get next pages.
// console.log("=>4",feedState);
// followersFeed.deserialize(feedState);
// const fourthPageItems = await followersFeed.items();
// console.log("=>5",fourthPageItems);
// followersFeed.items$.subscribe(
// followers => console.log("=>6",followers),
// error => console.error(error),
// () => console.log('Complete!'),
// );
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
import { Document, Types } from 'mongoose'
export type CommentDocument = Comment & Document
@Schema()
export class Comment {
@Prop()
_id: Types.ObjectId
@Prop()
comment: string
@Prop()
user_profile : string
@Prop()
date: Date
}
export const CommentSchema = SchemaFactory.createForClass(Comment)
export interface IFollower{
user_id: string
username: string
profile_pic: string
full_name: string
}
\ No newline at end of file
export interface IncomingComment {
owner_id: string
comment_value: string
date: Date
}
\ No newline at end of file
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
import { Document, Types } from 'mongoose'
export type RequestDocument = Request & Document
@Schema({timestamps:true})
export class Request {
@Prop()
_id: Types.ObjectId
@Prop()
cursor: string
@Prop()
type: string
}
export const RequestSchema = SchemaFactory.createForClass(Request)
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
import { Document, Types } from 'mongoose'
export type UserDocument = User & Document
@Schema()
export class User {
@Prop()
_id: Types.ObjectId
@Prop({ type: [{ type: Types.ObjectId, ref: 'User' }] })
invitedUsers: Types.ObjectId[]
@Prop()
score : number
}
export const UserSchema = SchemaFactory.createForClass(User)
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment