I've created a bot with Microsoft bot framework for Messenger.
All work great. i can recieve and send message to messanger but in messanger mobile push notification not work. I omit the property notification_type because facebook guide say
notification_type is optional; by default, messages will be REGULAR
push notification type
It is a Framework bug?
My code:
ConnectorClient connector = new ConnectorClient(new Uri(servUri), microsoftAppId: appId, microsoftAppPassword: pass);
ResourceResponse conversationId = await connector.Conversations.CreateDirectConversationAsync(botAccount, userAccount);
IMessageActivity activity = Activity.CreateMessageActivity();
activity.Id = conversationId.Id;
activity.Type = ActivityTypes.Message;
activity.From = botAccount;
activity.Conversation = conversation;
activity.Recipient = userAccount;
activity.Text = "hello";
await connector.Conversations.SendToConversationAsync((Activity)activity);
I've used activity.ChannelData and all work good
I post my solution, can be useful to someone
Add the attachment to the activity:
activity.ChannelData = new FacebookChannelData()
{
Attachment = GetFacebookAttachment()
};
create the attachment:
private static FacebookAttachment GetFacebookAttachment()
{
return new FacebookAttachment()
{
Payload = new GenericTemplate
{
Elements = new[] {
new TemplateElements(){
Title = "my title",
ItemUrl = "https://example.com",
ImageUrl = "https://example.com/test.jpg",
Subtitle = "subtitle",
Buttons = new[] {
new TemplateButtons() {
Type = "web_url",
Url = "https://example.com",
Title = "button title"
}
}
}
}
}
};
}
and then the classes:
public class FacebookChannelData
{
public FacebookChannelData() {
this.NotificationType = "REGULAR";
}
[JsonProperty("notification_type")]
public string NotificationType { get; set; }
[JsonProperty("attachment")]
public FacebookAttachment Attachment { get; internal set; }
}
public class FacebookAttachment
{
public FacebookAttachment()
{
this.Type = "template";
}
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("payload")]
public dynamic Payload { get; set; }
public override string ToString()
{
return this.Payload.ToString();
}
}
public class GenericTemplate
{
public GenericTemplate()
{
this.TemplateType = "generic";
}
[JsonProperty("template_type")]
public string TemplateType { get; set; }
[JsonProperty("elements")]
public TemplateElements[] Elements { get; set; }
}
public class TemplateElements
{
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("item_url")]
public string ItemUrl { get; set; }
[JsonProperty("image_url")]
public string ImageUrl { get; set; }
[JsonProperty("subtitle")]
public string Subtitle { get; set; }
[JsonProperty("buttons")]
public TemplateButtons[] Buttons { get; set; }
}
public class TemplateButtons
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("payload")]
public string Payload { get; set; }
}
notification_type IS optional - but only in the context of when you're actually specifying a ChannelData on your activity.
So just add (given that you're using Newtonsoft.Json.Linq;)
activity.ChannelData = JObject.FromObject(new
{
notification_type = "REGULAR"
});
and you'll get your notification, provided that your client app has not disabled notifications.
Related
I am trying to call the Azure DevOps Release Api to create a release from c# code, but it is giving me 400 Bad request error.
I am using the example in the following link by Microsoft
https://learn.microsoft.com/en-us/rest/api/azure/devops/release/releases/create?view=azure-devops-rest-5.1
Here is my code .....
My application is a small console app.
namespace DevOpsReleasePipelineTest
{
public class InstanceReference
{
public string id { get; set; }
public IList<string> name { get; set; }
public string definitionId { get; set; }
}
public class Artifacts
{
public string alias { get; set; }
public InstanceReference instanceReference { get; set; }
}
public class Application
{
public int definitionId { get; set; }
public string description { get; set; }
public IList<Artifacts> artifacts { get; set; }
public bool isDraft { get; set; }
public string reason { get; set; }
public IList<object> manualEnvironments { get; set; }
}
}
private static Application GetPayLoad()
{
InstanceReference instanceReference = new InstanceReference();
instanceReference.id = "7874";
instanceReference.name = null;
instanceReference.definitionId = "7874";
List<Artifacts> artifacts = new List<Artifacts>();
Artifacts artifacts1 = new Artifacts();
artifacts1.alias = "Mobility-Dev";
artifacts1.instanceReference = instanceReference;
artifacts.Add(artifacts1);
Application application = new Application();
application.definitionId = 4;
application.description = "Creating Sample release";
application.isDraft = false;
application.reason = "test";
application.manualEnvironments = null;
application.artifacts = artifacts;
return application;
}
public static async Task<HttpResponseMessage> PostRelease()
{
var personalaccesstoken = "djhghgtydfhfgdyuftyftdsf";
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", personalaccesstoken))));
var payLoad = GetPayLoad();
HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(payLoad),
Encoding.UTF8, "application/json");
Task <HttpResponseMessage> response = client.PostAsync("https://xxx-
devops.vsrm.visualstudio.com/DemoProj/_apis/release/releases?api-version=5.1", httpContent);
var result = await response;
return result;
}
Your code does not work on my side and I`ve checked the url. There is some problem %)
Try to use the url format from documentation:
POST https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/releases?api-version=5.1
Additionally, you can check the error in your response:
var response = client.PostAsync("https://vsrm.dev.azure.com/<org>/<team_project>/_apis/release/releases?api-version=5.1", httpContent).Result;
if (response.StatusCode == System.Net.HttpStatusCode.BadRequest)
{
string message = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(message);
}
My example:
I'm having problems resolving this error message. I've looked at some other answers on here and changed some things but I still receive this error:
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Clocker.Models.PeopleLocationForUser]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
This is my class:
namespace Clocker.Models
{
public class PeopleLocationForUser
{
string locationPeople { get; set; }
public users users { get; set; }
}
public class users
{
public int EB_Counter { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int TATokenValue { get; set; }
}
}
This is the method that errors on the deserialize line:
public static async Task<PeopleLocationForUser> GetPeopleLocationForUser(string UserName, int LocationId)
{
Uri uri = new Uri(URL + "GetPeopleLocationForUser" + "?username=" + UserName + "&locationid=" + LocationId);
HttpClient myClient = new HttpClient();
var response = await myClient.GetAsync(uri);
var content = await response.Content.ReadAsStringAsync();
var test = JsonConvert.DeserializeObject<List<PeopleLocationForUser>>(content);
//return something when it's working
return null;
}
This is the start of the Json data:
{"result":true,"locationPeople":[{"EB_Counter":101,"FirstName":"RSS","LastName":"13.11.1","TATokenValue":"TS_101_1_RSS_SWIPE"},{"EB_Counter":102,"FirstName":"RSS","LastName":"13.11.2","TATokenValue":"TS_102_1_RSS_SWIPE"},{"EB_Counter":93,"FirstName":"RSS","LastName":"13.7.1","TATokenValue":"TS_93_1_RSS_SWIPE"},{"EB_Counter":94,"FirstName":"RSS","LastName":"13.7.10","TATokenValue":"TS_94_1_RSS_SWIPE"},{"EB_Counter":95,"FirstName":"RSS","LastName":"13.8.2","TATokenValue":"TS_95_1_RSS_SWIPE"},{"EB_Counter":99,"FirstName":"RSS","LastName":"13.9.2","TATokenValue":"TS_99_1_RSS_SWIPE"},
This is what my Json data looks like when it arrives:
I hope you can help. The end result is that I'm trying to get this data into a list so I can use it in a Xamarin ListView.
You are receiving list and in the class you are expecting just one instance of user, this is how the class should be:
public class LocationPeople
{
public int EB_Counter { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string TATokenValue { get; set; }
}
public class RootObject
{
public bool result { get; set; }
public List<LocationPeople> locationPeople { get; set; }
}
var test = JsonConvert.DeserializeObject<RootObject>(content);
I'm using mandrill for managing email service, and it's features of inbound email webhook (HTTP POST) for retrieving the attached image.
Details of Mandrill inbound webhook.
http://help.mandrill.com/forums/21092258-Inbound-Email-Basics
I've tried to get the HTTP inbound webhook but unable to deserialize it into json, and unable to retrieve the attached image.
I've used class and method from following github link.
https://github.com/martydill/mandrill-inbound-classes
after fetching the attached image I need to upload it to imgur website using API,
Am able to upload images to imgur website but i'm facing problem while retrieving attachment from inbound webhook from mandrill.
kindly help me as soon as possible.
I've gone through the class as you stated in github and I've added one more field in the class to get the attachment value from the email.
here is the required class for mandrill webhook.
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Mandrill
{
public class MailEvent
{
[JsonProperty(PropertyName = "ts")]
public string TimeStamp { get; set; }
[JsonProperty(PropertyName = "event")]
public string Event { get; set; }
[JsonProperty(PropertyName = "msg")]
public Message Msg { get; set; }
}
public class Message
{
[JsonProperty(PropertyName = "raw_msg")]
public string RawMessage { get; set; }
[JsonProperty(PropertyName = "headers")]
public Header Header { get; set; }
[JsonProperty(PropertyName = "text")]
public string Text { get; set; }
[JsonProperty(PropertyName = "html")]
public string Html { get; set; }
[JsonProperty(PropertyName = "from_email")]
public string FromEmail { get; set; }
[JsonProperty(PropertyName = "from_name")]
public string FromName { get; set; }
// Not sure why Mandrill sends an array of arrays here...
[JsonProperty(PropertyName = "to")]
public string[][] To { get; set; }
[JsonProperty(PropertyName = "email")]
public string Email { get; set; }
[JsonProperty(PropertyName = "subject")]
public string Subject { get; set; }
[JsonProperty(PropertyName = "tags")]
public string[] Tags { get; set; }
[JsonProperty(PropertyName = "sender")]
public string Sender { get; set; }
[JsonProperty(PropertyName = "dkim")]
public DKIM DKIM { get; set; }
[JsonProperty(PropertyName = "spf")]
public SPF SPF { get; set; }
[JsonProperty(PropertyName = "spam_report")]
public SpamReport SpamReport { get; set; }
//[JsonProperty(PropertyName = "attachments")]
//public attachments attachments { get; set; }
[JsonProperty(PropertyName = "attachments")]
public IDictionary<string, IDictionary<string,string>> attachments { get; set; }
}
[JsonDictionary()]
public class Header : Dictionary<string, object>
{
// Need to find a nicer way of doing this... Dictionary<string, object> is kinda dumb
}
public class attachments
{
[JsonProperty(PropertyName = "name ")]
public string name { get; set; }
[JsonProperty(PropertyName = "type ")]
public string type { get; set; }
[JsonProperty(PropertyName = "content ")]
public string content { get; set; }
[JsonProperty(PropertyName = "base64 ")]
public bool base64 { get; set; }
}
public class SpamReport
{
[JsonProperty(PropertyName = "score")]
public decimal Score { get; set; }
[JsonProperty(PropertyName = "matched_rules")]
public SpamRule[] MatchedRules { get; set; }
}
public class SpamRule
{
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "score")]
public decimal Score { get; set; }
[JsonProperty(PropertyName = "description")]
public string Description { get; set; }
}
public class DKIM
{
[JsonProperty(PropertyName = "signed")]
public bool Signed { get; set; }
[JsonProperty(PropertyName = "valid")]
public bool Valid { get; set; }
}
public class SPF
{
[JsonProperty(PropertyName = "result")]
public string Result { get; set; }
[JsonProperty(PropertyName = "detail")]
public string Detail { get; set; }
}
}
and you have to call the imgur api like this.
[HttpPost]
[ValidateInput(false)]
public ActionResult past_mandrill(FormCollection fc)
{
string json = fc["mandrill_events"];
//SqlConnection con = new SqlConnection(WebConfigurationManager.AppSettings[0]);
var events = JsonConvert.DeserializeObject<IEnumerable<Mandrill.MailEvent>>(json);
foreach (var mailEvent in events)
{
//Label2.Text = Label2.Text + mailEvent.Msg.To[0][0] + "<br>";
try
{
foreach (KeyValuePair<string, IDictionary<string, string>> attch in mailEvent.Msg.attachments)
{
//Label2.Text = Label2.Text + attch.Key + "<br>";
byte[] temp;
string albumid = "zBBCDbRcNhE493I"; //use your own album id where you want to store the image.
foreach (KeyValuePair<string, string> attchcnt in attch.Value)
{
//Label2.Text = Label2.Text + attchcnt.Key + " " + attchcnt.Value + "<br>";
if (attchcnt.Key.Equals("content"))
{
using (var w = new WebClient())
{
string base64String = "";
base64String = attchcnt.Value.ToString();
var values = new NameValueCollection
{
{"image", base64String},
{"album", albumid}
};
w.Headers.Add("Authorization", "Client-ID dac37a6b08b4974"); // user your own client-id of imgur website
byte[] response = w.UploadValues("https://api.imgur.com/3/upload.xml", values);
temp = response;
}
}
}
}
}
catch (Exception e)
{
}
//Label2.Text = mailEvent.Msg.attachments.Values.ToString();
}
return new HttpStatusCodeResult((int)HttpStatusCode.OK);
}
I'm developing WP8 app and i'm new to it.. i want to know my post method is correct or not because i'm unable to post my data in the url it produces an exception..
My Class Contents...
public class Register
{
public int id { get; set; }
public string password_reset_hash { get; set; }
public string temp_password { get; set; }
public bool remember_me { get; set; }
public string activation_hash { get; set; }
public string ip_address { get; set; }
public bool status { get; set; }
public bool activated { get; set; }
public string permissions { get; set; }
public DateTime last_login { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
public string email { get; set; }
public string password { get; set; }
public string conformpassword { get; set; }
public string username { get; set; }
}
here is my code..
public void btn_register_click(object sender, RoutedEventArgs e)
{
string url="myurl";
Register res=new Register();// my class
res.email = txt_email.Text;
res.password = txt_password.Text;
res.conformpassword = txt_conf_psswrd.Text;
res.username = txt_username.Text;
res.created_at = DateTime.Now;
res.last_login = DateTime.Now;
res.updated_at = DateTime.Now;
res.status = true;
json = JsonConvert.SerializeObject(res);
WebClient wc = new WebClient();
var URI = new Uri(url);
wc.Headers["Content-Type"] = "application/json";
wc.Headers["ACCEPT"] = "application/json";
wc.UploadStringCompleted += new UploadStringCompletedEventHandler(wc_UploadStringCompleted);
wc.UploadStringAsync(URI, "POST", json);
}
private void wc_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
try
{
MessageBox.Show(e.Result);
//e.result fetches you the response against your POST request.
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString()); //i'm getting error here..
}
}
My Screen Design..
Error is..
Thanks
It looks to me like there is a problem with the URI you are using. The error message you posted shows the server returning a "Not found" header. Maybe it just is not quite correct? I did not see the exact URI in the code you posted. string url="myurl"; does not look like this is the url you want to use.
That's also why you can't access the response stream without an exception with this line: MessageBox.Show(e.Result);. There just is no valid response. This is documented here: http://msdn.microsoft.com/de-de/library/system.net.uploadstringcompletedeventargs.result%28v=vs.110%29.aspx.
You can determine if such an error occurred by checking the Error property of UploadStringCompletedEventArgs (http://msdn.microsoft.com/de-de/library/system.net.uploadstringcompletedeventargs%28v=vs.110%29.aspx).
I am trying to come up with an edit action. See below for what i have so far.
ViewModel:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace GlobalUnitedSC.WebUI.Models
{
public sealed class CreateMensPlayerViewModel
{
//Player profile starts here
[HiddenInput(DisplayValue=false)]
public int MensTeamId { get; set; }
[HiddenInput(DisplayValue = false)]
public int PlayerId { get; set; }
[Required]
public string Name { get; set; }
[DataType(DataType.Date)]
public DateTime? BirthDate { get; set; }
[Required]
public string Position { get; set; }
public int ShirtNumber { get; set; }
[DataType(DataType.Date)]
public DateTime? Joined { get; set; }
public string Country { get; set; }
[DataType(DataType.MultilineText)]
public string Description { get; set; }
public byte[] ImageData { get; set; }
[HiddenInput(DisplayValue = false)]
public string ImageMimeType { get; set; }
[DataType(DataType.EmailAddress)]
public string EmailAddress { get; set; }
[DataType(DataType.PhoneNumber)]
public string PhoneNumber { get; set; }
//Player Statistics starts here
public int Games { get; set; }
public int Goals { get; set; }
public int Assists { get; set; }
public int TotalShots { get; set; }
public int ShotsOnGoal { get; set; }
public int FoulsDrawn { get; set; }
public int FoulsCommitted { get; set; }
public int Saves { get; set; }
public int BlueCards { get; set; }
public int YellowCards { get; set; }
public int RedCards { get; set; }
}
}
Create Actions:
[HttpGet]
public ActionResult Create(int mensTeamId)
{
new CreateMensPlayerViewModel {MensTeamId = mensTeamId};
return View();
}
[HttpPost]
public ActionResult Create(CreateMensPlayerViewModel viewModel, HttpPostedFileBase image)
{
if (ModelState.IsValid)
{
var mensTeam = _dataSource.MensTeams.Single(t => t.Id == viewModel.MensTeamId);
var mensPlayer = new MensPlayer
{
Name = viewModel.Name,
BirthDate = viewModel.BirthDate,
Position = viewModel.Position,
ShirtNumber = viewModel.ShirtNumber,
Joined = viewModel.Joined,
Country = viewModel.Country,
Description = viewModel.Description,
EmailAddress = viewModel.EmailAddress,
PhoneNumber = viewModel.PhoneNumber,
Games = viewModel.Games,
Goals = viewModel.Goals,
Assists = viewModel.Assists,
TotalShots = viewModel.TotalShots,
ShotsOnGoal = viewModel.ShotsOnGoal,
FoulsDrawn = viewModel.FoulsDrawn,
FoulsCommitted = viewModel.FoulsCommitted,
Saves = viewModel.Saves,
BlueCards = viewModel.BlueCards,
YellowCards = viewModel.YellowCards,
RedCards = viewModel.RedCards
};
mensTeam.MensPlayers.Add(mensPlayer);
_dataSource.Save();
TempData["message"] = string.Format("{0} has been saved", mensPlayer.Name);
return RedirectToAction("detail", "MensTeam", new {id = viewModel.MensTeamId});
}
return View(viewModel);
}
HttpGet Edit Action
[HttpGet]
public ActionResult Edit (int id)
{
var mensPlayer = _dataSource.MensPlayers.FirstOrDefault(p => p.Id == id);
return View(mensPlayer);
}
Now could anyone please help me with the HttpPost Edit action, preferably one based on the model class mentioned above?
I was hoping it has something to do with the line below, if this creates a new player, what could i write to edit that player?
var mensPlayer = new MensPlayer {}
Since it's a post the method is kind of equal to your create-method. You will receive a MensPlayer as a parameter.
Than you check if the Model is valid (validation etc.) and flag the entry as modified and save the changes.
[HttpPost]
public ActionResult Edit(MyModel myModel)
{
if (ModelState.IsValid)
{
DbContext.Entry(myModel).State = EntityState.Modified;
DbContext.SaveChanges();
return RedirectToAction("Index");
}
return View(myModel);
}
DBContext
public class ModelContext : DbContext
{
public DbSet<MyModel> MyModelSet{ get; set; }
}
More info about DBContext.
With help of Slauma in the comments in the repost or extension of this question at:
Repost/Extension
This is what he suggested i do and it works.
Add to IDataSource Interface:
void Update(MensPlayer mensPlayer);
Update Implemented in Db class:
void IDataSource.Update(MensPlayer mensPlayer)
{
Entry(mensPlayer).State = EntityState.Modified;
}
Edit Action:
[HttpPost]
public ActionResult Edit(MensPlayer mensPlayer)
{
if (ModelState.IsValid)
{
//Save Player
_dataSource.Update(mensPlayer);
_dataSource.Save();
TempData["message"] = string.Format("{0} has been saved", mensPlayer.Name);
return RedirectToAction("Detail", "MensPlayer", new {id = mensPlayer.Id});
}
return View(mensPlayer);
}
And Just like that all works fine, although i was under the assumption that i would implement Update to the whole DbSet like i did with Save.