mirror of https://github.com/ghostfolio/ghostfolio
committed by
GitHub
27 changed files with 202 additions and 82 deletions
@ -1,18 +1,20 @@ |
|||
import { AuthDeviceController } from '@ghostfolio/api/app/auth-device/auth-device.controller'; |
|||
import { AuthDeviceService } from '@ghostfolio/api/app/auth-device/auth-device.service'; |
|||
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service'; |
|||
import { PrismaService } from '@ghostfolio/api/services/prisma.service'; |
|||
import { ConfigurationModule } from '@ghostfolio/api/services/configuration.module'; |
|||
import { PrismaModule } from '@ghostfolio/api/services/prisma.module'; |
|||
import { Module } from '@nestjs/common'; |
|||
import { JwtModule } from '@nestjs/jwt'; |
|||
|
|||
@Module({ |
|||
controllers: [AuthDeviceController], |
|||
imports: [ |
|||
ConfigurationModule, |
|||
JwtModule.register({ |
|||
secret: process.env.JWT_SECRET_KEY, |
|||
signOptions: { expiresIn: '180 days' } |
|||
}) |
|||
}), |
|||
PrismaModule |
|||
], |
|||
providers: [AuthDeviceService, ConfigurationService, PrismaService] |
|||
providers: [AuthDeviceService] |
|||
}) |
|||
export class AuthDeviceModule {} |
|||
|
@ -1,30 +1,27 @@ |
|||
import { CacheService } from '@ghostfolio/api/app/cache/cache.service'; |
|||
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module'; |
|||
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service'; |
|||
import { ConfigurationModule } from '@ghostfolio/api/services/configuration.module'; |
|||
import { DataGatheringModule } from '@ghostfolio/api/services/data-gathering.module'; |
|||
import { DataGatheringService } from '@ghostfolio/api/services/data-gathering.service'; |
|||
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module'; |
|||
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data.module'; |
|||
import { PrismaService } from '@ghostfolio/api/services/prisma.service'; |
|||
import { PrismaModule } from '@ghostfolio/api/services/prisma.module'; |
|||
import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile.module'; |
|||
import { Module } from '@nestjs/common'; |
|||
|
|||
import { CacheController } from './cache.controller'; |
|||
|
|||
@Module({ |
|||
exports: [CacheService], |
|||
controllers: [CacheController], |
|||
imports: [ |
|||
ConfigurationModule, |
|||
DataGatheringModule, |
|||
DataProviderModule, |
|||
ExchangeRateDataModule, |
|||
PrismaModule, |
|||
RedisCacheModule, |
|||
SymbolProfileModule |
|||
], |
|||
controllers: [CacheController], |
|||
providers: [ |
|||
CacheService, |
|||
ConfigurationService, |
|||
DataGatheringService, |
|||
PrismaService |
|||
] |
|||
providers: [CacheService] |
|||
}) |
|||
export class CacheModule {} |
|||
|
@ -0,0 +1,11 @@ |
|||
import { SymbolModule } from '@ghostfolio/api/app/symbol/symbol.module'; |
|||
import { ConfigurationModule } from '@ghostfolio/api/services/configuration.module'; |
|||
import { TwitterBotService } from '@ghostfolio/api/services/twitter-bot/twitter-bot.service'; |
|||
import { Module } from '@nestjs/common'; |
|||
|
|||
@Module({ |
|||
exports: [TwitterBotService], |
|||
imports: [ConfigurationModule, SymbolModule], |
|||
providers: [TwitterBotService] |
|||
}) |
|||
export class TwitterBotModule {} |
@ -0,0 +1,60 @@ |
|||
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service'; |
|||
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service'; |
|||
import { |
|||
ghostfolioFearAndGreedIndexDataSource, |
|||
ghostfolioFearAndGreedIndexSymbol |
|||
} from '@ghostfolio/common/config'; |
|||
import { resolveFearAndGreedIndex } from '@ghostfolio/common/helper'; |
|||
import { Injectable, Logger } from '@nestjs/common'; |
|||
import { TwitterApi, TwitterApiReadWrite } from 'twitter-api-v2'; |
|||
|
|||
@Injectable() |
|||
export class TwitterBotService { |
|||
private twitterClient: TwitterApiReadWrite; |
|||
|
|||
public constructor( |
|||
private readonly configurationService: ConfigurationService, |
|||
private readonly symbolService: SymbolService |
|||
) { |
|||
this.twitterClient = new TwitterApi({ |
|||
accessSecret: this.configurationService.get( |
|||
'TWITTER_ACCESS_TOKEN_SECRET' |
|||
), |
|||
accessToken: this.configurationService.get('TWITTER_ACCESS_TOKEN'), |
|||
appKey: this.configurationService.get('TWITTER_API_KEY'), |
|||
appSecret: this.configurationService.get('TWITTER_API_SECRET') |
|||
}).readWrite; |
|||
} |
|||
|
|||
public async tweetFearAndGreedIndex() { |
|||
if (!this.configurationService.get('ENABLE_FEATURE_FEAR_AND_GREED_INDEX')) { |
|||
return; |
|||
} |
|||
|
|||
try { |
|||
const symbolItem = await this.symbolService.get({ |
|||
dataGatheringItem: { |
|||
dataSource: ghostfolioFearAndGreedIndexDataSource, |
|||
symbol: ghostfolioFearAndGreedIndexSymbol |
|||
} |
|||
}); |
|||
|
|||
if (symbolItem?.marketPrice) { |
|||
const { emoji, text } = resolveFearAndGreedIndex( |
|||
symbolItem.marketPrice |
|||
); |
|||
|
|||
const status = `Current Market Mood: ${emoji} ${text} (${symbolItem.marketPrice}/100)\n\n#FearAndGreed #Markets #ServiceTweet`; |
|||
const { data: createdTweet } = await this.twitterClient.v2.tweet( |
|||
status |
|||
); |
|||
|
|||
Logger.log( |
|||
`Fear & Greed Index has been tweeted: https://twitter.com/ghostfolio_/status/${createdTweet.id}` |
|||
); |
|||
} |
|||
} catch (error) { |
|||
Logger.error(error); |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue