123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- package handlers
- import (
- "net/http"
- "git.linuxforward.com/byom/byom-trends/analysis"
- "git.linuxforward.com/byom/byom-trends/common"
- "git.linuxforward.com/byom/byom-trends/logger"
- "git.linuxforward.com/byom/byom-trends/services/instagram"
- "git.linuxforward.com/byom/byom-trends/services/tiktok"
- "git.linuxforward.com/byom/byom-trends/services/youtube"
- "git.linuxforward.com/byom/byom-trends/store"
- "github.com/gin-gonic/gin"
- "github.com/google/uuid"
- "github.com/sirupsen/logrus"
- )
- type SocialHandler struct {
- store *store.DataStore
- analyzer *analysis.TrendAnalyzer
- instagramSvc *instagram.Client
- tiktokSvc *tiktok.Client
- youtubeSvc *youtube.Client
- logger *logrus.Entry
- }
- type ConnectProfileRequest struct {
- Platform string `json:"platform" binding:"required,oneof=instagram tiktok youtube"`
- Username string `json:"username" binding:"required"`
- ProfileURL string `json:"profile_url" binding:"required,url"`
- }
- func NewSocialHandler(
- store *store.DataStore,
- instagramSvc *instagram.Client,
- tiktokSvc *tiktok.Client,
- youtubeSvc *youtube.Client,
- ) *SocialHandler {
- return &SocialHandler{
- store: store,
- instagramSvc: instagramSvc,
- tiktokSvc: tiktokSvc,
- youtubeSvc: youtubeSvc,
- logger: logger.NewLogger("social-handler"),
- }
- }
- // ConnectProfile connects a new social media profile
- func (h *SocialHandler) ConnectProfile(c *gin.Context) {
- var req ConnectProfileRequest
- if err := c.ShouldBindJSON(&req); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
- return
- }
- profile := &common.SocialProfile{
- ID: uuid.New(),
- Platform: req.Platform,
- Username: req.Username,
- ProfileURL: req.ProfileURL,
- }
- // Verify profile exists and get initial stats
- //var err error
- switch req.Platform {
- case "instagram":
- stats, err := h.instagramSvc.GetProfileStats(req.Username)
- if err != nil {
- h.logger.WithError(err).Error("failed to get Instagram profile stats")
- c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to verify Instagram profile"})
- return
- }
- profile.FollowerCount = stats.FollowerCount
- profile.Engagement = stats.Engagement
- case "tiktok":
- stats, err := h.tiktokSvc.GetProfileStats(req.Username)
- if err != nil {
- h.logger.WithError(err).Error("failed to get TikTok profile stats")
- c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to verify TikTok profile"})
- return
- }
- profile.FollowerCount = stats.FollowerCount
- profile.Engagement = stats.Engagement
- case "youtube":
- stats, err := h.youtubeSvc.GetChannelStats(req.Username)
- if err != nil {
- h.logger.WithError(err).Error("failed to get YouTube channel stats")
- c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to verify YouTube channel"})
- return
- }
- profile.FollowerCount = stats.SubscriberCount
- profile.Engagement = stats.Engagement
- }
- if err := h.store.CreateSocialProfile(c, profile); err != nil {
- h.logger.WithError(err).Error("failed to create social profile")
- c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create social profile"})
- return
- }
- c.JSON(http.StatusCreated, profile)
- }
- // GetProfileStats retrieves stats for a connected profile
- func (h *SocialHandler) GetProfileStats(c *gin.Context) {
- platform := c.Param("platform")
- username := c.Query("username")
- if username == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "Username is required"})
- return
- }
- var stats interface{}
- var err error
- switch platform {
- case "instagram":
- stats, err = h.instagramSvc.GetProfileStats(username)
- case "tiktok":
- stats, err = h.tiktokSvc.GetProfileStats(username)
- case "youtube":
- stats, err = h.youtubeSvc.GetChannelStats(username)
- default:
- c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid platform"})
- return
- }
- if err != nil {
- h.logger.WithError(err).Error("failed to get profile stats")
- c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get profile stats"})
- return
- }
- c.JSON(http.StatusOK, stats)
- }
- // GetProfileEngagement retrieves engagement metrics for a profile
- func (h *SocialHandler) GetProfileEngagement(c *gin.Context) {
- profileID, err := uuid.Parse(c.Param("id"))
- if err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid profile ID"})
- return
- }
- profile, err := h.store.GetSocialProfile(c, profileID)
- if err != nil {
- h.logger.WithError(err).Error("failed to get social profile")
- c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get social profile"})
- return
- }
- if profile == nil {
- c.JSON(http.StatusNotFound, gin.H{"error": "Profile not found"})
- return
- }
- metrics, err := h.analyzer.AnalyzeEngagement(c, profile)
- if err != nil {
- h.logger.WithError(err).Error("failed to analyze engagement")
- c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to analyze engagement"})
- return
- }
- c.JSON(http.StatusOK, metrics)
- }
|