I am very new to bigbluebutton. I successfully installed bbb on Ubuntu server and enabled API demo. It is working absolutely fine. I am calling API from c# and it is working fine too. I am creating a meeting like below which is working fine.
public CreateMeetingResponse CreateMeeting(CreateMeetingRequest request)
{
var qb = new QueryStringBuilder
{
{"meetingID", request.MeetingID},
{"name", request.Name},
{"attendeePW", request.AttendeePW},
{"moderatorPW", request.ModeratorPW},
{"record", request.Record.ToString()},
{"allowStartStopRecording", request.AllowStartStopRecording.ToString()},
{"autoStartRecording", request.AutoStartRecording.ToString()},
{"voiceBridge", request.VoiceBridge.ToString()},
{"welcome", request.Welcome},
{"recordingmarks", "true"},
{"logoutURL", request.LogoutURL}
};
qb.Add("checksum", GenerateChecksum("create", qb.ToString()));
var createRequest = new RestRequest($"/api/create?{qb}", Method.GET);
var response = Client.Execute<CreateMeetingResponse>(createRequest).Data;
return response;
}
After creating the meeting, i am trying to join the meeting like as below.
public JoinMeetingResponse JoinMeeting(JoinMeetingRequest request)
{
var qb = new QueryStringBuilder
{
{"meetingID", request.MeetingID},
{"fullName", request.FullName},
{"userId", request.UserID},
{"password", request.Password},
{"joinViaHtml5","true" },
{"redirect","false" },
{"guest","true" }
};
qb.Add("checksum", GenerateChecksum("join", qb.ToString()));
var joinRequest = new RestRequest($"/api/join?{qb}", Method.GET);
var joinResponse = Client.Execute<JoinMeetingResponse>(joinRequest);
return new JoinMeetingResponse();
}
The response from bbb server API is "SUCCESS" and message is "You have successfully joined". But when i try to open meeting or join with URL it shows UNAUTHORIZED 401. "Authentication failed due to missing credentials."
I open browser console and it shows:
[18:07:28:0290] DEBUG: clientLogger: Initial connection status change. status: connecting, connected: false https://bbb.adorasoft.net/html5client/7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:121:1031295
7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:9 [18:07:28:0970] DEBUG: clientLogger: Initial connection status change. status: connected, connected: true https://bbb.adorasoft.net/html5client/7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:121:1031295
7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:9 [18:07:28:0971] INFO: clientLogger: Connection to Meteor took 0.68s https://bbb.adorasoft.net/html5client/7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:121:1031466
7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:9 [18:07:29:0142] ERROR: clientLogger: User faced an error on main.joinRouteHandler. g.fetchToken (https://bbb.adorasoft.net/html5client/7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:121:1033747)
7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:9 [18:07:29:0144] ERROR: clientLogger: Encountered error while trying to authenticate t (https://bbb.adorasoft.net/html5client/7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:121:999188)
7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:9 [18:07:29:0146] ERROR: clientLogger: User could not log in HTML5, hit 401 z.renderByState (https://bbb.adorasoft.net/html5client/7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:121:1206397)
7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:9 [18:07:29:0327] ERROR: clientLogger: User could not log in HTML5, hit 401 z.renderByState (https://bbb.adorasoft.net/html5client/7df6acf6cb0f651dba4e71b3adac0efd23889793.js?meteor_js_resource=true:121:1206397)
What i am doing wrong?
So, after investing enough time i got the solution. There was no problem in bigBlueButton. The problem was that "Join" API request from server side.
"The Join request should be made from the client side/Browser"
So what I had to do is instead of passing XML response, I just need to pass the whole Big blue button Join URL with Checksum and redirect = true
so whenever someone want to join they will redirect to the meeting directly.
Related
I've implemented the HomeGraph API with the help of the package Google.Apis.HomeGraphService.v1 (1.50.0.2260)
It seems to work fine as well, the ReportStateAndNotification function works fine on the query, execute, and some sync requests.
But when I add a new device to my system through our app and a SYNC request is sent to Google and comes in our backend, the HomeGraph API will return an exception when sending this sync request..
-> The sync request does not throw an exception when I modify a device name in our app. It only occurs when new devices are added.
I've searched through google and multiple StackOverflow posts.. But I'm probably missing something. Most posts say check the API key etc but then the ReportStateAndNotification function should always fail, not only when the sync request comes from Google to our backend.
Could anyone point me in the right direction?
Function that is used for sync requests:
public static void Send(Dictionary<string, object> deviceStateList, string requestId, string googleCustomerId)
{
string deviceIdList = String.Format("({0})", string.Join(", ", deviceStateList.Keys));
try
{
var jsonFilePath = _appSettingsRetriever.PrivateGoogleAuthenticationFile;
string scope = "https://www.googleapis.com/auth/homegraph";
using (var stream = new FileStream(jsonFilePath, FileMode.Open, FileAccess.Read))
{
GoogleCredential credentials = GoogleCredential.FromStream(stream);
if (credentials.IsCreateScopedRequired)
credentials = credentials.CreateScoped(scope);
HomeGraphServiceService service = new HomeGraphServiceService(new BaseClientService.Initializer()
{
HttpClientInitializer = credentials
});
var request = new ReportStateAndNotificationRequest
{
AgentUserId = googleCustomerId,
RequestId = requestId,
Payload = new StateAndNotificationPayload
{
Devices = new ReportStateAndNotificationDevice
{
States = deviceStateList
}
}
};
_log.Debug($"Sending to HomeGraph for devices: {deviceIdList} customer: {googleCustomerId} requestId: {requestId}");
DevicesResource.ReportStateAndNotificationRequest rp = service.Devices.ReportStateAndNotification(request);
ReportStateAndNotificationResponse resop = rp.Execute();
}
}
catch (Exception ex)
{
_log.Error($"Exception in ReportToHomeGraph for Customer: {googleCustomerId}. DeviceList: {deviceIdList}. JsonPath: {_appSettingsRetriever.PrivateGoogleAuthenticationFile} Exception: {ex}.");
}
}
Exception:
2021-09-24 14:16:13,547 [110] ERROR ReportToHomeGraph
Exception in ReportToHomeGraph for Customer: 05. DeviceList: (
fe965e6a-21ad-425f-b594-914bf63510a9,
1cc0ee97-a87f-44c5-a3e3-a39d159ee193,
618cdf94-2b31-434f-b91e-00837d155d4a
).
JsonPath: C:/myfile.json Exception: The service homegraph has thrown an exception:
Google.GoogleApiException: Google.Apis.Requests.RequestError
Requested entity was not found. [404]
Errors [
Message[Requested entity was not found.] Location[ - ] Reason[notFound] Domain[global]
]
at Google.Apis.Requests.ClientServiceRequest`1.<ParseResponse>d__35.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Google.Apis.Requests.ClientServiceRequest`1.Execute()
at BusinessLogic.GoogleAssistant.TokenService.HomeGraph.ReportToHomeGraph.Send(Dictionary`2 deviceStateList,
String requestId, String googleCustomerId) in C:\Repos\GoogleAssistant
.TokenService\HomeGraph\ReportToHomeGraph.cs:line 57.
When users add a new device, the first step you need to do is to issue a Request Sync to Google. This indicates the set of devices for that user has changed, and you need a new Sync request to update the data in homegraph. Google will follow this by delivering a Sync intent to your fulfillment endpoint, which you can respond with the updated set of devices.
Getting a 404 when calling Request Sync might indicate your Service Account Key might be invalid, or the agent user id you target might be wrong. Otherwise getting an error for your Sync Response might indicate it’s structured incorrectly. You can find out more about how to structure it in our examples.
I'm using the C# Bot Framework library to retrieve some data from the Bot State Service. Whenever channelId == "emulator" in the code below, it fails with a 400 Bad Request. It looks like both Emulator versions 3.0.0.59 and 3.5.27 use this channel ID. Here's the returned payload:
{
"error": {
"code": "BadArgument",
"message": "Invalid channel ID"
}
}
Note that if I change channelId to something else like "skype", it works as expected.
var credentials = new MicrosoftAppCredentials(id, password);
this.botState = new BotState(new StateClient(credentials));
var channelId = activity.ChannelId;
await botState.GetUserDataAsync(channelId, activity.From.Id);
Received this answer from the Bot Framework team:
For emulator they need to use the activity’s serviceurl when create the state client. Builder automatically does that in the connector client factory:
https://github.com/Microsoft/BotBuilder/blob/master/CSharp/Library/Microsoft.Bot.Builder/ConnectorEx/IConnectorClientFactory.cs#L86
if (IsEmulator(this.address))
{
// for emulator we should use serviceUri of the emulator for storage
return new StateClient(this.serviceUri, this.credentials);
}
That error is from state.botframework.com (which is the default endpoint for stateclient) since emulator is not a valid channelid for the state service.
I am trying to broadcast live from my .Net application using Youtube.Data.Api v3.
I have set up OAuth and downloaded the .JSON file, and that works fine. I know that, because I have already successfully obtained a list of channels resp. videos on my account, i.e., following code works:
var channelsRequest = ytService.Channels.List("contentDetails, snippet");
channelsRequest.Mine = true;
var channelsListResponse = channelsRequest.Execute();
But if I try to execute a insert request (for completeness I show you the whole method),
public static LiveBroadcast CreateImmediateBroadcast(string title = "DefaultBroadcast") {
var snippet = new LiveBroadcastSnippet();
snippet.Title = title;
snippet.ScheduledStartTime = DateTime.Now;
snippet.ScheduledEndTime = DateTime.Now + TimeSpan.FromMinutes(60);
var status = new LiveBroadcastStatus();
status.PrivacyStatus = "unlisted";
var broadcast = new LiveBroadcast();
broadcast.Kind = "youtube#liveBroadcast";
broadcast.Snippet = snippet;
broadcast.Status = status;
var insertBroadcastRequest = ytService.LiveBroadcasts.Insert(broadcast, "snippet, status");
insertBroadcastRequest.Execute();
return broadcast;
}
I get an exception when calling insertBroadcastRequest.Execute(), namely:
Google.GoogleApiException was unhandled
HResult=-2146233088
Message=Google.Apis.Requests.RequestError
Insufficient Permission [403]
Errors [
Message[Insufficient Permission] Location[ - ] Reason[insufficientPermissions] Domain[global]
]
ServiceName=youtube
Source=Google.Apis
StackTrace:
at Google.Apis.Requests.ClientServiceRequest`1.Execute() in C:\Users\cloudsharp\Documents\GitHub\google-api-dotnet-client\Src\Support\GoogleApis\Apis\Requests\ClientServiceRequest.cs:line 96
at YoutubeConsole.YouTubeAPI.CreateImmediateStream(String title) in C:\Users\bussg\Source\Workspaces\OwnExperimental\YoutubeConsole\YoutubeConsole\YouTubeAPI.cs:line 87
at YoutubeConsole.YouTubeAPI.Test() in
...
Also, for completeness, here is my authorization,
using (var stream = new FileStream(Directory.GetCurrentDirectory() + #"\GoogleAuthOtherApplication.json", FileMode.Open, FileAccess.Read)) {
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { YouTubeService.Scope.YoutubeForceSsl},
"user",
CancellationToken.None,
new FileDataStore("YouTubeAPI")
).Result;
}
Also, For the YouTubeService.Scope I have tried all options. The insert method should work with ForceSsl according to the documentation.
Also this documentation page sais
Note: A channel must be approved to use the YouTube Live feature, which enables the channel owner to stream live content to that channel. If you send API requests on behalf of an authenticated user whose channel is not enabled or eligible to stream live content, the API will return an insufficientPermissions error.
But all my channels are approved for Youtube Live. Any ideas how to get this to work?
Ok after some testing between us over Email.
You need to have the correct scope "YouTubeService.Scope.YoutubeForceSsl" by changing "user" we forced it to request permissions again. My tutorial on how filedata store works in the Google .net client library
remove the space "snippet, status" by sending "snippet,status" it worked for me.
For the fun of it: Issue 8568:LiveBroadcasts: insert - spaces in part
I am trying to set up apple push notifications, i am writing my own code for the server and as far as i know i have set up the app correctly. How ever i keep getting the following error come back from the log:
Payload queue received. Connecting to apple server. Creating SSL
connection. Conected. Payload generated for
"Token goes here i deleted it :
{"aps":{"alert":"test","badge":1,"sound":"default"}} Notification
successfully sent to APNS server for Device Toekn :
"Token here I've deleted it" An
error occurred while reading Apple response for token
"Token here I've deleted it" -
Input string was not in a correct format. Disconnected
This is my code.
var push = new PushNotification(true, #"C:\wwwroot\UltraNet\PushService\bin\Debug\206dist.p12", "ultrait");
var payload = new NotificationPayload("devicetoken here ive deleted it", "test", 1, "default");
var p = new List<NotificationPayload> { payload };
var result = push.SendToApple(p);
Console.ReadLine();
I have made sure that the certificates etc are set up correctly.
I am testing it as a adhoc app at the moment because it takes so long for a new version to be able to go live.
I really don't know where I'm going wrong if any one could help it would be brilliant thank you.
I also don't know what i need to do with the PEM files that i have created.
Edit***
I have the correct token this is another error that i receive
Payload generated for
df99286a1cb993cecba86b2e21f3fc4c04d214fcf7e0cf35a668fc822bdaa053 :
{"aps":{"alert":"test","badge":1,"sound":"default"}} Notification
successfully sent to APNS server for Device Toekn :
df99286a1cb993cecba86b2e21f3fc4c04d214fcf7e0cf35a668fc822bdaa053
Disconnected. An error occurred while reading Apple response for token
df99286a1cb993cecba86b2e21f3fc4c04d214fcf7e0cf35a668fc822bdaa053 -
Safe handle has been closed
Based on the code of ReadResponse (see below), the Input string was not in a correct format error message refers to the response received from Apple, and not to the notification you sent.
The code failed to properly read the error response from Apple.
Had it succeeded in reading the response, you would have known what the exact failure was and which message failed. Since you don't have the error response, it's a safe bet to assume the problem is your device token. That's the most common failure. If you can isolate the device token for which the error occurs, you should simply delete that token from your DB. Invalid Device Token error often occurs when you try to use sandbox tokens when pushing to production environment or vica versa.
private void ReadResponse(IAsyncResult ar)
{
if (!_conected)
return;
string payLoadId = "";
int payLoadIndex = 0;
try
{
var info = ar.AsyncState as MyAsyncInfo;
info.MyStream.ReadTimeout = 100;
if (_apnsStream.CanRead)
{
var command = Convert.ToInt16(info.ByteArray[0]);
var status = Convert.ToInt16(info.ByteArray[1]);
var ID = new byte[4];
Array.Copy(info.ByteArray, 2, ID, 0, 4);
payLoadId = Encoding.Default.GetString(ID);
payLoadIndex = ((int.Parse(payLoadId)) - 1000);
Logger.Error("Apple rejected palyload for device token : " + _notifications[payLoadIndex].DeviceToken);
Logger.Error("Apple Error code : " + _errorList[status]);
Logger.Error("Connection terminated by Apple.");
_rejected.Add(_notifications[payLoadIndex].DeviceToken);
_conected = false;
}
}
catch (Exception ex)
{
Logger.Error("An error occurred while reading Apple response for token {0} - {1}", _notifications[payLoadIndex].DeviceToken, ex.Message);
}
}
It was all to do with my certificates.
Because i hadn't turnt my combined PEM certificate back to a p12 file.
I'm trying to add comment to videos on YouTube , some times when I'm getting a video to add comment on it, YouTube send me the below error:
Execution of request failed: http://gdata.youtube.com/feeds/api/videos/ceVlltPBcHg/comments
The inner message of the exception is: "The remote server returned an error: (403) Forbidden."
public bool commentVideo(string videoId)
{
Uri Url = new Uri("http://gdata.youtube.com/feeds/api/videos/" + videoId);
YouTubeRequestSettings s = new YouTubeRequestSettings(AppName, ApiKey,UserName,
Password);
s.Timeout = 10000000;
YouTubeRequest account = new YouTubeRequest(s);
account.Proxy = GetProxyForUser(user);
Video video = account.Retrieve<Video>(Url);//some times got exception
string rating = commentRepository.getRating();
Comment c = new Comment();
c.Content = commentRepository.getComment();
account.AddComment(video, c);
Console.WriteLine("Comment successfully added to : " + videoId);
return true;
}
What is wrong in my code?
It seems google's qouta security rules return error to my code. Code works correctly when I use the code in long intervals.