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 { AuthDeviceController } from '@ghostfolio/api/app/auth-device/auth-device.controller'; |
||||
import { AuthDeviceService } from '@ghostfolio/api/app/auth-device/auth-device.service'; |
import { AuthDeviceService } from '@ghostfolio/api/app/auth-device/auth-device.service'; |
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service'; |
import { ConfigurationModule } from '@ghostfolio/api/services/configuration.module'; |
||||
import { PrismaService } from '@ghostfolio/api/services/prisma.service'; |
import { PrismaModule } from '@ghostfolio/api/services/prisma.module'; |
||||
import { Module } from '@nestjs/common'; |
import { Module } from '@nestjs/common'; |
||||
import { JwtModule } from '@nestjs/jwt'; |
import { JwtModule } from '@nestjs/jwt'; |
||||
|
|
||||
@Module({ |
@Module({ |
||||
controllers: [AuthDeviceController], |
controllers: [AuthDeviceController], |
||||
imports: [ |
imports: [ |
||||
|
ConfigurationModule, |
||||
JwtModule.register({ |
JwtModule.register({ |
||||
secret: process.env.JWT_SECRET_KEY, |
secret: process.env.JWT_SECRET_KEY, |
||||
signOptions: { expiresIn: '180 days' } |
signOptions: { expiresIn: '180 days' } |
||||
}) |
}), |
||||
|
PrismaModule |
||||
], |
], |
||||
providers: [AuthDeviceService, ConfigurationService, PrismaService] |
providers: [AuthDeviceService] |
||||
}) |
}) |
||||
export class AuthDeviceModule {} |
export class AuthDeviceModule {} |
||||
|
@ -1,30 +1,27 @@ |
|||||
import { CacheService } from '@ghostfolio/api/app/cache/cache.service'; |
import { CacheService } from '@ghostfolio/api/app/cache/cache.service'; |
||||
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module'; |
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 { 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 { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module'; |
||||
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data.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 { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile.module'; |
||||
import { Module } from '@nestjs/common'; |
import { Module } from '@nestjs/common'; |
||||
|
|
||||
import { CacheController } from './cache.controller'; |
import { CacheController } from './cache.controller'; |
||||
|
|
||||
@Module({ |
@Module({ |
||||
|
exports: [CacheService], |
||||
|
controllers: [CacheController], |
||||
imports: [ |
imports: [ |
||||
|
ConfigurationModule, |
||||
DataGatheringModule, |
DataGatheringModule, |
||||
DataProviderModule, |
DataProviderModule, |
||||
ExchangeRateDataModule, |
ExchangeRateDataModule, |
||||
|
PrismaModule, |
||||
RedisCacheModule, |
RedisCacheModule, |
||||
SymbolProfileModule |
SymbolProfileModule |
||||
], |
], |
||||
controllers: [CacheController], |
providers: [CacheService] |
||||
providers: [ |
|
||||
CacheService, |
|
||||
ConfigurationService, |
|
||||
DataGatheringService, |
|
||||
PrismaService |
|
||||
] |
|
||||
}) |
}) |
||||
export class CacheModule {} |
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