Skip to content

Commit

Permalink
feat: create google docs using google api (#211)
Browse files Browse the repository at this point in the history
* feat: google docs using google api

* fix: prettier error

* chore: upgrade prettier cli action 1.0.0 to 1.0.2
  • Loading branch information
120EE0692 authored Mar 15, 2024
1 parent 431da79 commit 0fcda7a
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/prettier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
- name: Run Prettier
id: prettier-run
uses: rutajdash/[email protected].0
uses: rutajdash/[email protected].2
with:
file_pattern: ${{ inputs.file_pattern }}
config_path: ${{ inputs.config_path }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ out

# Roles Cache
roles.json
firebaseServiceAccount.json

# Environment Variables
.env.*
Expand Down
12 changes: 9 additions & 3 deletions server/config/firebase.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,25 @@

const Admin = require('firebase-admin');
const logger = require('../utils/logger')('firebase');
const fs = require('fs');

module.exports = {
/**
* @description Firebase Initialization Sequence
* @function
*/
init: () => {
const firebaseServiceAccount = JSON.parse(
Buffer.from(process.env.FIREBASE_SERVICE_ACCOUNT, 'base64').toString('ascii')
);

if (!fs.existsSync('firebaseServiceAccount.json')) {
fs.writeFileSync('firebaseServiceAccount.json', JSON.stringify(firebaseServiceAccount));
}

try {
/** Inititalize Firebase Admin SDK with required configuration */
if (process.env.FIREBASE_SERVICE_ACCOUNT && process.env.NODE_ENV !== 'development') {
const firebaseServiceAccount = JSON.parse(
Buffer.from(process.env.FIREBASE_SERVICE_ACCOUNT, 'base64').toString('ascii')
);
Admin.initializeApp({
credential: Admin.credential.cert(firebaseServiceAccount),
storageBucket: process.env.FIREBASE_STORAGE_BUCKET || null,
Expand Down
2 changes: 2 additions & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
]
},
"dependencies": {
"@googleapis/docs": "^3.0.0",
"@googleapis/drive": "^8.6.0",
"@graphql-tools/stitch": "^8.3.1",
"apollo-server-core": "^3.10.1",
"apollo-server-express": "^3.4.0",
Expand Down
60 changes: 57 additions & 3 deletions server/schema/article/article.datasources.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,54 @@ const UserModel = require('../user/user.model');
const { connection } = require('../../config/mongoose');
const createUpdateObject = require('../../utils/createUpdateObject');
const TagModel = require('../tag/tag.model');
const docs = require('@googleapis/docs');

Check failure on line 10 in server/schema/article/article.datasources.js

View workflow job for this annotation

GitHub Actions / eslint / ESLint Check

'docs' is assigned a value but never used. Allowed unused vars must match /^_/u
const drive = require('@googleapis/drive');

let auth;

const googleAuth = () => {
auth = new drive.auth.GoogleAuth({
keyFilename: './firebaseServiceAccount.json',
scopes: ['https://www.googleapis.com/auth/documents', 'https://www.googleapis.com/auth/drive'],
});
};

const createGoogleDoc = async (title = 'test', emails) => {
try {
googleAuth();
const authClient = await auth.getClient();

const driveClient = drive.drive({
version: 'v3',
auth: authClient,
});

const driveResponse = await driveClient.files.create({
requestBody: {
name: title,
mimeType: 'application/vnd.google-apps.document',
},
});

const googleDocsId = driveResponse.data.id;

await emails.forEach(async (email) => {

Check failure on line 41 in server/schema/article/article.datasources.js

View workflow job for this annotation

GitHub Actions / eslint / ESLint Check

Async arrow function has no 'await' expression
driveClient.permissions.create({
fileId: googleDocsId,
requestBody: {
role: 'writer',
type: 'user',
transferOwnership: true,
emailAddress: email,
},
});
});

return googleDocsId;
} catch (error) {
console.log('error:', error);

Check failure on line 55 in server/schema/article/article.datasources.js

View workflow job for this annotation

GitHub Actions / eslint / ESLint Check

Unexpected console statement
}
};

const ARTICLE_PUBLISH_TYPES = Object.fromEntries(
PublishStatusEnumType.getValues().map((item) => [item.name, item.value])
Expand Down Expand Up @@ -196,6 +244,7 @@ const create = async (
photographers,
designers,
tech,
emails,
categories,
session,
authToken,
Expand All @@ -214,13 +263,18 @@ const create = async (
'At least one of the user IDs supplied supplied is invalid, i.e. that user does not exist or is not a MM Team Member.',
});
}

// TODO: create google doc and link
let googleDocsId;
try {
googleDocsId = await createGoogleDoc(title, emails);
} catch (error) {
throw APIError(`Google docs can not be created`, null, { reason: error });
}
const [_article] = await ArticleModel.create(
[
{
articleType,
title,
googleDocsId,
users: _users.map((_user) => ({
name: _user.fullName,
team: authors.includes(_user._id.toString())
Expand All @@ -235,7 +289,7 @@ const create = async (
details: _user._id,
})),
categories,
createdBy: UserSession.valid(session, authToken) ? mid : null,
createdBy: UserSession.valid(session, authToken) ? mid || null : null,
},
],
{ session: mdbSession }
Expand Down
4 changes: 4 additions & 0 deletions server/schema/article/article.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const ArticleSchema = new Schema(
min: 0,
max: 2,
},
googleDocsId: {
type: String,
required: false,
},
title: {
type: String,
required: true,
Expand Down
1 change: 1 addition & 0 deletions server/schema/article/article.mutation.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ module.exports = new GraphQLObjectType({
photographers: { type: new GraphQLNonNull(new GraphQLList(GraphQLID)) },
designers: { type: new GraphQLNonNull(new GraphQLList(GraphQLID)) },
tech: { type: new GraphQLNonNull(new GraphQLList(GraphQLID)) },
emails: { type: new GraphQLNonNull(new GraphQLList(GraphQLString)) },
categoryNumbers: { type: new GraphQLNonNull(new GraphQLList(GraphQLInt)) },
},
resolve: createArticle,
Expand Down
3 changes: 2 additions & 1 deletion server/schema/article/article.resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ module.exports = {

createArticle: async (
_parent,
{ articleType, title, authors, photographers, designers, tech, categoryNumbers },
{ articleType, title, authors, photographers, designers, tech, emails, categoryNumbers },
{ mid, session, authToken, decodedToken, API: { Article, CategoryMap } }
) => {
try {
Expand Down Expand Up @@ -377,6 +377,7 @@ module.exports = {
photographers,
designers,
tech,
emails,
categories,
session,
authToken,
Expand Down
2 changes: 1 addition & 1 deletion server/schema/article/article.type.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const ArticleType = new GraphQLObjectType({
id: { type: GraphQLID },

articleType: { type: ArticleTypeEnumType },

googleDocsId: { type: GraphQLString },
title: { type: GraphQLString },
content: { type: new GraphQLList(ContentType) },
inshort: { type: GraphQLString },
Expand Down
4 changes: 2 additions & 2 deletions server/schema/squiggle/squiggle.datasources.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const updateContent = async (id, newContent) => {

return _squiggle;
} catch (error) {
throw APIError("failed to update squiggle content.", error);
throw APIError('failed to update squiggle content.', error);
}
};

Expand All @@ -60,7 +60,7 @@ const SquiggleDataSources = () => ({
findByID,
find,
create,
updateContent
updateContent,
});

module.exports = SquiggleDataSources;
4 changes: 2 additions & 2 deletions server/schema/squiggle/squiggle.mutation.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { GraphQLObjectType, GraphQLNonNull, GraphQLID ,GraphQLString } = require('../scalars');
const { GraphQLObjectType, GraphQLNonNull, GraphQLID, GraphQLString } = require('../scalars');
const { createSquiggle, updateSquiggle } = require('./squiggle.resolver');

const SquiggleType = require('./squiggle.type');
Expand All @@ -23,6 +23,6 @@ module.exports = new GraphQLObjectType({
newContent: { type: GraphQLString },
},
resolve: updateSquiggle,
},
},
}
});
14 changes: 5 additions & 9 deletions server/schema/squiggle/squiggle.resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@ module.exports = {
}
},

updateSquiggle: async (
_parent,
{ id, newContent },
{ session, authToken, decodedToken, API: { Squiggle } }
) => {
updateSquiggle: async (_parent, { id, newContent }, { session, authToken, decodedToken, API: { Squiggle } }) => {
try {
if (!UserPermission.exists(session, authToken, decodedToken, 'squiggle.write.all')) {
throw APIError('FORBIDDEN', null, {
Expand All @@ -48,16 +44,16 @@ module.exports = {
let _squiggle = await Squiggle.findByID(id);

if (!_squiggle) {
throw APIError('NOT_FOUND', null, { reason: 'The squiggle to update does not exist.',});
throw APIError('NOT_FOUND', null, { reason: 'The squiggle to update does not exist.' });
}

_squiggle = await Squiggle.updateContent(id, newContent);
return _squiggle;
return _squiggle;
} catch (error) {
throw APIError(null, error);
}
},

getLatestSquiggle: async (_parent, _args, { API: { Squiggle } }, _) => {
try {
const _squiggle = await Squiggle.getLatest();
Expand Down
Loading

0 comments on commit 0fcda7a

Please sign in to comment.