I am able to receive challenge call and return 200 status code with plain text.
I don’t see any notifications and calling https://api.twitch.tv/helix/webhooks/subscriptions
returns empty
{
“total”: 0,
“data”: [],
“pagination”: {}
}
topic url: https://api.twitch.tv/helix/streams?user_id={0}
Here is my controller code dotnet core code hosted in azure. I can hit both get & post endpoint from internet. What am I missing ?
[Route("/notice/twitch")]
[Produces("application/json")]
[ApiController]
public class TwitchNotificationsController : ControllerBase
{
private const string V1 = "v1";
private const string ChallengeKey = "hub.challenge";
private readonly ILogger logger;
private readonly IVideoGameStreamsNoticeManager noticeManage;
public TwitchNotificationsController(IVideoGameStreamsNoticeManager noticeManager, ILogger logger = null)
{
noticeManager.ThrowIfNull(nameof(noticeManager));
this.noticeManage = noticeManager;
this.logger = logger ?? NullLogger.Instance;
}
[HttpPost("{streamerId}")]
public async Task<IActionResult> ProcessStreamsChangeNoticeAsync(string streamerId, CancellationToken cancellationToken)
{
var eventName = $"{nameof(TwitchNotificationsController)}.ProcessStreamsChangeNotice";
var telemetryContext = new EventContext(Guid.NewGuid());
return await this.logger.LogTelemetryAsync(eventName, telemetryContext, async () =>
{
TwitchStreamEvent twitchStreams = null;
telemetryContext.AddContext(nameof(streamerId), streamerId);
IActionResult result = null;
try
{
telemetryContext.AddContext(nameof(twitchStreams), twitchStreams);
if (twitchStreams == null)
{
result = this.BadRequest(twitchStreams);
}
else
{
var headerSignature = this.Request.Headers["X-Hub-Signature"].FirstOrDefault();
if (!this.noticeManage.IsAuthorized(headerSignature, twitchStreams.ToJson()))
{
result = this.BadRequest(twitchStreams);
}
else
{
var stream = new VideoGameStream()
{
StreamerId = streamerId,
};
if (twitchStreams?.Data?.Any() == true)
{
var firstStreams = twitchStreams.Data[0];
stream.Id = firstStreams.Id;
stream.StreamerId = firstStreams.UserName;
stream.StreamerMetadataId = firstStreams.UserId;
stream.CurrentViewers = firstStreams.ViewerCount;
stream.Title = firstStreams.Title;
stream.ProviderVideoGameId = firstStreams.GameId;
stream.Language = firstStreams.Language;
stream.ImageUrl = firstStreams.ThumbnailUrl;
stream.StartTime = firstStreams.StartedAt;
stream.Type = firstStreams.Type;
stream.Status = StreamStatus.Live;
}
else if (twitchStreams?.Data?.Any() == false)
{
stream.Status = StreamStatus.Offline;
}
await this.noticeManage.EnqueueVideoGameStreamAsync(stream, cancellationToken);
result = this.Ok();
}
}
}
catch (Exception exc)
{
// We should return okay also when is there internal server, but track it in our telemetry.
telemetryContext.AddError(exc);
result = this.Ok();
}
return result;
});
}
[HttpGet("{streamerId}")]
public Task<string> ReturnChallengeTokenAsync(string streamerId, CancellationToken cancellationToken)
{
var eventName = $"{nameof(TwitchNotificationsController)}.ReturnTwitchChallengeToken";
var telemetryContext = new EventContext(Guid.NewGuid());
return this.logger.LogTelemetryAsync(eventName, telemetryContext, async () =>
{
telemetryContext.AddContext(nameof(streamerId), streamerId);
this.Request.ThrowIfNull(nameof(this.Request));
string token = this.Request.Query["hub.challenge"];
telemetryContext.AddContext(nameof(token), token);
return token;
});
}
}