Google Meet: How can i catch the url? - meeting-request

I need to open a new google meet room, and send it. I can't use standard "share" button in app. I need to catch the final url.
I can't catch that with curl (it's not a normal redirect).
My idea is that i need to open a request/link in background or in the same page, wait some second and catch the link, after i can release the page and user can enter.
Do you know something that can help me?
Edit:
Yes, i had miss to tell that i need to generate a room from a click and catch the url from code. Generally, i should to make this with Google Calendar API, but in this case i can't.

I use google Calendar API. I make a webApp for my organization, that from a form (with user information to send togheter meet link) make a google calendar event with google meet room (from google loggedin user account), catch the link and send it by a smsGateway.
function FormForMeet (Args) {
// get calendar name, if it already exists
var meetsCalendar = CalendarApp.getCalendarsByName ('CalendarName');
Logger.log (meetsCalendar.length)
if (meetsCalendar.length> = 1) {
// if some calendar be found, it catch the first, obviously here you can use some differet method. I had choose this because I don't expect to find more than 1
var calendar = meetsCalendar [0] .getId ();
}
else
{
// If miss, create new one.
var calendar = CalendarApp.createCalendar ('CalendarName', {summary: 'descrip Calendar',
// set a color of calendar label :D
color: CalendarApp.Color.PURPLE});
calendar = calendar.getId ();
}
// Call function to create meet
var LinkMeet = CreateConference_ (calendar);
// here you can use what you want for send Args + LinkMeet);
// if you want return link
return LinkMeet;
}
// Function to create Conference. You can obviously use the code up without make a new function.
function CreateConference_ (calendarId) {
// Custom of event, here I created the conferences according to my needs (now, with 1 h / conference)
var now = new Date ();
var start = new Date (now.getTime ()). toISOString ();
var end = new Date (now.getTime () + (1 * 60 * 60 * 1000)). toISOString ();
// generate random string to request
var rdmreqId = genStrg ();
var event = {
"end": {
"dateTime": end
},
"start": {
"dateTime": start
},
"summary": "conferenceName",
"conferenceData": {
"createRequest": {
"conferenceSolutionKey": {
"type": "hangoutsMeet"
},
"requestId": rdmreqId
}
}
};
// insert event in calendar
event = Calendar.Events.insert (event, calendarId, {
"conferenceDataVersion": 1});
// if use the function you can return the link to send
return event.hangoutLink
}
// random strind
function genStrg () {
var data = "something";
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789! # # $% & <> * -";
for (var j = 2; j <= data.length; j ++) {
text = ""; // Reset text to empty string
for (var i = 0; i <possible.length; i ++) {
text + = possible.charAt (Math.floor (Math.random () * possible.length));
}
return text;
}
}

all google meet links look something like this:
https://meet.google.com/abc-defg-hij
You should be able to just copy and paste this link from your browser page. If someone enters this link, they will be taken to the meet lobby and they can enter at any time.
If you can't access this link for some reason, like if you're on mobile, you have to put your meet code (the abc-defg-hij) at the end of the aforementioned url.
edit: You actually can find the link if you're on mobile by going into your meeting lobby and scrolling down until you get to "joining information". Under that there should be the meeting link and the numbers to join by phone.

Related

Google Classroom API : Unable to receive push notifications for courseworks and student submissions (COURSE_WORK_CHANGES)

We are seriously blocked. We have followed the documentation below (among many others) to set up the pub/sub pipelines, create service accounts, assign permissions and use the right scopes and feed types for registrations.
https://developers.google.com/classroom/guides/push-notifications
So programmatically we are able to do the following in .net using the API :
We can Create Courses
We can create registrations for a given courseid
We create/update courseworks for the course that we have created a registration.
All good so far,
BUT, we don't receive notifications for that created/update course work.
some code for clarity :
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer("sa-something#precise-asset-259113.iam.gserviceaccount.com")
{
User = "impersonated user",
Scopes = new string[] { "https://www.googleapis.com/auth/classroom.coursework.students" ,
"https://www.googleapis.com/auth/classroom.courses",
"https://www.googleapis.com/auth/classroom.push-notifications" }}
.FromPrivateKey("My private key"));
//Authorize request
var result = credential.RequestAccessTokenAsync(CancellationToken.None).Result;
var service = new ClassroomService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
});
// We get courses
var courses = service.Courses.List().Execute();
// We get one course for registration
var course = courses.Courses.First();
// We create registration
var registration = service.Registrations.Create(new Google.Apis.Classroom.v1.Data.Registration()
{
Feed = new Google.Apis.Classroom.v1.Data.Feed()
{
FeedType = "COURSE_WORK_CHANGES",
CourseWorkChangesInfo = new Google.Apis.Classroom.v1.Data.CourseWorkChangesInfo()
{
CourseId = course.Id
},
},
CloudPubsubTopic = new Google.Apis.Classroom.v1.Data.CloudPubsubTopic()
{
TopicName = "projects/precise-asset-259113/topics/test"
},
});
//Successful response - We get a registrationID
var response = registration.Execute();
var courseWork = new CourseWork()
{
CourseId = course.Id,
Title = "Ver Test",
Description = "Calculus",
WorkType = "ASSIGNMENT",
MaxPoints = 20.0,
State = "PUBLISHED",
AlternateLink = "www.uni.com",
CreatorUserId = course.OwnerId,
CreationTime = DateTime.UtcNow,
DueTime = new TimeOfDay() { Hours = 5, Minutes = 10, Nanos = 10, Seconds = 10 },
DueDate = new Date() { Day = 3, Month = 12, Year = 2019 },
Assignment = new Assignment() { StudentWorkFolder = new DriveFolder() { AlternateLink = "Somewhere", Title = "My Calculus" } }
};
//Create course work for the course that we registered
var courseWorkResponse = service.Courses.CourseWork.Create(courseWork, course.Id).Execute();
SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create();
SubscriptionName subscriptionName = new SubscriptionName("precise-asset-259113", "test");
PullResponse pullResponse = subscriber.Pull(
subscriptionName, returnImmediately: true, maxMessages: 20);
// Check for push notifications BUT ....NADA!!!
foreach (ReceivedMessage msg in pullResponse.ReceivedMessages)
{
string text = Encoding.UTF8.GetString(msg.Message.Data.ToArray());
Console.WriteLine($"Message {msg.Message.MessageId}: {text}");
}
Can you please assist?
Thanks
There are several things you need to change in order to ensure you get the notifications:
You need to create your subscription before you send the request that will generate the Pub/Sub message. Only messages published after the successful creation of a subscription are guaranteed to be received by subscribers for that subscription.
A single pull request with returnImmediately set to true is unlikely to return any messages, even if a message has been published. With this property set, if there are no messages immediately in memory of the server reached, the empty response is returned. You should always set returnImmediately to false. This still won't guarantee that messages are returned in a single request/response, even if there are messages available, but it will make it more likely.
Ideally, you would use the asynchronous client library, which opens a stream to the Cloud Pub/Sub service and receives messages as soon as they are available. If you are going to use the synchronous Pull method directly, then you need to keep many of them outstanding simultaneously in order to ensure delivery of messages with minimal latency. As soon as you receive a PullResponse for any of the outstanding requests, you should immediately open up another request to replace it. The goal of the asynchronous client library is to prevent one from having to take all of these step manually to ensure efficient delivery.

Edting collection of items is slow in Sitecore

I've implemented an on item:saved handler per this question I posted here: Run code when Publishing Restriction is saved in Sitecore
When an author changes the publishing restrictions on a page, I iterate through each of the related components for that page, updating the publishing restrictions on each to match the page item. This works, but some pages have 150 or so components and the process of editing each is taking for ever. The result is that the UI hangs for up to 5 minutes while it runs. Not good.
I'm doing this:
compItem.Editing.BeginEdit();
compItem.Publishing.ValidFrom = pageItem.Publishing.ValidFrom;
compItem.Publishing.ValidTo = pageItem.Publishing.ValidTo;
compItem.Editing.EndEdit(true, true);
I've played around with the updateStatistics and silent arguments. If do it "silent" the UI responds, but of course it still takes forever for the update to run in the background which could cause issues, since there will be a window of time where the pub restrictions between the page and components would be out of sync.
Any thoughts on why updating 150 items is so slow? Any ways to speed it up?
Here's the full code:
public void OnItemSaved(object sender, EventArgs args)
{
Item item = Event.ExtractParameter(args, 0) as Item;
if (item == null)
return;
//if it's a page, then update the page component templates with the same publish restrictions.
if(this.HasBaseTemplate(item, GlobalId.PageBaseTemplate))
{
ItemChanges itemChanges = Event.ExtractParameter(args, 1) as ItemChanges;
if (itemChanges != null &&
(itemChanges.FieldChanges.Contains(__Validfrom) || itemChanges.FieldChanges.Contains(__Validto)))
{
foreach (Item i in this.GetPageComponents(item))
{
try
{
i.Editing.BeginEdit();
i.Publishing.ValidFrom = item.Publishing.ValidFrom;
i.Publishing.ValidTo = item.Publishing.ValidTo;
i.Editing.EndEdit(true, false);
}
catch(Exception ex)
{
i.Editing.CancelEdit();
}
}
}
}
}
protected IEnumerable<Item> GetPageComponents(Item page)
{
var links = page.Links.GetAllLinks(false, true);
var foundIds = new HashSet<ID>();
var foundComponentIds = new HashSet<ID>();
var componentIds = new List<ID> { page.ID };
using (var context = ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
while (componentIds.Any())
{
var query = context.GetQueryable<LinkSearchResultItem>();
var predicate = PredicateBuilder.False<LinkSearchResultItem>();
foreach (var id in componentIds)
{
predicate = predicate.Or(sri => sri.ItemId == id);
}
query = query.Where(predicate);
var results = query.GetResults().Hits.Select(h => h.Document);
foundIds.Add(componentIds);
componentIds.Clear();
componentIds.AddRange(results
.Where(sri => (sri.Path.StartsWith("/sitecore/content/BECU/Global/Page Components/", StringComparison.InvariantCultureIgnoreCase) || sri.ItemId == page.ID) && sri.Links != null)
.SelectMany(sri => sri.Links)
.Except(foundIds));
foundComponentIds.Add(results
.Where(sri => (sri.Path.StartsWith("/sitecore/content/BECU/Global/Page Components/", StringComparison.InvariantCultureIgnoreCase)))
.Select(sri => sri.ItemId));
}
}
var database = page.Database;
return foundComponentIds.Select(id => database.GetItem(id)).Where(i => i != null);
}
I would recommend that you try wrapping your edit code with a Sitecore.Data.BulkUpdateContext as follows
...
using(new Sitecore.Data.BulkUpdateContext())
{
foreach (Item i in this.GetPageComponents(item))
{
try
{
i.Editing.BeginEdit();
i.Publishing.ValidFrom = item.Publishing.ValidFrom;
i.Publishing.ValidTo = item.Publishing.ValidTo;
i.Editing.EndEdit(true, false);
}
catch(Exception ex)
{
i.Editing.CancelEdit();
}
}
}
...
When an item is updated in Sitecore, several other background processes and events as a result of updating the item. Such an example is indexing which will slow down the update of a large number of items at once.
The BulkUpdateContext will disable most of these events and processes until the update is complete thereby hopefully speeding up the update of your items.
Note: I have yet to use this BulkUpdateContext myself but I found several posts including this Stackoverflow question where it claims that the BulkUpdateContext only improves item creation speed, not updates. However that may only apply to the particular version of Sitecore that was being used at the time. It may may no longer be the case with new versions of Sitecore (7.X and 8), so I think it is still worth a try.

Loopback strange behaviour

I am talking about loopback push component. I am trying to intercept the "create" method of "Installation" model. My code looks like this -
server/boot/installationex.js
module.exports = function (app) {
var Installation = app.models.Installation;
var create = Installation.create;
Installation.create = function (data, cb) {
//reinitializing old implementation
this.create = create;
console.log("Received data: "+JSON.stringify(data));
if (!data || !data.imei) {
console.log("No data or imei was provided, creating new");
this.create(data, cb);
return;
}
//saving 'this' reference
var that = this;
//search by imei filter
var filter = {where: {imei: data.imei}};
this.findOne(filter, function (err, result) {
if (err) {
console.log("Error occurred while looking for installation by IMEI");
cb(err);
return;
}
if (!result) {
console.log("No installation found by IMEI, will create a new installation");
that.create(data, cb);
return;
}
console.log("Found existing installation with id: " + JSON.stringify(result));
result.deviceToken = result.gpsLocation = result.osVersion = result.vendor = result.phoneNumbers = null;
if (data.deviceToken) {
result.deviceToken = data.deviceToken;
}
if (data.gpsLocation) {
result.gpsLocation = data.gpsLocation;
}
if (data.osVersion) {
result.osVersion = data.osVersion;
}
if (data.vendor) {
//result.vendor=data.vendor;
result.vendor = 'jahid';
}
if (data.phoneNumbers) {
result.phoneNumbers = data.phoneNumbers;
}
that.upsert(result, cb);
});
}
}
Unfortunately this code is invoked only once, I mean the first time. After that this code is never invoked. I became sure by looking at the log. It only prints the log first time. After that it does not print any log.
Any idea why this glue code is only invoked once? My intention is to intercept all create method invocation for Installation model. And check if there is already an entry for supplied "IMEI", if so then reuse that. Otherwise create new.
Thanks in advance.
Best regards,
Jahid
What I would start here with is:
instead of implementing your own intercepting mechanism use Model Hooks
check out findOrCreate() method
boot scripts are only run once during application startup. if you want a function that triggers every time a function is called, use a remote hook or model hook. probably something along the lines of:
...
Installation.beforeRemote('create', ...
...
see http://docs.strongloop.com/display/LB/Adding+logic+to+models for more info

Firefox Add-On to redirect urls based on wildcards

I am looking at writing a firefox extension which will take a url, apply a regex to it to produce a second url.
I then need to have firefox redirect to this new URL without the user having to do anyything.
Does anyone have any examples I could use to learn how to do this. I've used the firefox tutorials to get as far as this..
// Import the page-mod API
var pageMod = require("sdk/page-mod");
// Import the self API
var self = require("sdk/self");
// Create a page mod
// It will run a script whenever a ".org" URL is loaded
// The script replaces the page contents with a message
pageMod.PageMod({
include: "*",
contentScript: 'window.alert("Matched Page");'
})
So my question is, how would I do this.
For instance, if a user types in http://www.mywebsite/data/7287232/wherever, I'd like them to be redirected to http://www.anotherwebsite/folder/7287232
Well.. answering to the initial head line:
https://addons.mozilla.org/en-US/firefox/addon/redirector
Or is that actually you? #ScaryAardvark ?
that example is very complex, the main purpose of that traceable channel example is to get a COPY of the sourcecode that gets loaded at that uri.
const { Ci, Cu, Cc, Cr } = require('chrome'); //const {interfaces: Ci, utils: Cu, classes: Cc, results: Cr } = Components;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/devtools/Console.jsm');
var observers = {
'http-on-modify-request': {
observe: function (aSubject, aTopic, aData) {
console.info('http-on-modify-request: aSubject = ' + aSubject + ' | aTopic = ' + aTopic + ' | aData = ' + aData);
var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
var requestUrl = httpChannel.URI.spec
if (/\.org/.test(requestUrl) || /http\:\/\/www\.mywebsite\/data\/7287232\/.+/.test(requestUrl)) {
httpChannel.redirectTo(Services.io.newURI('http://www.anotherwebsite/folder/7287232', null, null));
}
},
reg: function () {
Services.obs.addObserver(observers['http-on-modify-request'], 'http-on-modify-request', false);
},
unreg: function () {
Services.obs.removeObserver(observers['http-on-modify-request'], 'http-on-modify-request');
}
}
};
to register the observer on startup of addon run this:
//register all observers
for (var o in observers) {
observers[o].reg();
}
and on shutdown of addon unregister all observers like this:
//unregister all observers
for (var o in observers) {
observers[o].unreg();
}

How to send an alert message to a special online user with firebase

I'm trying to make a "FourConnect"-game with javascript. I want, that there is a list from all online users. This list I've made with the example on the firebase site. Now I want that I can choose one online user and send them a invitation to play with me.
So I wrote a function, that all users expect of me have an additional div. When I click on the div this special user should get a confirm box to say okey or cancel. If the user clicks okey the play should begin.
I'll save the name and the id from the user. This already works.
My problem is, that I don't know how to send the request to the other user. I tried out many but always the confirm box is on my brwoser not on the browser of the other user.
I looked for solutions on the firebase page and in google but couldn't find anything which solves my problem.
The code I already have:
var name = prompt("Your name?", "Guest"),
currentStatus = "★ online";
// Get a reference to the presence data in Firebase.
var userListRef = new Firebase(connectFour.CONFIG.firebaseUrl);
// Generate a reference to a new location for my user with push.
var myUserRef = userListRef.push();
var gameId = myUserRef.name();
document.getElementById('labelGameId').innerHTML = gameId;
beginGame({id: gameId, name: name, status: currentStatus});
// Get a reference to my own presence status.
var connectedRef = new Firebase('http://presence.firebaseio-demo.com/.info/connected');
connectedRef.on("value", function(isOnline) {
if (isOnline.val()) {
// If we lose our internet connection, we want ourselves removed from the list.
myUserRef.onDisconnect().remove();
// Set our initial online status.
setUserStatus("★ online");
} else {
// We need to catch anytime we are marked as offline and then set the correct status. We
// could be marked as offline 1) on page load or 2) when we lose our internet connection
// temporarily.
setUserStatus(currentStatus);
}
});
//}
// A helper function to let us set our own state.
function setUserStatus(status) {
// Set our status in the list of online users.
currentStatus = status;
myUserRef.set({ name: name, status: status });
}
// Update our GUI to show someone"s online status.
userListRef.on("child_added", function(snapshot) {
var user = snapshot.val();
$("#output").append($("<div/>").attr("id", snapshot.name()));
$("#" + snapshot.name()).text(user.name + " is currently " + user.status);
if(snapshot.name() != myUserRef.name()){
var $invite = $('<div id="invite">invite</div>');
$("#output").append($invite);
$($invite).on('click', function(){
//startGame(user);
console.log('Gegner2: '+snapshot.name());
console.log('Genger2Name: '+user.name);
joinGame({id: snapshot.name(), name: user.name, status: user.status});
});
}
});
// Update our GUI to remove the status of a user who has left.
userListRef.on("child_removed", function(snapshot) {
$("#" + snapshot.name()).remove();
});
// Update our GUI to change a user"s status.
userListRef.on("child_changed", function(snapshot) {
var user = snapshot.val();
$("#" + snapshot.name()).text(user.name + " is currently " + user.status);
});
document.onIdle = function () {
setUserStatus("☆ idle");
}
document.onAway = function () {
setUserStatus("☄ away");
}
document.onBack = function (isIdle, isAway) {
setUserStatus("★ online");
}
setIdleTimeout(5000);
setAwayTimeout(10000);
function joinGame(opponent) {
console.log(opponent);
console.log(opponent.id);
var player2ID = opponent.id;
myUserRef = new Firebase(connectFour.CONFIG.firebaseUrl + opponent.id);
myUserRef.once('value', function(dataSnapshot){
if(dataSnapshot.val()){
beginGame({id: player2ID , name: opponent.name, status: opponent.status});
}else{
alert("game doesn't exist");
}
});
}
function beginGame(player) {
console.log(player);
console.log('Id spieler1: '+gameId);
});
With this code I can click on "invite" and then I will see the ID which the user had. I also wanted to send the ID to beginGame() but this doesn't really works.
My Firebase Structure:
games
-InmydEpSe5oZcLZUhfU
-InrLM6uxAsoOayOgFce
-name: "Barbara"
-status: "away"
In order to send a message to another user, you need that user to be monitoring a known location in your Firebase. Then when you want to send them a message, you simply modify that location in some way and they'll get a callback. Here's some pseudo code:
var root = new Firebase(...);
//On initialization start listening for messages
root.child("users/inbound-messages").on("child_added",
function(newMessageSnapshot) {
displaySomethingToTheUser(newMessageSnapshot.val());
newMessageSnapshot.ref().remove();
}
);
//Send a message to another user
root.child(otherUserId).child("inbound-messages").push("Hi other user!");
From what I understand. You want a chat window in the game so that users logged to communicate among themselves, okay?
Well, in its structure, you simply add something like:
-Games
    -rooms
     -charOfRoomSpecific
         - users
            
             + InmydEpSe5oZcLZUhfU
              -InrLM6uxAsoOayOgFce
                     name: "Barbara"
                     status "away"
         
       - messages
           + InmyBlaBlae5oZcLPKSu
           -InmyBlaBlae5oZcLPKSu2
                user: "Barbara"
                say: "Hello man, will gamer!"
     + charOfRoomSpecific2
     + charOfRoomSpecific3
     ...
So, for your users in the room can read the message simply:
FirebaseRef.child ("rooms/charOfYourRoomSpecific/messages");
And everyone who has access to this room will see in real time their conversations.