AWSTemplateFormatVersion: 2010-09-09 Description: AppSync setup Parameters: FunctionStack: Description: The stack name that deploys the Lambda functions to invoke. Type: String Resources: DataSourceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: appsync.amazonaws.com Policies: - PolicyName: LambdaInvoker PolicyDocument: Version: 2012-10-17 Statement: - Action: lambda:InvokeFunction Effect: Allow Resource: - Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-HipchatCapabilitiesDescriptor' - Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-HipchatCapabilitiesDescriptor' - ':*' - Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-HipchatInstallData' - Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-HipchatInstallData' - ':*' - Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-ServiceInfo' - Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-ServiceInfo' - ':*' - Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-SnsNotification' - Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-SnsNotification' - ':*' RoleName: !Sub '${AWS::StackName}-lambda-role' GqlApi: Type: AWS::AppSync::GraphQLApi Properties: AuthenticationType: AWS_IAM Name: !Ref AWS::StackName GqlSchema: Type: AWS::AppSync::GraphQLSchema Properties: ApiId: !GetAtt GqlApi.ApiId Definition: | type Mutation { deleteHipchatInstallData(oauthId: String, cognitoIdentityId__: String): ! postHipchatInstallData(hipchatInstallData: HipchatInstallDataInput! cognitoIdentityId__: String): ! postSnsNotification(snsNotification: SnsNotificationInput! , roomId: String, cognitoIdentityId__: String): ! } type Query { getHipchatCapabilitiesDescriptor(redirectToHipchatInstall: Boolean, cognitoIdentityId__: String): HipchatCapabilitiesDescriptor getHipchatInstallData(installableUrl: String, redirectUrl: String, cognitoIdentityId__: String): HipchatCapabilitiesDescriptor getServiceInfo(cognitoIdentityId__: String): ServiceInfo } input ErrorInput { description: String } type Error { description: String! } input HipchatApiConsumerInput { fromName: String scopes: [hipchat_scope] } type HipchatApiConsumer { fromName: String scopes: [hipchat_scope]! } input HipchatCapabilitiesInput { configurable: hipchat_configuration_pageInput hipchatApiConsumer: hipchat_api_consumerInput installable: hipchat_installableInput oauth2Provider: hipchat_oauth2_providerInput } type HipchatCapabilities { configurable: hipchat_configuration_page hipchatApiConsumer: hipchat_api_consumer installable: hipchat_installable oauth2Provider: hipchat_oauth2_provider } input HipchatCapabilitiesDescriptorInput { apiVersion: String capabilities: hipchat_capabilitiesInput description: String key: String links: hipchat_linksInput name: String vendor: hipchat_vendorInput } type HipchatCapabilitiesDescriptor { apiVersion: String capabilities: hipchat_capabilities description: String! key: String! links: hipchat_links! name: String! vendor: hipchat_vendor } input HipchatConfigurationPageInput { allowAccessToRoomAdmins: String url: String } type HipchatConfigurationPage { allowAccessToRoomAdmins: String url: String! } input HipchatInstallDataInput { capabilitiesUrl: String groupId: Int oauthId: String oauthSecret: String roomId: String } type HipchatInstallData { capabilitiesUrl: String! groupId: Int! oauthId: String! oauthSecret: String! roomId: String } input HipchatInstallableInput { allowGlobal: Boolean allowRoom: Boolean callbackUrl: String installedUrl: String } type HipchatInstallable { allowGlobal: Boolean allowRoom: Boolean callbackUrl: String installedUrl: String } input HipchatLinksInput { api: String homepage: String self: String } type HipchatLinks { api: String homepage: String self: String! } input HipchatOauth2ProviderInput { authorizationUrl: String tokenUrl: String } type HipchatOauth2Provider { authorizationUrl: String tokenUrl: String } input HipchatVendorInput { name: String url: String } type HipchatVendor { name: String! url: String! } input ServiceInfoInput { buildTime: AWSDateTime name: String sbtVersion: String scalaVersion: String version: String } type ServiceInfo { buildTime: AWSDateTime! name: String! sbtVersion: String! scalaVersion: String! version: String! } input SnsNotificationInput { message: String messageId: String signature: String signatureVersion: String signingCertURL: String subject: String subscribeURL: String timestamp: String token: String topicArn: String type: String unsubscribeURL: String } type SnsNotification { message: String! messageId: String! signature: String! signatureVersion: String! signingCertURL: String! subject: String subscribeURL: String timestamp: String! token: String topicArn: String! type: String! unsubscribeURL: String } enum HipchatScope { SEND_MESSAGE SEND_NOTIFICATION } schema { query: Query mutation: Mutation } DependsOn: - GqlApi HipchatCapabilitiesDescriptorDataSource: Type: AWS::AppSync::DataSource Properties: ApiId: !GetAtt GqlApi.ApiId LambdaConfig: LambdaFunctionArn: Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-HipchatCapabilitiesDescriptor' Name: hipchat_capabilities_descriptor_lambda ServiceRoleArn: !GetAtt DataSourceRole.Arn Type: AWS_LAMBDA DependsOn: - DataSourceRole - GqlApi GetHipchatCapabilitiesDescriptorResolver: Type: AWS::AppSync::Resolver Properties: ApiId: !GetAtt GqlApi.ApiId FieldName: getHipchatCapabilitiesDescriptor TypeName: Query DataSourceName: !GetAtt HipchatCapabilitiesDescriptorDataSource.Name RequestMappingTemplate: | #set( $cognitoIdentityId = $context.identity.cognitoIdentityId ) #if($context.identity.userArn.matches('arn:aws:iam::\d+:user/.*')) #if($context.args.cognitoIdentityId__) #set( $cognitoIdentityId = $context.args.cognitoIdentityId__ ) #elseif( $context.source.cognitoIdentityId__ ) #set( $cognitoIdentityId = $context.source.cognitoIdentityId__ ) #end #end #set( $unamepwd = "$util.urlEncode($cognitoIdentityId):" ) { "version" : "2017-02-28", "operation": "Invoke", "payload": { "source": "AppSync", "httpMethod": "get", "headers": { "Authorization": "Basic $util.base64Encode($unamepwd)", }, "pathParameters": { }, "queryStringParameters": { "redirect_to_hipchat_install": "$util.escapeJavaScript($context.args.redirectToHipchatInstall)" } } } ResponseMappingTemplate: | #if($context.result.statusCode >= 200 && $context.result.statusCode <= 299) #set( $result = $util.parseJson($context.result.body) ) #if($context.args.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.args.cognitoIdentityId__ ) #elseif($context.source.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.source.cognitoIdentityId__ ) #end $util.toJson($result) #else $utils.error($util.parseJson($context.result.body).message, $context.result.statusCode.toString(), $util.parseJson($context.result.body)) #end DependsOn: - GqlApi - GqlSchema - HipchatCapabilitiesDescriptorDataSource HipchatInstallDataDataSource: Type: AWS::AppSync::DataSource Properties: ApiId: !GetAtt GqlApi.ApiId LambdaConfig: LambdaFunctionArn: Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-HipchatInstallData' Name: hipchat_install_data_lambda ServiceRoleArn: !GetAtt DataSourceRole.Arn Type: AWS_LAMBDA DependsOn: - DataSourceRole - GqlApi DeleteHipchatInstallDataResolver: Type: AWS::AppSync::Resolver Properties: ApiId: !GetAtt GqlApi.ApiId FieldName: deleteHipchatInstallData TypeName: Mutation DataSourceName: !GetAtt HipchatInstallDataDataSource.Name RequestMappingTemplate: | #set( $cognitoIdentityId = $context.identity.cognitoIdentityId ) #if($context.identity.userArn.matches('arn:aws:iam::\d+:user/.*')) #if($context.args.cognitoIdentityId__) #set( $cognitoIdentityId = $context.args.cognitoIdentityId__ ) #elseif( $context.source.cognitoIdentityId__ ) #set( $cognitoIdentityId = $context.source.cognitoIdentityId__ ) #end #end #set( $unamepwd = "$util.urlEncode($cognitoIdentityId):" ) { "version" : "2017-02-28", "operation": "Invoke", "payload": { "source": "AppSync", "httpMethod": "delete", "headers": { "Authorization": "Basic $util.base64Encode($unamepwd)", }, "pathParameters": { "oauthId": "$util.escapeJavaScript($context.args.oauthId)" }, "queryStringParameters": { } } } ResponseMappingTemplate: | #if($context.result.statusCode >= 200 && $context.result.statusCode <= 299) #set( $result = $util.parseJson($context.result.body) ) #if($context.args.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.args.cognitoIdentityId__ ) #elseif($context.source.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.source.cognitoIdentityId__ ) #end $util.toJson($result) #else $utils.error($util.parseJson($context.result.body).message, $context.result.statusCode.toString(), $util.parseJson($context.result.body)) #end DependsOn: - GqlApi - GqlSchema - HipchatInstallDataDataSource GetHipchatInstallDataResolver: Type: AWS::AppSync::Resolver Properties: ApiId: !GetAtt GqlApi.ApiId FieldName: getHipchatInstallData TypeName: Query DataSourceName: !GetAtt HipchatInstallDataDataSource.Name RequestMappingTemplate: | #set( $cognitoIdentityId = $context.identity.cognitoIdentityId ) #if($context.identity.userArn.matches('arn:aws:iam::\d+:user/.*')) #if($context.args.cognitoIdentityId__) #set( $cognitoIdentityId = $context.args.cognitoIdentityId__ ) #elseif( $context.source.cognitoIdentityId__ ) #set( $cognitoIdentityId = $context.source.cognitoIdentityId__ ) #end #end #set( $unamepwd = "$util.urlEncode($cognitoIdentityId):" ) { "version" : "2017-02-28", "operation": "Invoke", "payload": { "source": "AppSync", "httpMethod": "get", "headers": { "Authorization": "Basic $util.base64Encode($unamepwd)", }, "pathParameters": { }, "queryStringParameters": { "installable_url": "$util.escapeJavaScript($context.args.installableUrl)", "redirect_url": "$util.escapeJavaScript($context.args.redirectUrl)" } } } ResponseMappingTemplate: | #if($context.result.statusCode >= 200 && $context.result.statusCode <= 299) #set( $result = $util.parseJson($context.result.body) ) #if($context.args.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.args.cognitoIdentityId__ ) #elseif($context.source.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.source.cognitoIdentityId__ ) #end $util.toJson($result) #else $utils.error($util.parseJson($context.result.body).message, $context.result.statusCode.toString(), $util.parseJson($context.result.body)) #end DependsOn: - GqlApi - GqlSchema - HipchatInstallDataDataSource PostHipchatInstallDataResolver: Type: AWS::AppSync::Resolver Properties: ApiId: !GetAtt GqlApi.ApiId FieldName: postHipchatInstallData TypeName: Mutation DataSourceName: !GetAtt HipchatInstallDataDataSource.Name RequestMappingTemplate: | #set( $cognitoIdentityId = $context.identity.cognitoIdentityId ) #if($context.identity.userArn.matches('arn:aws:iam::\d+:user/.*')) #if($context.args.cognitoIdentityId__) #set( $cognitoIdentityId = $context.args.cognitoIdentityId__ ) #elseif( $context.source.cognitoIdentityId__ ) #set( $cognitoIdentityId = $context.source.cognitoIdentityId__ ) #end #end #set( $unamepwd = "$util.urlEncode($cognitoIdentityId):" ) { "version" : "2017-02-28", "operation": "Invoke", "payload": { "source": "AppSync", "httpMethod": "post", "body": "$util.escapeJavaScript($util.toJson($context.args.hipchatInstallData))", "headers": { "Authorization": "Basic $util.base64Encode($unamepwd)", }, "pathParameters": { }, "queryStringParameters": { } } } ResponseMappingTemplate: | #if($context.result.statusCode >= 200 && $context.result.statusCode <= 299) #set( $result = $util.parseJson($context.result.body) ) #if($context.args.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.args.cognitoIdentityId__ ) #elseif($context.source.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.source.cognitoIdentityId__ ) #end $util.toJson($result) #else $utils.error($util.parseJson($context.result.body).message, $context.result.statusCode.toString(), $util.parseJson($context.result.body)) #end DependsOn: - GqlApi - GqlSchema - HipchatInstallDataDataSource ServiceInfoDataSource: Type: AWS::AppSync::DataSource Properties: ApiId: !GetAtt GqlApi.ApiId LambdaConfig: LambdaFunctionArn: Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-ServiceInfo' Name: service_info_lambda ServiceRoleArn: !GetAtt DataSourceRole.Arn Type: AWS_LAMBDA DependsOn: - DataSourceRole - GqlApi GetServiceInfoResolver: Type: AWS::AppSync::Resolver Properties: ApiId: !GetAtt GqlApi.ApiId FieldName: getServiceInfo TypeName: Query DataSourceName: !GetAtt ServiceInfoDataSource.Name RequestMappingTemplate: | #set( $cognitoIdentityId = $context.identity.cognitoIdentityId ) #if($context.identity.userArn.matches('arn:aws:iam::\d+:user/.*')) #if($context.args.cognitoIdentityId__) #set( $cognitoIdentityId = $context.args.cognitoIdentityId__ ) #elseif( $context.source.cognitoIdentityId__ ) #set( $cognitoIdentityId = $context.source.cognitoIdentityId__ ) #end #end #set( $unamepwd = "$util.urlEncode($cognitoIdentityId):" ) { "version" : "2017-02-28", "operation": "Invoke", "payload": { "source": "AppSync", "httpMethod": "get", "headers": { "Authorization": "Basic $util.base64Encode($unamepwd)", }, "pathParameters": { }, "queryStringParameters": { } } } ResponseMappingTemplate: | #if($context.result.statusCode >= 200 && $context.result.statusCode <= 299) #set( $result = $util.parseJson($context.result.body) ) #if($context.args.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.args.cognitoIdentityId__ ) #elseif($context.source.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.source.cognitoIdentityId__ ) #end $util.toJson($result) #else $utils.error($util.parseJson($context.result.body).message, $context.result.statusCode.toString(), $util.parseJson($context.result.body)) #end DependsOn: - GqlApi - GqlSchema - ServiceInfoDataSource SnsNotificationDataSource: Type: AWS::AppSync::DataSource Properties: ApiId: !GetAtt GqlApi.ApiId LambdaConfig: LambdaFunctionArn: Fn::Join: - '' - - 'arn:aws:lambda:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':function:' - Fn::ImportValue: !Sub '${FunctionStack}-functions-SnsNotification' Name: sns_notification_lambda ServiceRoleArn: !GetAtt DataSourceRole.Arn Type: AWS_LAMBDA DependsOn: - DataSourceRole - GqlApi PostSnsNotificationResolver: Type: AWS::AppSync::Resolver Properties: ApiId: !GetAtt GqlApi.ApiId FieldName: postSnsNotification TypeName: Mutation DataSourceName: !GetAtt SnsNotificationDataSource.Name RequestMappingTemplate: | #set( $cognitoIdentityId = $context.identity.cognitoIdentityId ) #if($context.identity.userArn.matches('arn:aws:iam::\d+:user/.*')) #if($context.args.cognitoIdentityId__) #set( $cognitoIdentityId = $context.args.cognitoIdentityId__ ) #elseif( $context.source.cognitoIdentityId__ ) #set( $cognitoIdentityId = $context.source.cognitoIdentityId__ ) #end #end #set( $unamepwd = "$util.urlEncode($cognitoIdentityId):" ) { "version" : "2017-02-28", "operation": "Invoke", "payload": { "source": "AppSync", "httpMethod": "post", "body": "$util.escapeJavaScript($util.toJson($context.args.snsNotification))", "headers": { "Authorization": "Basic $util.base64Encode($unamepwd)", }, "pathParameters": { "roomId": "$util.escapeJavaScript($context.args.roomId)" }, "queryStringParameters": { } } } ResponseMappingTemplate: | #if($context.result.statusCode >= 200 && $context.result.statusCode <= 299) #set( $result = $util.parseJson($context.result.body) ) #if($context.args.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.args.cognitoIdentityId__ ) #elseif($context.source.cognitoIdentityId__) #set( $result.cognitoIdentityId__ = $context.source.cognitoIdentityId__ ) #end $util.toJson($result) #else $utils.error($util.parseJson($context.result.body).message, $context.result.statusCode.toString(), $util.parseJson($context.result.body)) #end DependsOn: - GqlApi - GqlSchema - SnsNotificationDataSource Outputs: ApiEndpoint: Description: The endpoint for the AppSync API. Value: !GetAtt GqlApi.GraphQLUrl