managarten/packages/bot-services/src/planta/planta.module.ts
Till-JS dcf4438804 feat(mana-bot): add daily morning summary feature
Add configurable morning summaries that aggregate data from multiple sources:
- Weather forecast via Open-Meteo API (free, no API key needed)
- Today's calendar events
- Today's tasks + overdue tasks
- Birthdays from contacts
- Plants needing water from Planta

New commands:
- !morning / !morgen - Get summary now
- !morning-on/off - Enable/disable automatic delivery
- !morning-time HH:MM - Set delivery time
- !morning-location [city] - Set weather location
- !morning-timezone [zone] - Set timezone
- !morning-format [kompakt|ausfuehrlich] - Set format
- !morning-settings - Show current settings

New shared services in @manacore/bot-services:
- WeatherService - Open-Meteo integration with geocoding
- ContactsApiService - Birthday fetching
- PlantaApiService - Watering schedule
- MorningSummaryService - Aggregates all sources
- MorningPreferencesService - User preferences storage

Includes scheduler for automatic daily delivery at user-configured time.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 11:01:47 +01:00

89 lines
1.9 KiB
TypeScript

import { Module, DynamicModule, Global } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { PlantaApiService } from './planta-api.service';
import { PlantaModuleOptions, PLANTA_MODULE_OPTIONS } from './types';
/**
* Planta Module
*
* Plant care and watering management API client.
*
* @example
* ```typescript
* // Basic usage
* @Module({
* imports: [PlantaModule.register()]
* })
*
* // With custom API URL
* @Module({
* imports: [
* PlantaModule.register({
* apiUrl: 'http://planta-backend:3022',
* })
* ]
* })
* ```
*/
@Global()
@Module({})
export class PlantaModule {
/**
* Register module with explicit options
*/
static register(options: PlantaModuleOptions = {}): DynamicModule {
return {
module: PlantaModule,
providers: [
{
provide: PLANTA_MODULE_OPTIONS,
useValue: options,
},
PlantaApiService,
],
exports: [PlantaApiService],
};
}
/**
* Register module with async configuration
*/
static registerAsync(options: {
imports?: any[];
useFactory: (...args: any[]) => Promise<PlantaModuleOptions> | PlantaModuleOptions;
inject?: any[];
}): DynamicModule {
return {
module: PlantaModule,
imports: [...(options.imports || [])],
providers: [
{
provide: PLANTA_MODULE_OPTIONS,
useFactory: options.useFactory,
inject: options.inject || [],
},
PlantaApiService,
],
exports: [PlantaApiService],
};
}
/**
* Register with ConfigService reading from environment
*
* Environment variables:
* - PLANTA_API_URL: Planta backend URL
*/
static forRoot(): DynamicModule {
return this.registerAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
apiUrl:
config.get<string>('planta.apiUrl') ||
config.get<string>('PLANTA_API_URL') ||
'http://localhost:3022',
}),
inject: [ConfigService],
});
}
}