I'm using the Youtube API to upload videos.
The videos are uploaded public, but after the upload, they automatically changed to Private.
I've done the approval from the developer console, so the youtube.upload scope has been approved already. I'm only using the scope to upload and nothing else.
Any ideas ? I tried to contact the support, but no luck :(
Edit:
My application has been verified:
And I have the correct scope:
And the code:
let oauth = Youtube.authenticate({
type: "oauth",
client_id:
"client",
client_secret: "secret",
redirect_url: "redirect",
});
oauth.setCredentials(token);
Youtube.videos.insert(
{
resource: {
snippet: {
title: `blabla`,
description: `blabla`,
},
status: {
privacyStatus: "public",
madeForKids: true,
},
},
part: "snippet,status",
media: {
body: fs.createReadStream(`blabla.mp4`),
},
},
(err, data) => {
console.log("Done.");
}
);
Videos: insert
When your application is still in the testing phase and has not been verified by google yet all videos uploaded will be uploaded as private.
Once you have set your application to published and gone though the verification process you will then be abled to upload public videos.
YouTube API Services - Audit and Quota Extension Form
YouTube API Services Terms of Service
July 28, 2020
update
Audit is not verification, these are two different things. You need to apply for an audit. YouTube API Services - Audit and Quota Extension Form
Related
I'm trying to create new convesation for just created channel using Nodejs + botframework v4.9.2.
I've
created new Channel using POST https://graph.microsoft.com/beta/teams/${teamId}/channels
new tab using POST https://graph.microsoft.com/beta/teams/${req.teamId}/channels/${req.channelId}/tabs
I can see new channel and tab in Teams UI
trying to create new conversation via Conversations.createConversation from bot sdk, it's basically calling POST https://directline.botframework.com/v3/conversations with passing new channel id and getting 405 BadArgument This channel does not support this operation
I'm running bot locally and proxying via ngrok.
Also I can access GET /v3/conversations.
Updated code
Get Team Memebers GET ${graphUrl}/groups/${teamId}/members
Create new Channel
const createChannelRequest: IGraphCreateChannelBody = {
"#odata.type": "#Microsoft.Teams.Core.channel",
displayName: channelName,
description: `This channel is for incident id : ${incidentId}`,
members: membersIds.map(memberId => (
{
"#odata.type": "#microsoft.graph.aadUserConversationMember",
"user#odata.bind": `https://graph.microsoft.com/beta/users('${memberId}')`,
roles: ["owner"]
}
))
};
return await graphClient.createChannel(teamId, createChannelRequest);
createChannel is basically POST ${graphUrl}/teams/${teamId}/channels
Create new Tab POST ${graphUrl}/teams/${req.teamId}/channels/${req.channelId}/tabs where channelId is createChannelResponse.id
Create new conversation
const client = new BotConnector.ConnectorClient(credentials, {baseUri: serviceUrl});
const {bot} = TurnContext.getConversationReference(activity);
const createConversationResponse = await client.conversations.createConversation({
bot,
activity: incidentActivity,
members: teamMembers.value.map(member => ({
id: member.id,
name: member.displayName
})),
channelData: {
channel: {
id: newIncidentChannelId
},
tenant: {
id: tenantId
}
},
isGroup: true
});
where createConversation fails with 405
[Posting a complete answer, based on the comments above]
There's no need (and it won't work), in the context of Teams, to use createConversation, because the conversation is created the moment the Team/Channel/Group chat itself is created (createConversation exists for other Bot Framework scenarios, and is not applicable for Teams). As a result SendToConversation is the correct operation to use.
As to how to use SendToConversation, there are certain important variables you need to have already your side, and the most common time to get these is when your bot is added to the channel/chat/whatever in the first place. You can read more about that here, but more generally, this is considered something called "proactive" messaging, in Teams, and it's worth reading up on that topic more. Please see here and here as good starting points.
I am trying to show a popup message to user using the task module. I have sent a attachment with type invoke. Here is the code
content.sendActivity(MessageFactory.attachment(CardFactory.heroCard('Task Module Invocation from Hero Card',
'This is a hero card with a Task Module Action button',
null, // No images
[{ type: 'invoke', title: 'Task Module', value: { type: 'task/fetch' } }])));
When I click on the Button I have received a request to my messaging end point and the response I have sent is
reply({
task: {
type: 'continue',
value: {
"title": "Task module title",
"height": 'large',
"width": 'large',
"url": "https://67aa9b57.ngrok.io/api/internal/teams/tabs/content",
"fallbackUrl": "https://67aa9b57.ngrok.io/api/internal/teams/tabs/content"
}
}
});
But in the popup message is blank. My ngrok url is not even being hit for the HTML page. This is what I see in popup. But the title was updated. I have no idea why it is not working.
Ant help would be thankful
This is pretty much always caused by the domain of the page not being listed in the valid domains for the application (you set this in your manifest json file, inside App Studio if you're using it). Because you've not listed this as a valid and "safe" domain, Teams won't even make any call at all, that's why there's nothing visible in the NGrok log even.
Just to be clear, we're talking about this section of the schema.
I used YouTube Data API to enable a web-based client I produced for a customer to connect to youtube and list out the videos on her account. This was working fine until the customer left those services unused for 90 days after which the credential was canceled.
I created a new credential but now it doesn't work and I can't figure out the solution. The client authorizes using OAuth then does a YouTube Youtube.Search.list
try{
youtube = getYouTubeService(XXXXXX);
}catch(NullPointerException e){
throw new BasicException("You must connect this system to YouTube before you can load videos. You may do this in Settings.");
}
HashMap<String, String> parameters = new HashMap<String,String>();
parameters.clear();
parameters.put("part", "id,snippet");
parameters.put("forMine", "true");
parameters.put("type", "video");
parameters.put("maxResults", "50");
YouTube.Search.List searchListMineRequest = youtube.search().list(parameters.get("part").toString());
if (parameters.containsKey("maxResults")) {
searchListMineRequest.setMaxResults(Long.parseLong(parameters.get("maxResults").toString()));
}
if (parameters.containsKey("forMine") && parameters.get("forMine") != "") {
boolean forMine = (parameters.get("forMine") == "true") ? true : false;
searchListMineRequest.setForMine(forMine);
}
if (parameters.containsKey("type") && parameters.get("type") != "") {
searchListMineRequest.setType(parameters.get("type").toString());
}
SearchListResponse response = searchListMineRequest.execute();
It is the execute command that produces the problem. The user connects using OAuth in another part of the program and the refresh token is stored for use with the above code. I am new to the google api so excuse if I'm getting some code wrong. I am getting a 403 error. However since the code worked before the credential was cancelled, then I conclude that the problem is with the new credential.
I get the following error message:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "usageLimits",
"message" : "Access Not Configured. YouTube Data API has not been used in project XXXXXXXXXX before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/youtube.googleapis.com/overview?project=XXXXXXXXXX then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
"reason" : "accessNotConfigured",
"extendedHelp" : "https://console.developers.google.com/apis/api/youtube.googleapis.com/overview?project=XXXXXXXXXXXXX"
} ],
"message" : "Access Not Configured. YouTube Data API has not been used in project X before or it is disabled. Enable it by visiting.......
}
I found the solution. Once the project credential reached 90 days, my google console project was no longer a functioning project. Some things would work, others not. I had to completely delete the project, connect the youtube data API again and issue a new credential. This resolved the problem.
so far I've managed to create two webhooks by using their official gem (https://github.com/bigcommerce/bigcommerce-api-ruby) with the following events:
store/order/statusUpdated
store/app/uninstalled
The destination URL is a localhost tunnel managed by ngrok (the https) version.
status_update_hook = Bigcommerce::Webhook.create(connection: connection, headers: { is_active: true }, scope: 'store/order/statusUpdated', destination: 'https://myapp.ngrok.io/bigcommerce/notifications')
uninstall_hook = Bigcommerce::Webhook.create(connection: connection, headers: { is_active: true }, scope: 'store/app/uninstalled', destination: 'https://myapp.ngrok.io/bigcommerce/notifications')
The webhooks seems to be active and correctly created as I can retrieve and list them.
Bigcommerce::Webhook.all(connection:connection)
I manually created an order in my store dashboard but no matter to which state or how many states I change it, no notification is fired. Am I missing something?
The exception that I'm seeing in the logs is:
ExceptionMessage: true is not a valid header value
The "is-active" flag should be sent as part of the request body--your headers, if you choose to include them, would be an arbitrary key value pair that you can check at runtime to verify the hook's origin.
Here's an example request body:
{
"scope": "store/order/*",
"headers": {
"X-Custom-Auth-Header": "{secret_auth_password}"
},
"destination": "https://app.example.com/orders",
"is_active": true
}
Hope this helps!
The following code does fine when I search for videos using Google's YouTube API (version 3) but fails when attempting:
Playlist youTubePlaylist = new Playlist();
youTubePlaylist.setSnippet(playlistSnippet);
youTubePlaylist.setStatus(playlistStatus);
YouTube.Playlists.Insert command = youTube.playlists().insert("snippet,status", youTubePlaylist);
youTubePlaylist.setKey("AI...1IU");
youTubePlaylist.execute();
On the credential step I do get an accessToken but failure happens on youTubePlaylist.execute():
{
"access_token" : "ya29...DSoQ",
"expires_in" : 3600,
"token_type" : "Bearer"
}
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Insufficient Permission",
"reason" : "insufficientPermissions"
} ],
"message" : "Insufficient Permission"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:312)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1049)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
at ...publication.youtube.YouTubeAPIVersion3Connector.execute(YouTubeAPIVersion3Connector.java:107)
at ...publication.youtube.YouTubeAPIVersion3ServiceImpl.createPlaylist(YouTubeAPIVersion3ServiceImpl.java:119)
The authentication is done as follows:
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
File privateKeyP12 = new File(getYouTubeConfigDirectory(), "/private-key-youtube-v3.p12");
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId("99...#developer.gserviceaccount.com")
.setServiceAccountScopes(Collections.list(YouTubeScopes.YOUTUBE_READONLY, YouTubeScopes.YOUTUBE_UPLOAD))
.setServiceAccountPrivateKeyFromP12File(privateKeyP12)
.setClientSecrets("9...42.apps.googleusercontent.com", "DH...w8")
.setRefreshListeners(getRefreshListeners())
.build();
}
return new YouTube.Builder(httpTransport, jsonFactory, credential).setApplicationName(googleAppAccountName).build();
Keep in mind, I am NOT performing YouTube operations on behalf of another user. My web application is managing videos on its own YouTube channel. What I've done already:
via Google Cloud Console, I enabled YouTube v3 API, created an app with permission to edit
I generated p12 private key file which is loaded by code above
I use API key on all operations
What am I missing? For example:
- what am I supposed to do with the Public Key Fingerprint provided by Google Cloud Console?
- am I properly setting setServiceAccountScopes() with only YouTubeScopes.YOUTUBE_READONLY and YouTubeScopes.YOUTUBE_UPLOAD?
- Is there some way I can control permissions beyond setting "Can Edit" on Cloud Console for email: 99...91i#developer.gserviceaccount.com?
Part of my frustration is that all code samples provided by YouTube v3 API site involve spinning up a "headless" AWT toolkit. All my app wants to do is authenticate using its own YouTube account.
Thank you for your suggestion.
Service accounts are not supported in Data API v3. Please create a project id in cloud console and use your client secret and id.
Although we are aware of the need, we don't have news about this availability at this point.
Here are our Java samples, that can guide you.