Post a message to slack from c# application - c#

I am trying to post a message on the #general channel and this worked when was doing it through a console app but Now I am using MVC and the message doesn't seem to get posted. Also, earlier I was using the webhook URL and now I am using the access token that I have.
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
namespace SlackClient.Controllers
{
public class SlackClient
{
private readonly Uri _uri;
private readonly Encoding _encoding = new UTF8Encoding();
public SlackClient(string urlWithAccessToken)
{
_uri = new Uri(urlWithAccessToken);
}
//Post a message using simple strings
public void PostMessage(string text, string username = null, string channel = null)
{
Payload payload = new Payload()
{
Channel = channel,
Username = username,
Text = text
};
PostMessage(payload);
}
//Post a message using a Payload object
public void PostMessage(Payload payload)
{
string payloadJson = JsonConvert.SerializeObject(payload);
using (WebClient client = new WebClient())
{
NameValueCollection data = new NameValueCollection();
data["payload"] = payloadJson;
var response = client.UploadValues(_uri, "POST", data);
//The response text is usually "ok"
string responseText = _encoding.GetString(response);
}
}
}
//This class serializes into the Json payload required by Slack Incoming WebHooks
public class Payload
{
[JsonProperty("channel")]
public string Channel { get; set; }
[JsonProperty("username")]
public string Username { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
}
}
And the other class is SlackClientTest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace SlackClient.Controllers
{
public class SlackClientTest
{
void TestPostMessage()
{
string urlWithAccessToken = "https://srishti2604.slack.com/services/hooks/incoming-webhook?token=my-tokenHere.";
SlackClient client = new SlackClient(urlWithAccessToken);
client.PostMessage(username: "Mr. Torgue",
text: "THIS IS A TEST MESSAGE! SQUEEDLYBAMBLYFEEDLYMEEDLYMOWWWWWWWW!",
channel: "#general");
}
}
}
Could someone tell me what might me wrong?
My console app looks like this
SlackClient.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace SlackProject1
{
public class SlackCient
{
private readonly Uri _webhookUrl;
private readonly HttpClient _httpClient = new HttpClient();
public SlackCient(Uri webhookUrl)
{
_webhookUrl = webhookUrl;
}
public async Task<HttpResponseMessage> SendMessageAsync(string message,
string channel = null, string username = null)
{
var payload = new
{
text = message,
channel,
username,
};
var serializedPayload = JsonConvert.SerializeObject(payload);
var response = await _httpClient.PostAsync(_webhookUrl,
new StringContent(serializedPayload, Encoding.UTF8, "application/json"));
return response;
}
}
}
And the Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SlackProject1
{
class Program
{
static void Main(string[] args)
{
Task.WaitAll(IntegrateWithSlackAsync());
}
private static async Task IntegrateWithSlackAsync()
{
var webhookUrl = new Uri("https://hooks.slack.com/services/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");
var slackClient = new SlackCient(webhookUrl);
while (true)
{
Console.Write("Type a message: ");
var message = Console.ReadLine();
var response = await slackClient.SendMessageAsync(message);
var isValid = response.IsSuccessStatusCode ? "valid" : "invalid";
Console.WriteLine($"Received {isValid} response.");
}
}
}
}

Related

Creating a script component with error in SSIS

I am trying to get data from a IT ticketing system through API in SSIS using Script Component, very new to this:
I am just starting with 1 field called Supplier, for that i have so far written below scripts:
Script Component
Created a class called ResultAPI:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SC_b15eeeff0e3544d3a882578b3eb9bbba
{
public class ResultAPI
{
public string Supplier { get; set; }
}
}
Another class called GenericResponse:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SC_b15eeeff0e3544d3a882578b3eb9bbba
{
public class GenericResponse
{
public ResultAPI[] ListData { get; set; }
}
public class ResultGen
{
public GenericResponse Result { get; set; }
}
}
Main:
public override void CreateNewOutputRows()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://***************");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var cred = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "username", "pwd")));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", cred);
string APIUrl = string.Format("https://**************");
var response = client.GetAsync(APIUrl).Result;
if (response.IsSuccessStatusCode)
{
var result = response.Content.ReadAsStringAsync().Result;
var serializer = new JavaScriptSerializer();
var data = serializer.Deserialize<ResultAPI>(result);
APIResultsBuffer.AddRow();
//APIResultsBuffer.SupplierType = data.SupplierType;
APIResultsBuffer.Supplier = data.Supplier;
//APIResultsBuffer.nextpage = data.nextpage;
//APIResultsBuffer.previouspage = data.previouspage;
//APIResultsBuffer.recordcount = data.recordcount;
//APIResultsBuffer.HREF = data.HREF;
}
}
}
When I execute the package, i get the attached error:
Error
Not sure exactly where this error is.
Hoping to download this file in SQL Server table

How to populate a text box with data from another .cs files' class

Hi im so sorry for the generic question i am really new to C#. I am using a previous colleagues code but im looking to populate a textbox on a form with the data from a class.
This is the code for the thing i want to reference
public string GetToken(string username, string password) {
var request = SvcRequest
.Get(_url)
.WithAuthentication(this.CreateHeader(username, password))
.ReturningXml();
var response = _svc.Send(request);
return this.ExtractToken(response.Body);
I need to populate my text box with this.ExtractToken(response.Body). How do i do this?
Thanks a lot!
Code for main .cs file
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Configuration;
using System.IO;
namespace EbsWebServices
{
internal sealed class EbsAuthManager
{
private readonly string _url;
private readonly SvcUtility _svc = new SvcUtility();
public EbsAuthManager()
{
_url = "URL_HERE";
if(!_url.EndsWith("/"))
{
_url += "/";
}
_url += "Rest/Authentication";
}
public string GetToken(string username, string password)
{
var request = SvcRequest
.Get(_url)
.WithAuthentication(this.CreateHeader(username, password))
.ReturningXml();
var response = _svc.Send(request);
return this.ExtractToken(response.Body);
}
private string CreateHeader(string username, string password)
{
var credentials = String.Format("{0}:{1}", username, password);
var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials));
return String.Format("Basic {0}", encoded);
}
private string ExtractToken (string xml)
{
var doc = new XmlDocument();
doc.LoadXml(xml);
var navigator = doc.DocumentElement.CreateNavigator();
var success = navigator
.SelectChildren("Success", string.Empty)
.Cast<XPathNavigator>()
.First();
var token = navigator
.SelectChildren("Token", string.Empty)
.Cast<XPathNavigator>()
.First();
return Convert.ToBoolean(success.InnerXml)
? token.InnerXml
: null;
}
}
}
Code for my form
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using EbsWebServices;
namespace EBSGetTokenForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}

HTTP status code 500 when querying an API from a C# program, except the API works

I need to use another company's API to query data using POST requests.
The API works (= I receive all the data with no errors) when I query it from the swagger website using the UI, but when I do it from my C# program I get a 500 Internal Server Error.
Where should I be looking for the problem ? Is there a way to get a more detailed error message ?
Edit (added code) :
using System;
using System.Data.Entity;
using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Infrastructure.Interception;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.Serialization;
using System.Text;
namespace credex_distribution_offers_to_interfaces
{
class Program
{
private const string jsonMediaType = "application/json";
static void Main()
{
FetchJSONAndInsertToDB();
}
private static bool FetchJSONAndInsertToDB()
{
var baseServiceUrl = new Uri("a valid url");
Root rootObject;
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(jsonMediaType));
try
{
string token = FetchToken(httpClient, baseServiceUrl);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token);
}
catch (Exception e)
{
return false;
}
try
{
rootObject = FetchDistributionLookupOffers(httpClient, baseServiceUrl, 29612, 29613, 29614, 29617, 29621);
}
catch (Exception e)
{
return false;
}
}
// database related stuff...
// ...
return true;
}
[DataContract]
public class MortgageForDistributionLookupInputDto
{
public int[] OfferNumbers { get; set; }
}
private static Root FetchDistributionLookupOffers(HttpClient aHttpClient, Uri aBaseServiceUrl, params int[] aOfferNumbers)
{
var input = new MortgageForDistributionLookupInputDto()
{
OfferNumbers = aOfferNumbers
};
var lookup = aHttpClient.PostAsync(new Uri(aBaseServiceUrl, "v1/MortgageDetails/InvestorLookupOffers"), PayloadFor(input)).Result;
if (lookup.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Fetching investor lookup offers failed with HTTP status code '" + lookup.StatusCode + "' : " + lookup.ReasonPhrase + "}");
}
var obj = ValueFor<Root>(lookup.Content);
return obj;
}
private static HttpContent PayloadFor<T>(T aObject)
{
return new StringContent(aObject.SerializeJson(), Encoding.UTF8, jsonMediaType);
}
private static T ValueFor<T>(HttpContent aHttpContent)
{
//var content = aHttpContent.ReadAsStringAsync();
return aHttpContent.ReadAsStreamAsync().Result.DeSerializeJson<T>();
}
private static string FetchToken(HttpClient aHttpClient, Uri aBaseServiceUrl)
{
var login = new LoginRequest()
{
UserName = "some user name",
Password = "some password"
};
var authResult = aHttpClient.PostAsync(new Uri(aBaseServiceUrl, "api/Login"), PayloadFor(login)).Result;
if (authResult.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Fetching authentication token failed. Reason : " + authResult.StatusCode + " -> " + authResult.ReasonPhrase);
}
return authResult.Content.ReadAsStringAsync().Result.Trim('"');
}
}
}

GET, POST to a rest api

Hi i have a Api that i want to use to collect data from a backend that spits out json i need to get this via C# Application and it's http functionalities. My question is should i use a rest api and setup an async thread that downloads the data and then use the data as i want to from there or should i somehow use something close to a Web Api i have an authentication that is required to exist in a header. This has given me some hedaches because i keep on being split by what to use for what. I mean i need to do a Httprequest with a header. this i later on need to use for posting to another database. but the user of the program should not have to see the data itself. i have two examples that i have done but i don't know with what i should continue? this is my two examples in code...
Example 1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
namespace Plugin
{
public enum HttpVerb
{
GET,
POST,
PUT,
DELETE
}
class Api
{
private HttpVerb HttpMethod { get; set; }
public Api()
{}
public string startDownload()
{
return (Download("sending token"));
}
private string Download(string token)
{
string strResponseValue = string.Empty;
string finnishedOutput = string.Empty;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("Url");
request.Headers.Add("Authorization", "Bearer " + token);
request.Method = HttpMethod.ToString();
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
strResponseValue = reader.ReadToEnd();
}
return strResponseValue;
}
catch (WebException e)
{
HttpWebResponse httpResponse = (HttpWebResponse)e.Response;
if ((int)httpResponse.StatusCode == 401)
{}
int errorCodeInt;
string errorCode;
errorCodeInt = (int)httpResponse.StatusCode;
errorCode = errorCodeInt.ToString();
return errorCode;
}
}
}
}
Example 2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace TestAPi
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Api.InitializeClient("");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
namespace TestAPi
{
public class Api
{
private static HttpClient ApiClient { get; set;}
private string url { get; set;}
public static void InitializeClient(string token)
{
ApiClient = new HttpClient();
ApiClient.BaseAddress = new Uri("your url");
ApiClient.DefaultRequestHeaders.Accept.Clear();
ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("Bearer Authentication"));
}
public async Task<Data> LoadData()
{
url = ApiClient.BaseAddress.ToString();
using (HttpResponseMessage response = await ApiClient.GetAsync(url))
{
if (response.IsSuccessStatusCode)
{
Data data = await response.Content.ReadAsAsync<data>();
return data;
}
else
{
throw new Exception(response.ReasonPhrase);
}
}
}
}
}

C# Throwing unable to resolve controller error

I'm fairly new to .NET and c# and I'm working on a POC where I've run into an issue when a controller throws the error
System.InvalidOperation Exception {"Unable to resolve controller: TenantController"}
The Inner exception details are
No default Instance is registered and cannot be automatically determined for type 'GICS.Web.Managers.Interfaces.ITenantManager'
There is no configuration specified for GICS.Web.Managers.Interfaces.ITenantManager
1.) new TenantController(Default of ITenantManager, Default of IRemedyService)
2.) GICS.Web.Controllers.Api.TenantController
3.) Instance of GICS.Web.Controllers.Api.TenantController
4.) Container.GetInstance(GICS.Web.Controllers.Api.TenantController)
The TenantController looks as follows:
using System.Web.Mvc;
using GICS.Web.Controllers.Api.Abstracts;
using GICS.Web.Managers.Interfaces;
using GICS.Web.Services.Interfaces;
using System.Collections.Generic;
using GICS.Web.ViewModels.Tenant;
using GICS.Web.Models.Tenant;
namespace GICS.Web.Controllers.Api
{
[RoutePrefix("api/tenant")]
public class TenantController : BaseApiController
{
private readonly ITenantManager _tenantsManager;
private readonly IRemedyService _remedyService;
private string token;
public TenantController(ITenantManager tenantsManager, IRemedyService remedyService)
{
_tenantsManager = tenantsManager;
_remedyService = remedyService;
token = null;
}
[HttpGet, Route("{groupId}/{userName}")]
public JsonResult getTenants(string groupId, string UserName)
{
getToken(UserName);
JsonResult result = Json(null);
if (token != null)
{
var tenants = _tenantsManager.GetTenants(token, groupId);
List<TenantViewModel> tenantViewModelList = new List<TenantViewModel>();
foreach (Values x in tenants)
{
TenantViewModel model = new TenantViewModel(x, groupId);
tenantViewModelList.Add(model);
}
result = Json(tenantViewModelList);
}
return result;
}
}
The TenantManager interface is as follows:
using System.Collections.Generic;
using GICS.Web.Models.Tenant;
namespace GICS.Web.Managers.Interfaces
{
public interface ITenantManager
{
IEnumerable<Values> GetTenants(string token, string groupId);
}
}
And the Manager implementation is:
using GICS.Web.Managers.Abstracts;
using GICS.Web.Managers.Interfaces;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Configuration;
using System.Net;
using GICS.Web.Models.Tenant;
namespace GICS.Web.Managers
{
public class TentantManager : ManagerBase, ITenantManager
{
public IEnumerable<Models.Tenant.Values> GetTenants(string token, string groupId)
{
Tenant restEntries = null;
List<Models.Tenant.Values> tenantList = new List<Models.Tenant.Values>();
using (WebClient client = new WebClient())
{
client.Headers[HttpRequestHeader.Authorization] = token;
var baseURL = ConfigurationManager.AppSettings["RemedyBaseUrl"];
var apiPath = ConfigurationManager.AppSettings["RemedyAPIPath"];
string getURL = baseURL + apiPath + "ESN%3AAST%3ALogSysComp%5FASTPeople" + "?q=?q=%27PeopleGroup%20Form%20Entry%20ID%27%20%3D%20%22" + groupId + "%22&fields=values(Name)";
string getResponse = client.DownloadString(getURL);
restEntries = JsonConvert.DeserializeObject<Tenant>(getResponse);
foreach (Models.Tenant.Entry x in restEntries.entries)
{
tenantList.Add(x.values);
}
}
return tenantList;
}
}
}
I have other controllers in the project that follow the same approach and all are working except for this one. Anyone spot where I am going wrong here?
Thanks in advance.

Categories