StreamerBot already has the built-in Fetch URL sub-action to immediately send simple HTTP GET requests directly from the actions UI.
Sometimes, however, you will find a situation where you need to send data via POST, PUT or generally any other request type that is not GET.
In this case, you will need to implement your own request handling in a C# code module using the HttpClient class.
Execute C# Code block for a single instance of needing to send a request, or a more persistent C# module with different actions triggering different Execute C# Method sub-actions - you need to know how use this feature in your normal action flow.using System;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class CPHInline {
// You can set the timeout to any length you need
private static readonly HttpClient _httpClient = new HttpClient{Timeout = TimeSpan.FromSeconds(30)};
public void Init() {
// Ensure we are working with a clean slate
_httpClient.DefaultRequestHeaders.Clear();
}
public void Dispose() {
// Free up allocations
_httpClient.Dispose();
}
public bool Execute() {
// ...
return true;
}
}
using statement or creating a new one within the executed function may be a common occurence, it is heavily discouraged to do so. Read More%userName% and %userId% pair (from common triggers) as PUT request to our fictional logging website.public bool Execute() {
// Get the arguments - or abort if it does not exist
if(!CPH.TryGetArg("userName", out string userName)) return false;
if(!CPH.TryGetArg("userId", out string userId)) return false;
// Build a wrapper object as payload
var data = new {
id = userId,
name = userName
};
// Serialize JSON
string json = JsonConvert.SerializeObject(data);
// Create web request payload
var payload = new StringContent(json, Encoding.UTF8, "application/json");
// Finally, send request
HttpResponseMessage response = _httpClient.PutAsync("https://my-logging-server.com", payload).GetAwaiter().GetResult();
// Do with the response what you need to.
// ...
return true;
}
GetAsync(), PutAsync(), PostAsync() or DeleteAsync().PATCH request type may not be available in the .net versions used by StreamerBot. In this case, you need a workaround. // ...
// Finally, send the request
var request = new HttpRequestMessage(new HttpMethod("PATCH"), "https://my-logging-server.com"){
Content = payload
};
HttpResponseMessage response = _httpClient.SendAsync(request).GetAwaiter().GetResult();
// ...
SendAsync method and building your own HttpRequestMessage.public bool Execute() {
// Making a call to the Twitch API to get all currently live streams
string token = CPH.TwitchOAuthToken;
string clientId = CPH.TwitchClientId;
// Clear our old headers
_httpClient.DefaultRequestHeaders.Clear();
// Now set your Twitch API authorization
_httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer "+token);
_httpClient.DefaultRequestHeaders.Add("Client-Id", clientId);
// Send your request
HttpResponseMessage response = _httpClient.GetAsync("https://api.twitch.tv/helix/streams").GetAwaiter().GetResult();
// Do with the response what you need to.
// ...
return true;
}
public bool Execute() {
// ...all your data preparation
HttpResponseMessage response = _httpClient.GetAsync("https://api.twitch.tv/helix/streams").GetAwaiter().GetResult();
// Check if our request was successful
try {
if(!response.IsSuccessStatusCode) {
// It was not. Abort.
CPH.LogError($"{response.StatusCode} - {response.ReasonPhrase}");
return false;
}
// Get the response data
string content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
// Usually, data is JSON. So you would decode it now.
JObject parsed = JObject.Parse(content);
// And then do with the data whatever you need.
// ...
return true;
} catch (Exception e) {
// Something went wrong
CPH.LogError(e.Message);
return false;
}
}
Wrapping sensitive parts of code, especially when using web requests, into try catch blocks is good practice and prevents potential unexpected bigger issues you do not anticipate.
Of course, proper error handling is always better, but not always necessary.